May 12th, 2016

2 нюанса использования Modbus RTU

Рабочее.

Звёзды сошлись так, что проверка CRC в верификаторе посылки Modbus RTU протокола дала сбой.

Это сообщение проходит проверку CRC, но некорректно:
0x04, 0x03, 0x1c, 0x3f, 0xe9, 0x15, 0x18, 0x03, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00

Вот корректное сообщение:
0x04, 0x03, 0x1c, 0x3f, 0xe9, 0x15, 0x18, 0x03, 0x02, 0x00, 0x01, 0x02, 0x02, 0x00, 0x03, 0x18, 0x02, 0x00, 0x03, 0x0b, 0x06, 0xc6, 0x39, 0x07, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xee

Это не проблема протокола Modbus, т.к. он создавался для медной линии связи *дцать лет назад и в нем концом посылки является пауза между байтами длинее, чем 1.5 байта. В наше время Modbus RTU часто используют через TCP\IP соединение (преобразователи MOXA и т.п.), а в этом случае временные промежутки становятся случайным.

Вывод: Надо проверять не только CRC, а еще и длину посылки в сообщении (она не всегда есть, надо смотреть тип сообщений).

И еще есть одна, уже не исправляемая, проблема Modbus:
В ответной посылке не фигурирует номер регистра из запроса.

Может возникнуть следующая ситуация: спросили адрес 1000, ответа от устройства за N мс нет, спрашиваем адрес 1001, приходит ответ на предыдущий запрос (1000), который интерпретируется ответом на 1001й.
Страховки от такой ситуации нет. Минимизация: установка таймаута больше, чем возможная задержка в TCP соединении. Однако при GPRS подключении (GSM модем) она может быть сколь угодно большой.

Вывод: не использовать Modbus RTU/TCP в сетях где нет гарантированного времени ответа.

P.S. Для тех, кто не в курсе, моей профессиональной деятельностью является программирование промышленной автоматизации. Несколько лет я проработал в компании, разрабатывающий ПО транспортировки газа для Газпрома, а сейчас продолжаю программировать взаимодействие с различным оборудование системы типа "умный дом", а также отвлекаюсь на автоматизацию тестирования и веб программирование.

Ссылки по теме:
2015 Умная кофемашина
2015 Автоматизация тестирования СКУД
2013 Беларусь (картинки пропали :( )
2011 Первая командировка