Russian Qt Forum
Апрель 26, 2024, 02:56 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Libmodbus как узнать что COM порт закрылся  (Прочитано 8427 раз)
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« : Апрель 04, 2015, 12:24 »

Здравствуйте.
Есть сеть MODBUS-RTU Rs-485 80 устройств.
Устройства из себя предстовляют контроллеры OWEN ПЛК73.
Соответсвенно нужно ее опрашивать.

Прикрутил для начала libmodbus http://libmodbus.org/

На форуме нашел что кто то с ней работает.
Все заработало почти с полпинка, есть но.

В качестве транспорта использую RS485 который подключен к COM порту компа.
Причем это виртуальный порт переходник USB-RS232.

Если идет обращение к сушествующему адресу то связь есть
функция чтения возвращает количество прочитанных байт.
Код:
// Читаем регистры
 res = modbus_read_registers( m_serialModbus, reg, numReciveByte, buf16 );


Если идет запрос к устройству которого нет на шине  modbus_read_registers возвращает -1 что как бы логично.
А вот дальше если раскрыть эту ошибку
Код:
errorStr = modbus_strerror(errno);

То получаем "Unknown error"

Если просто отключить виртуальный COM порт
То снова получим эту же ошибку "Unknown error"

Вот интересно это libmodbus не умеет определять что случилось или я что то не так делаю.
Допустим есть сеть одно устройсво пропало, не ответило по тайм ауту значит его нет на связе.
Ком порт отвалился тоже можно определить.

Документация крайне скудна.
Поскажите может есть что по приличнее чем libmodbus.
Сам обмен как бы работает, но ведь нужно обработать и не штатные ситуации.
Свое писать что то не хочется.

Записан
sergek
Гипер активный житель
*****
Offline Offline

Сообщений: 870


Мы должны приносить пользу людям.


Просмотр профиля
« Ответ #1 : Апрель 04, 2015, 23:31 »

Это нормально, USB такой вот информативный. Возьмите MOXA NPort, например, 5150, в режиме TCP Server Mode и таких проблем не будет. И быстрее будет работать.
Записан

Qt 5.13.0 Qt Creator 5.0.1
Win10, Ubuntu 20.04
Fat-Zer
Гость
« Ответ #2 : Апрель 04, 2015, 23:51 »

а сам errno какой? и на какой платформе дело происходит?
Записан
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« Ответ #3 : Апрель 05, 2015, 09:48 »

Это нормально, USB такой вот информативный. Возьмите MOXA NPort, например, 5150, в режиме TCP Server Mode и таких проблем не будет. И быстрее будет работать.
Да нельзя у заказчика уже все купленно.
Записан
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« Ответ #4 : Апрель 05, 2015, 10:01 »

а сам errno какой? и на какой платформе дело происходит?

errno == "Unknown error"

Причем эта  ошибка как в случае если нет ответа от удаленного устройства.
Так и если  (Доктор вырвет провода) отсоединить Rs485 адаптор рт USB.

Объясните зачем в libmodbus вот эта функция modbus_poll();
Я ее тоже прицепил так как в примере она была.
Работает она у меня по таймеру.

Но без нее тоже все работает если по таймеру читать
 res = modbus_read_registers( m_serialModbus, reg, numReciveByte, buf16 );

Документация по libmodbus просто никакая.

Причем если заглянуть во внутрь modbus.c
Код:
const char *modbus_strerror(int errnum) {
    switch (errnum) {
    case EMBXILFUN:
        return "Illegal function";
    case EMBXILADD:
        return "Illegal data address";
    case EMBXILVAL:
        return "Illegal data value";
    case EMBXSFAIL:
        return "Slave device or server failure";
    case EMBXACK:
        return "Acknowledge";
    case EMBXSBUSY:
        return "Slave device or server is busy";
    case EMBXNACK:
        return "Negative acknowledge";
    case EMBXMEMPAR:
        return "Memory parity error";
    case EMBXGPATH:
        return "Gateway path unavailable";
    case EMBXGTAR:
        return "Target device failed to respond";
    case EMBBADCRC:
        return "Invalid CRC";
    case EMBBADDATA:
        return "Invalid data";
    case EMBBADEXC:
        return "Invalid exception code";
    case EMBMDATA:
        return "Too many data";
    case EMBBADSLAVE:
        return "Response not from requested slave";
    default:
        return strerror(errnum);
    }
}

Есть же расшифровки ошибки что мне нужно
"Response not from requested slave"
"Slave device or server failure";

Почему тогда  res = modbus_read_registers( m_serialModbus, reg, numReciveByte, buf16 );
не отрабатывает эту ошибку
Записан
Fat-Zer
Гость
« Ответ #5 : Апрель 05, 2015, 11:58 »

errno == "Unknown error"
числовое значение errno, а не то что возвратила strerror...
Объясните зачем в libmodbus вот эта функция modbus_poll();
Я ее тоже прицепил так как в примере она была.
Работает она у меня по таймеру.
в моей libmodbus такой нет... версия? источник?
Записан
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« Ответ #6 : Апрель 05, 2015, 12:09 »

числовое значение errno, а не то что возвратила strerror...

errno == 10060 (0x274C)

в моей libmodbus такой нет... версия? источник?
#define LIBMODBUS_VERSION        3.1.1
Вот с источником не уверен.
Хм... спасибо что на мысель натолкнули счас с сайта скачаю проверю.


Записан
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« Ответ #7 : Апрель 05, 2015, 12:55 »

Спасибо за подсказку.
Короче где то я взял чей то пример и тупо воткнул в проект.
И этот кто то правил исходник libmodbus.

Стянул с официального сайта и собрал библиотеку.
Все так же заработало.

Но теперь при доступе к адресу устройства которого нет на шине modbus
Получаем тоже errno == 10060
А если отключтить USB-RS232 от компа то вообще нет никаких ошибок
errno == 0
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Апрель 05, 2015, 14:36 »

Цитировать
А если отключтить USB-RS232 от компа то вообще нет никаких ошибок
errno == 0

Это не проблема ни USB, ни Modbus. Это проблема самого драйвера последовательного устройства. Не все устройства возвращают какую-либо ошибку при попытке записи/чтения в "выдернутый" дескриптор. И даже если некоторые и возвращают - то все разные. Поэтому нельзя узнать о том, что у-во выдернули или какая-то другая аппаратная проблема.

Например есть такая вещь как QSerialPort, которые пытается отследить это.. но опять, же - это работает не всегда.

Для того чтобы отследить исчезновение/появление устройства (любого) нужно написать дополнительный код (класс), используя SetupApi (в Windows) - это будет работать железно.  Улыбающийся

UPD: А если речь идет про Linux - то там использовать libudev.
Записан

ArchLinux x86_64 / Win10 64 bit
VVN
Чайник
*
Offline Offline

Сообщений: 52


Просмотр профиля
« Ответ #9 : Апрель 06, 2015, 18:07 »

Спасибо за ответы.
Понял что не так все просто.
Нашел пример с SetupApi, нда там не особо все просто.
Плюс boost используют.
Отсавил пока на потом.
Нужно проект в целом сделать.


Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.052 секунд. Запросов: 22.