Russian Qt Forum

Qt => Работа с сетью => Тема начата: VVN от Апрель 04, 2015, 12:24



Название: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 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.
Сам обмен как бы работает, но ведь нужно обработать и не штатные ситуации.
Свое писать что то не хочется.



Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: sergek от Апрель 04, 2015, 23:31
Это нормально, USB такой вот информативный. Возьмите MOXA NPort, например, 5150, в режиме TCP Server Mode и таких проблем не будет. И быстрее будет работать.


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: Fat-Zer от Апрель 04, 2015, 23:51
а сам errno какой? и на какой платформе дело происходит?


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 05, 2015, 09:48
Это нормально, USB такой вот информативный. Возьмите MOXA NPort, например, 5150, в режиме TCP Server Mode и таких проблем не будет. И быстрее будет работать.
Да нельзя у заказчика уже все купленно.


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 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 );
не отрабатывает эту ошибку


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: Fat-Zer от Апрель 05, 2015, 11:58
errno == "Unknown error"
числовое значение errno, а не то что возвратила strerror...
Объясните зачем в libmodbus вот эта функция modbus_poll();
Я ее тоже прицепил так как в примере она была.
Работает она у меня по таймеру.
в моей libmodbus такой нет... версия? источник?


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 05, 2015, 12:09
числовое значение errno, а не то что возвратила strerror...

errno == 10060 (0x274C)

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




Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 05, 2015, 12:55
Спасибо за подсказку.
Короче где то я взял чей то пример и тупо воткнул в проект.
И этот кто то правил исходник libmodbus.

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

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


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: kuzulis от Апрель 05, 2015, 14:36
Цитировать
А если отключтить USB-RS232 от компа то вообще нет никаких ошибок
errno == 0

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

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

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

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


Название: Re: Libmodbus как узнать что COM порт закрылся
Отправлено: VVN от Апрель 06, 2015, 18:07
Спасибо за ответы.
Понял что не так все просто.
Нашел пример с SetupApi, нда там не особо все просто.
Плюс boost используют.
Отсавил пока на потом.
Нужно проект в целом сделать.