Modbus-RTU — это метод связи, который уже давно используется на заводах и промышленных объектах, поэтому существует множество документации и на практике он встречается очень часто. Однако для непосредственного подключения линий и наблюдения за обменом необходим преобразователь RS-485 или реальное оборудование, поэтому разобраться в нем на практике зачастую бывает сложно.
В этой статье я сначала кратко объясню концепцию Modbus, а затем расскажу, как полностью создать и протестировать обмен данными на ПК без реального оборудования, используя com0com (виртуальные последовательные порты) и две тестовые программы Modbus Poll/Modbus Slave.
1. Что такое Modbus?
Modbus был впервые создан в 1979 году и остается одним из наиболее широко используемых протоколов связи в промышленности. Даже если такие устройства, как ПЛК, датчики, измерительные приборы и инверторы, произведены разными компаниями, они могут обмениваться данными при условии соответствия этому стандарту, поэтому его продолжают применять в новом оборудовании.
Структура обмена данными в Modbus всегда разделена на «ведущее устройство» (Master) и «ведомое устройство» (Slave). Slave отвечает только после того, как Master сначала отправит запрос, поэтому Slave никогда не передает данные по собственной инициативе. К одному Master можно подключить несколько Slave, и каждое Slave определяется уникальным идентификатором Slave ID (1–247).
В зависимости от физической линии, по которой происходит этот обмен между Master и Slave, Modbus в общих чертах делится на два типа.
|
Категория |
Modbus TCP |
Modbus RTU |
|---|---|---|
|
Физический уровень |
Ethernet (сетевой кабель) |
Последовательный интерфейс RS-232 / RS-485 |
|
Адресация |
IP-адрес + порт |
Slave ID (1–247) |
|
Структура кадра |
Заголовок MBAP + PDU |
Slave ID + PDU + CRC16 |
|
Характеристики |
Простая и быстрая настройка сети |
Проводка недорога и позволяет передавать данные на большие расстояния (RS-485: 1,2 км, до 32 устройств), поэтому этот тип по-прежнему широко используется для полевых приборов и устаревшего оборудования. |
Кадр RTU имеет очень простую структуру, как показано ниже.
|
Slave ID (1 байт) |
Код функции (1 байт) |
Данные (переменная длина) |
CRC16 (2 байта) |
|---|---|---|---|
|
Номер устройства, которое должно получить запрос |
Что сделать (прочитать/записать и т. д.) |
Адрес регистра, количество, значение и т. д. |
Контрольная сумма для обнаружения ошибок |
Чтобы понять большинство упражнений, достаточно знать несколько часто используемых кодов функций.
-
03 (Read Holding Registers) — считывает значения регистров. Чаще всего используется в упражнениях.
-
06 (Write Single Register) — записывает значение в один регистр.
-
01 (Read Coils) — считывает значения Вкл./Выкл. (биты).
-
16 (Write Multiple Registers) — одновременно записывает значения в несколько регистров.
Для работы обмена по RTU Master и Slave должны точно совпадать по следующим четырем параметрам связи: Baud Rate (скорость передачи, например 9600), Parity (обычно None), Data Bits (обычно 8) и Stop Bits (обычно 1). Если хотя бы один из параметров отличается, устройство может вообще не ответить либо полученные значения могут оказаться поврежденными.
Итог: RTU — это простой протокол, который представляет в виде очень короткой последовательности байтов «кто (Slave ID), что обменивает (код функции), где (адрес) и сколько (количество)», а затем проверяет наличие ошибок с помощью CRC в конце.
2. Зачем тестировать с помощью виртуальных последовательных портов?
Чтобы напрямую наблюдать за обменом данными RTU, обычно нужны преобразователь RS-485, кабели и реальное Slave-устройство, способное отвечать на запросы. Однако если нужно лишь убедиться, что «сам обмен данными работает правильно», его можно воспроизвести на ПК без этого оборудования. com0com — это бесплатный виртуальный драйвер нуль-модема с открытым исходным кодом для Windows. После установки он создает пару внутренних соединенных COM-портов. Поскольку байты, записанные в один порт, без изменений попадают в буфер приема другого порта, создается такая же ситуация, как при соединении двух устройств настоящим кабелем.
Подключив по одной программе к каждому концу этой пары виртуальных портов, можно назначить им роли Master и Slave соответственно.
-
Modbus Slave — действует как моделируемое полевое устройство. Он хранит значения по определенным адресам и отвечает при поступлении запроса.
-
Modbus Poll — действует как Master. Он периодически считывает значения из Slave или записывает их в него.
Обе программы являются парными утилитами для Windows, распространяемыми компанией Witte Software (modbustools.com), и даже бесплатной пробной версии достаточно для базового тестирования.
3. Настройка com0com
-
Скачайте com0com и установите его с правами администратора.
-
По умолчанию установка создает одну пару портов с именами CNCA0 ↔ CNCB0. В окне настроек можно изменить имена на нужные номера COM — в этой статье будем считать, что они изменены на COM7 (сторона Slave) и COM8 (сторона Master).
-
В параметрах портов рекомендуется включить «Эмуляцию скорости передачи». Если этот параметр отключен, данные доставляются немедленно независимо от скорости передачи, в отличие от настоящей последовательной линии. Некоторые программы определяют окончание кадра по «времени простоя между символами», поэтому для тестирования безопаснее разрешить работу таймингов в режиме, более похожем на реальное оборудование.
-
После сохранения настроек проверьте, отображаются ли COM7 и COM8 в списке «Порты (COM и LPT)» в диспетчере устройств Windows.
Пример окна настроек com0com — пара портов COM7 ↔ COM8 и параметры (фактический вид окна может отличаться в зависимости от версии)
Пример окна диспетчера устройств — проверка наличия портов COM7 и COM8
4. Создание виртуального устройства с помощью Modbus Slave
Запустите Modbus Slave, подключите его к COM7 и задайте параметры связи в соответствии с указанными значениями.
-
Порт: COM7
-
Скорость передачи / Чётность / Биты данных / Стоповые биты: 9600 / Нет / 8 / 1
-
ID ведомого устройства: 1
После подключения также появится таблица для редактирования значений регистров. В меню Setup задайте Function: 03 Holding Registers, установите начальный адрес 40001, укажите подходящее количество регистров, а затем дважды щёлкните значение в таблице, чтобы ввести произвольное тестовое значение (например, введите 1234 по адресу 40001).
Пример окна Modbus Slave — слева: параметры подключения (COM7, 9600-N-8-1, ID ведомого устройства 1) / справа: значение регистра (40001=1234)
5. Чтение значений с помощью Modbus Poll
На этот раз запустите Modbus Poll и подключите его к противоположному порту — COM8. Задайте параметры связи точно такими же, как в Modbus Slave.
-
Порт: COM8
-
Скорость передачи / Чётность / Биты данных / Стоповые биты: 9600 / Нет / 8 / 1 (как у ведомого устройства)
-
ID ведомого устройства: 1 (как у ведомого устройства)
Откройте Read/Write Definition в меню Setup, задайте Function: 03 Holding Registers, установите начальный адрес 40001 и задайте количество регистров таким же, как в Modbus Slave. После этого Modbus Poll будет периодически отправлять запросы по маршруту COM8 → (com0com) → COM7 → Modbus Slave, получать ответ и отображать его на экране. Если ранее введённое на стороне ведомого устройства значение (1234) отображается без изменений, значит, связь работает правильно.
Пример окна Modbus Poll — слева: параметры подключения и чтения (COM8) / справа: результат ответа (40001=1234, соответствует ведомому устройству)
Если снова изменить значение в окне Modbus Slave, в следующем цикле опроса можно увидеть, как оно обновится в окне Modbus Poll. После подтверждения того, что обе стороны обмениваются значениями без расхождений, проверка фактически завершена — от передачи и приёма RTU-кадров до сопоставления параметров связи — без использования реального оборудования.
6. Что проверить при возникновении проблем
-
При отсутствии ответа (тайм-ауте): проверьте, что параметры Baud Rate, Parity, Data Bits и Stop Bits в Modbus Poll и Modbus Slave полностью совпадают, а также убедитесь, что ID ведомого устройства одинаков.
-
Если порт невозможно открыть: проверьте, не занят ли тот же COM-порт другой программой. (Одновременно порт может быть открыт только одной программой.)
-
Если значения отображаются неправильно (например, возникает ошибка CRC): проверьте параметр эмуляции скорости передачи в com0com и убедитесь, что настройки начального адреса и количества регистров на обеих сторонах указывают на одни и те же регистры.
7. Заключение
Итак, RTU в конечном счёте представляет собой всего лишь обмен короткой последовательностью байтов — «ID ведомого устройства + код функции + данные + CRC» — с использованием заранее заданных параметров связи. Даже без физического соединения можно создать с помощью com0com пару виртуальных COM-портов и подключить к одному концу Modbus Slave (виртуальное устройство), а к другому — Modbus Poll (ведущее устройство). Это позволяет визуально проверить весь процесс обмена Modbus-RTU — формирование кадра запроса, последовательную передачу, ответ, проверку CRC и отображение значения — без проводов RS-485 и реального промышленного оборудования. Если вы непосредственно наблюдали весь процесс: от создания и последовательной передачи кадра запроса до поступления ответа и отображения значения на экране, — значит, вы уже проверили все основные аспекты связи RTU.
К этому моменту вы уже попрактиковались в тестировании через виртуальные порты с помощью драйвера Modbus. Когда реальное оборудование RS-485 будет готово, останется совсем немного. Просто замените com0com на реальный преобразователь RS-485, подключённый к COM-порту, замените Modbus Poll на фактически используемое ведущее устройство или программное обеспечение и заново настройте такие параметры связи, как Baud Rate, Parity и Slave ID, в соответствии с характеристиками оборудования.
Ссылки
-
Modbus Organization — https://www.modbus.org/modbus-specifications
-
Modbus Application Protocol — https://www.modbus.org/file/secure/modbusprotocolspecification.pdf
-
com0com – эмулятор нуль-модема — https://sourceforge.net/projects/com0com/
Luna