RS-485 и Modbus RTU
id: COURSE-01-M04-L02
title: "RS-485 и Modbus RTU"
level: foundation
tags: [protocol, rs-485, modbus, wiring, node-red, integration]
prerequisites: [COURSE-01-M04-L01]
version: 1.0
status: published
---
# Урок: RS-485 и Modbus RTU
В предыдущем уроке мы обсудили, зачем в системах автоматизации нужны протоколы и как они обеспечивают структурированное взаимодействие между устройствами. Сегодня мы углубимся в одну из самых надежных и распространенных связок в промышленной и коммерческой автоматизации: физический интерфейс RS-485 и протокол Modbus RTU. Эта комбинация является стандартом де-факто для подключения счетчиков электроэнергии, модулей реле, климатического оборудования и множества других периферийных устройств.
📋 Ключевые понятия:
- RS-485: Стандарт физического уровня (PHY), описывающий электрические характеристики передачи данных.
- Modbus RTU: Протокол прикладного уровня, определяющий "язык" общения устройств.
- Дифференциальная передача: Метод передачи сигнала по двум проводам, обеспечивающий высокую помехоустойчивость.
- Топология "шина": Способ подключения нескольких устройств к одной общей паре проводов.
- Терминатор: Резистор (обычно 120 Ом), устанавливаемый на концах шины для предотвращения отражения сигнала.
- Client/Server (Master/Slave): Модель взаимодействия, где одно устройство (Client/Master) инициирует запросы, а другие (Servers/Slaves) отвечают.
- Карта регистров (Register Map): Документация от производителя устройства, описывающая адреса и назначение его внутренних данных.
- Function Codes: Команды в протоколе Modbus (например, "прочитать данные" или "записать данные").
- CRC (Cyclic Redundancy Check): Контрольная сумма для проверки целостности передаваемых данных.
🎯 Цели обучения:
По завершении этого урока вы сможете:
- Объяснять разницу между физическим уровнем (RS-485) и протоколом (Modbus RTU).
- Настраивать чтение и запись данных с Modbus RTU устройства в среде Node-RED.
- Использовать карту регистров производителя для интеграции нового устройства.
- Выполнять базовую диагностику неисправностей в Modbus-сети.
Что такое RS-485? Физический уровень.
Часто начинающие инженеры путают RS-485 и Modbus, считая их одним и тем же. Крайне важно понимать их разделение. RS-485 — это не протокол, а стандарт физического уровня (Physical Layer, L1). Он описывает, как электрические сигналы передаются по проводам, но ничего не говорит о том, что эти сигналы значат.
Представьте, что RS-485 — это телефонная линия между двумя людьми. Линия обеспечивает возможность голосу дойти от одного абонента к другому, но она не определяет язык, на котором они будут говорить (русский, английский или китайский). Этим "языком" в нашем случае выступит протокол Modbus, который мы рассмотрим далее.
> 💡 Подсказка: Для построения шины RS-485 всегда используйте специализированный кабель или витую пару (например, UTP Cat5e). Это минимизирует влияние помех и обеспечит стабильность связи на больших дистанциях.
Ключевые характеристики RS-485:
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│Контроллер │ │Устройство 1│ │Устройство 2│ │Устройство N│
│ (Client) │ │ (Server) │ │ (Server) │ │ (Server) │
└─────┬─┬───┘ └─────┬─┬───┘ └─────┬─┬───┘ └─────┬─┬───┘
| | | | | | | |
A o───┼─┴──────────────┼─┴──────────────┼─┴──────────────┼─┴──o A
B o───┴────────────────┴────────────────┴────────────────┴────o B
▲ ▲
│ │
Терминатор (120 Ом) Терминатор (120 Ом)
Modbus RTU: Протокол поверх RS-485
Если RS-485 — это физическая среда, то Modbus — это протокол прикладного уровня, определяющий правила и формат общения. Он был создан в 1979 году для промышленных контроллеров и благодаря своей простоте и открытости стал одним из самых популярных протоколов в мире. Мы будем рассматривать его самую распространенную реализацию — Modbus RTU (Remote Terminal Unit), которая предназначена для работы поверх последовательных интерфейсов, таких как RS-485.
> ⚠️ Внимание: Адрес устройства '0' в Modbus RTU является широковещательным (broadcast). Команды, отправленные на этот адрес, получат все устройства в сети, но ни одно из них не отправит ответ. Используйте эту функцию с особой осторожностью, например, для одновременной отправки команды на выключение всех реле.
Ключевые аспекты Modbus RTU:
* Адрес устройства (1 байт): Тот самый Slave ID (1-247).
* Код функции (1 байт): Указывает, какое действие должен выполнить сервер (например, прочитать данные, записать данные).
* Данные (N байт): Содержимое зависит от кода функции. Это могут быть стартовый адрес регистра и количество регистров для чтения, или адрес и значение для записи.
* Контрольная сумма CRC (2 байта): Значение, рассчитанное по специальному алгоритму на основе всех предыдущих байт кадра. Приемник выполняет тот же расчет и сравнивает результат с полученной контрольной суммой. Если они не совпадают, пакет считается поврежденным и отбрасывается.
* `0x03 (Read Holding Registers)`: Чтение одного или нескольких 16-битных регистров хранения. Это наиболее часто используемая функция для получения данных состояния, измерений (температура, напряжение) и уставок.
* `0x04 (Read Input Registers)`: Аналогично `0x03`, но читает регистры "только для чтения". Обычно используется для данных, которые нельзя изменить (например, показания счетчика электроэнергии).
* `0x06 (Write Single Register)`: Запись значения в один 16-битный регистр хранения. Используется для управления, например, включением одного реле или установкой целевой температуры.
* `0x10 (Write Multiple Registers)`: Запись значений в несколько регистров хранения подряд. Удобно для одновременного управления группой реле или обновления нескольких настроек за один запрос.
Практика: Чтение данных с устройства в Node-RED
Теперь перейдем от теории к практике. Наш контроллер с установленным Node-RED предоставляет мощные и удобные инструменты для работы с Modbus.
🔗 Связанный материал: Подробно о принципах работы и установки Node-RED мы рассказывали в модуле `COURSE-01-M03`.
Задача: Настроить опрос гипотетического датчика температуры и влажности, подключенного по Modbus RTU. Предположим, у него Slave ID = 15, и он отдает температуру в регистре 100, а влажность — в регистре 101. Шаг 1: Установка палитры `node-red-contrib-modbus`* Name: "Шина RS485-1" (или любое понятное имя).
* Type: `RTU` (для работы через последовательный порт).
* Serial Port: `/dev/ttyRS485-1` (это типовой путь к порту RS-485 на нашем контроллере; если вы используете внешний USB-адаптер, путь может быть `/dev/ttyUSB0`).
* Serial Type: `RTU-BUFFERD`.
* Baud Rate: `9600` (или другая скорость, указанная в документации к вашему устройству).
* Data Bits: `8`.
* Parity: `None`.
* Stop Bits: `1`.
* Unit-ID: Оставьте это поле пустым здесь. Оно будет задаваться в каждом узле чтения/записи индивидуально.
* Name: "Чтение T/H датчика".
* Unit-ID: `15` (адрес нашего датчика).
* FC: `0x03: Read Holding Registers`.
* Address: `100` (адрес первого регистра для чтения).
* Quantity: `2` (мы хотим прочитать два регистра подряд: 100 и 101).
* Poll Rate: `5 seconds` (опрашивать устройство каждые 5 секунд).
Его `msg.payload` будет выглядеть примерно так:
{
"data": [ 255, 480 ],
"buffer": ""
}
Узел `modbus-contrib` удобно преобразует сырые данные из буфера (`buffer`) в массив чисел (`data`). В нашем примере:
- `255` — это значение из регистра 100 (температура).
- `480` — это значение из регистра 101 (влажность).
Часто производители кодируют значения. Например, "температура = значение / 10". Тогда реальная температура будет 25.5°C, а влажность — 48.0%. Для таких преобразований идеально подходит узел `Function`.
Реальный кейс: Управление реле
Рассмотрим, как управлять реальным устройством. Возьмем для примера популярный модуль реле Wirenboard WB-MR6C. Он имеет 6 релейных выходов и управляется по Modbus.
> 💡 Подсказка: Всегда начинайте работу с новым Modbus-устройством с внимательного изучения его карты регистров (Modbus Register Map). Это самый важный документ для успешной интеграции.
Шаг 1: Изучение карты регистровОткрыв документацию на WB-MR6C, мы находим информацию:
- Каждое реле управляется отдельным регистром (Coil).
- Адрес первого реле (K1) — `0`. Адрес второго (K2) — `1`, и так далее.
- Для управления реле используется команда `0x05 (Write Single Coil)` или `0x0F (Write Multiple Coils)`. Значение `1` (или `true`) включает реле, `0` (`false`) — выключает.
- Также есть регистры `Holding Registers` с адреса `128` для K1, `129` для K2 и т.д. Команды`0x06` и `0x10` также могут управлять реле: запись `1` включает, `0` — выключает. Будем использовать их для примера.
* Payload: `number` (число) `1`.
* Topic: `relay/1/on`.
* Name: "Включить Реле 1".
* Payload: `number` (число) `0`.
* Topic: `relay/1/off`.
* Name: "Выключить Реле 1".
* Name: "Управление Реле 1".
* Server: Выберите ранее созданную конфигурацию "Шина RS485-1".
* Остальные параметры оставим пустыми, так как мы будем передавать их в сообщении.
`Modbus-Write` ожидает на вход `msg.payload`, содержащий значение для записи. Но как ему узнать адрес и код функции? Для этого мы можем передать их в объекте `msg`. Добавим узел `Function` между `Inject` и `Modbus-Write`.
// Function node
// Предположим, у модуля WB-MR6C адрес (Slave ID) = 10
// Регистр для Реле 1 = 128
// Получаем значение (0 или 1) из входа
const value = msg.payload;
// Формируем объект для узла Modbus-Write
msg.payload = {
'value': value,
'fc': 6, // 0x06: Write Single Register
'unitid': 10,
'address': 128
};
return msg;
Теперь, при нажатии на `Inject` "Включить Реле 1", узел `Function` сформирует правильный объект, и узел `Modbus-Write` отправит команду на запись `1` в регистр `128` устройства `10`. Реле щелкнет и включится.
Диагностика проблем на шине RS-485/Modbus
Ничто не работает с первого раза. Сети Modbus могут быть капризны, и умение диагностировать проблемы — ключевой навык инженера. Вот мини-runbook для отладки.
1. Программные ошибки (самые частые): Неверные параметры порта: Проверьте трижды скорость (Baud Rate), четность (Parity), количество бит данных (Data bits) и стоп-биты (Stop bits). Они должны быть абсолютно одинаковыми* на контроллере и на всех устройствах на шине.- Неправильный Slave ID: Убедитесь, что `Unit-ID` в узле Node-RED соответствует адресу, выставленному на самом устройстве (часто с помощью DIP-переключателей).
- Перепутанные адреса регистров: Внимательно читайте карту регистров. Обратите внимание, что некоторые производители нумеруют адреса с 0, а некоторые с 1 ("off-by-one error").
- Перепутанная полярность: Провода A и B перепутаны местами. Это самая частая ошибка монтажа. Связь работать не будет. Просто поменяйте провода местами на одном из концов (на контроллере или на устройстве).
- Плохой контакт: Проверьте затяжку клемм на всех устройствах.
- Отсутствие или неправильная установка терминаторов: Если шина короткая (до 50 м) и скорость низкая (9600), она может работать и без терминаторов. Но на длинных линиях или при высоких скоростях их отсутствие приведет к ошибкам (`CRC Error`). Используйте мультиметр: при отключенном питании контроллера и устройств измерьте сопротивление между линиями A и B. На правильно терминированной шине оно должно быть около 60 Ом (результат параллельного соединения двух резисторов по 120 Ом).
Узлы `node-red-contrib-modbus` при ошибках отправляют сообщение на второй выход. Подключите к нему `Debug` узел.
- `Timeout`: Устройство не ответило за указанное время. Причины: неверный Slave ID, обрыв провода, устройство выключено, перепутаны A/B.
- `CRC Error`: Контрольная сумма ответа неверна. Пакет поврежден. Причины: сильные помехи, неправильные параметры порта, проблемы с терминаторами.
- `Exception`: Устройство ответило, но с кодом ошибки. Например, "Illegal data address" (вы пытаетесь прочитать несуществующий регистр) или "Illegal data value" (вы пытаетесь записать недопустимое значение). Это ошибка логики, а не связи.
Иногда полезно проверить связь, минуя Node-RED. Наш контроллер на базе Debian позволяет использовать утилиту `mbpoll`.
Установите ее: `sudo apt-get install mbpoll`
Пример: опросить 1 регистр, начиная с адреса 128, у устройства с ID=10 на порту `/dev/ttyRS485-1` со скоростью 9600.
mbpoll -a 10 -b 9600 -P none -t 4 -r 128 -c 1 /dev/ttyRS485-1
- `-a 10`: адрес 10
- `-b 9600`: скорость 9600
- `-P none`: без четности
- `-t 4`: тип регистров `Input Registers` (`-t 3` для `Holding Registers`)
- `-r 128`: стартовый адрес 128
- `-c 1`: прочитать 1 регистр
Если `mbpoll` показывает данные, а Node-RED — нет, проблема в настройках Node-RED. Если `mbpoll` тоже не работает, проблема на физическом уровне или в настройках порта.
Резюме и ключевые выводы
В этом уроке мы сделали глубокое погружение в мир RS-485 и Modbus RTU — фундаментальных технологий для построения надежных систем автоматизации.
- Мы четко разграничили RS-485 как стандарт физического уровня, отвечающий за помехозащищенную передачу сигналов по двухпроводной шине, и Modbus RTU как протокол, определяющий "язык", на котором устройства общаются друг с другом.
- Мы разобрали ключевые принципы работы: топологию "шина", необходимость терминаторов, модель Client-Server и важность уникальной адресации устройств.
- На практических примерах мы научились настраивать Node-RED для работы с Modbus-устройствами: установили необходимую палитру, сконфигурировали клиент и использовали узлы `Modbus-Read` и `Modbus-Write`.
- Мы поняли, что карта регистров — это главный документ при интеграции любого Modbus-устройства, и научились применять ее для решения реальной задачи управления релейным модулем.
- Наконец, мы вооружились чек-листом для диагностики наиболее распространенных проблем — от банальной перепутанной полярности проводов до анализа ошибок в логах и использования консольных утилит.
Освоив связку RS-485/Modbus, вы открыли для себя возможность интеграции огромного парка промышленного и инженерного оборудования в экосистему нашей платформы.
---
Что дальше:В следующем уроке мы познакомимся с другим мощным протоколом, который является сердцем многих современных IoT-систем и ключевым элементом нашей платформы.
➡️ Следующий урок: COURSE-01-M04-L03: Введение в MQTT