Протокол Modbus RTU
Modbus RTU — двоичный протокол «ведущий — ведомые» поверх UART: кадр состоит из адреса устройства, кода функции, данных и CRC-16, а границей кадра служит тишина на линии не короче 3,5 символа. Ниже — физический уровень, формат символа и кадра, функции с примерами побайтно, расчёт CRC на C и разбор типичных ошибок.
Обновлено Редакция GAW
Содержание
- Modbus RTU, ASCII и TCP: чем они отличаются
- Физический уровень: RS-485 и RS-232
- Формат символа: 11 бит, чётность и скорость
- Структура кадра Modbus RTU
- Паузы t1,5 и t3,5: как приёмник находит границы кадра
- Модель данных: катушки, входы и регистры
- Коды функций Modbus
- Коды ошибок Modbus: ответ с исключением
- CRC-16 в Modbus RTU: алгоритм и код на C
- Пример: собираем запрос и разбираем ответ
- Обмен ведущего и ведомых: таймаут, широковещательный запрос, повторы
- 32-битные числа и float в двух регистрах
- Типичные ошибки
- Как отлаживать Modbus RTU
Modbus RTU — вариант протокола Modbus для последовательной линии, в котором байты кадра передаются в двоичном виде, без перекодирования в текст. На шине один ведущий (master) и до 247 ведомых (slave). Обмен всегда начинает ведущий: он передаёт кадр — адрес ведомого, код функции, данные и CRC-16, — а ведомый с этим адресом выполняет запрос и отвечает кадром такого же вида. Ведомые не передают без запроса и не обмениваются данными между собой. Символов начала и конца у кадра нет: его границы приёмник находит по паузам, поэтому кадр передают сплошным потоком, а между кадрами выдерживают тишину не короче 3,5 символа.
Modbus появился в 1979 году как протокол программируемых контроллеров Modicon и с тех пор стал общим языком промышленной автоматики: его понимают контроллеры, панели оператора, приводы, модули ввода-вывода. Сейчас спецификации публикует Modbus Organization. Протокол описан двумя документами: MODBUS Application Protocol Specification V1.1b3 задаёт модель данных и функции, общие для всех вариантов Modbus, а MODBUS over Serial Line Specification and Implementation Guide V1.02 — всё, что относится к последовательной линии: кадр RTU, паузы, CRC, провода, терминаторы. Числа и примеры в статье взяты из этих документов; наши расчёты и проверки отмечены в тексте.
В спецификации прикладного протокола роли названы иначе: клиент отправляет запрос, сервер отвечает. На последовательной линии клиент — это ведущий, а серверы — ведомые.
Коротко
- Кадр: адрес ведомого (1 байт), код функции (1 байт), данные (0–252 байта) и CRC-16 (2 байта, младший первым) — не больше 256 байт.
- Символ: 11 бит — старт-бит, 8 бит данных младшим вперёд, бит чётности и стоп-бит. По умолчанию чётность even (8E1); без чётности — два стоп-бита (8N2).
- Паузы: между кадрами — тишина не короче 3,5 символа, внутри кадра — не длиннее 1,5 символа. Выше 19 200 бит/с — постоянные 1,75 мс и 750 мкс.
- Скорость: 9600 и 19 200 бит/с обязательны, 19 200 бит/с — значение по умолчанию.
- Адреса: 1–247 — ведомые, 0 — широковещательный запрос без ответа, 248–255 зарезервированы.
- Данные: четыре таблицы — катушки, дискретные входы, входные регистры и регистры хранения по 16 бит. Адрес в кадре на единицу меньше номера: регистр 40001 — это адрес 0.
Modbus RTU, ASCII и TCP: чем они отличаются
Запросы и ответы Modbus одинаковы в любой сети: это PDU (protocol data unit) — код функции и данные. Варианты протокола различаются тем, во что PDU упаковывают для передачи: RTU (Remote Terminal Unit) и ASCII — два режима последовательной линии, Modbus TCP — вариант для сетей TCP/IP.
| Modbus RTU | Modbus ASCII | Modbus TCP | |
|---|---|---|---|
| Среда | UART поверх RS-485 или RS-232 | то же | Ethernet, TCP/IP, порт 502 |
| Кодирование | байт кадра — один 8-битный символ | байт кадра — два символа ASCII: 0–9, A–F | байты как есть |
| Символ на линии | 11 бит: старт, 8 бит данных, чётность, стоп | 10 бит: старт, 7 бит данных, чётность, стоп | — |
| Границы кадра | тишина не короче 3,5 символа | двоеточие в начале, CR и LF в конце | поле длины в заголовке MBAP |
| Пауза внутри кадра | не больше 1,5 символа | до 1 с | не важна |
| Адрес устройства | 1 байт: 1–247, 0 — всем | то же, 2 символа | поле Unit Identifier в заголовке |
| Контроль ошибок | CRC-16, 2 байта | LRC, 1 байт (2 символа) | свой не нужен: проверку делают TCP и CRC-32 в Ethernet |
| Наибольший кадр | 256 байт | 513 символов | 260 байт |
| Чтение регистров 108–110 у устройства 17 | 11 03 00 6B 00 03 76 87 | :1103006B00037E и CR LF | 00 01 00 00 00 06 11 03 00 6B 00 03 |
В последней строке — один и тот же запрос. В RTU он занимает 8 символов по 11 бит, то есть 88 бит на линии, в ASCII — 17 символов по 10 бит, 170 бит. В примере для TCP первые семь байт — заголовок MBAP: номер транзакции 0x0001, идентификатор протокола 0x0000, длина 0x0006 и Unit Identifier 0x11; значения LRC и заголовка посчитаны нами по правилам из спецификаций.
На последовательной линии все устройства обязаны поддерживать режим RTU, и он же должен быть включён по умолчанию; ASCII — необязательное дополнение. Режим и параметры порта должны быть одинаковыми у всех устройств одной линии. ASCII вдвое менее плотный, зато терпит паузы между символами до секунды: руководство оставляет его для случаев, когда оборудование или канал связи не могут выдержать паузы RTU.
Modbus TCP несёт те же PDU. Адрес ведомого в нём заменён байтом Unit Identifier, по которому шлюз между Ethernet и последовательной линией узнаёт, какому ведомому предназначен запрос.
Физический уровень: RS-485 и RS-232
Для новых устройств руководство рекомендует двухпроводный RS-485; четырёхпроводный вариант и RS-232 — дополнительные возможности. Электрические параметры RS-485 — уровни, единичные нагрузки, расчёт смещения, выбор трансивера — разобраны в статье RS-485; здесь только то, что к ним добавляет Modbus.
Двухпроводная линия: D1, D0 и Common
В двухпроводной схеме все устройства подключены параллельно к магистральному кабелю из трёх проводников: витой пары D1 и D0 и общего провода Common. В каждый момент передаёт только один передатчик. Руководство требует называть цепи в документации устройств именно так — D1, D0 и Common.
| Цепь Modbus | По TIA/EIA-485 | У микросхем трансиверов | Признак |
|---|---|---|---|
| D1 | B/B′ | вывод A, неинвертирующий | при двоичной единице напряжение на D1 выше, чем на D0 |
| D0 | A/A′ | вывод B, инвертирующий | при двоичном нуле напряжение на D0 выше, чем на D1 |
| Common | C/C′ | GND | общий провод сигнала и, если есть, питания |
UART в паузе передаёт единицу, поэтому в простое D1 положительнее D0. Отсюда практическое правило: D1 — линия, которую в паузе подтягивают к плюсу. По тексту стандарта TIA/EIA-485 это линия B, а у микросхем она обычно называется A: у SP3485, например, A — неинвертирующий вывод, и при единице на входе передатчика на нём высокий уровень. Как не запутаться в буквах на клеммах приборов — в разделе «A и B: почему их путают».
Общий провод обязателен: это третий проводник того же кабеля. Его соединяют с защитной землёй напрямую и желательно только в одной точке шины — обычно у ведущего или у его ответвителя. Кабель должен быть экранированным; экран соединяют с защитной землёй на одном конце каждого отрезка.
Терминаторы и поляризация линии
Терминаторы (line termination, LT) ставят у каждого из двух концов магистрали, между D1 и D0. Правила руководства:
- на одной паре — не больше двух терминаторов, и никогда — на отводе;
- подходит резистор 150 Ом мощностью 0,5 Вт;
- если на шине есть поляризация, лучше цепочка из резистора 120 Ом (0,25 Вт) и конденсатора 1 нФ (на напряжение не ниже 10 В), включённых последовательно: постоянный ток через такой терминатор не течёт;
- в четырёхпроводной схеме терминируют каждую пару на обоих концах; на RS-232 терминаторы не ставят.
Поляризация (в статье про RS-485 — смещение, failsafe) нужна, чтобы в паузе, когда все передатчики выключены, приёмники видели определённый уровень, а не шум. Руководство обязывает производителя указать в документации каждого устройства, нужна ли ему поляризация линии и умеет ли оно обеспечить её само. Если поляризация нужна хотя бы одному устройству, на шину ставят одну пару резисторов:
- подтягивающий — от D1 к напряжению 5 В;
- стягивающий — от D0 к Common;
- сопротивление каждого — от 450 до 650 Ом; с резисторами 650 Ом на линии помещается больше устройств.
Поляризацию делают в одном месте на всю шину, обычно у ведущего или у его ответвителя; остальные устройства включать её не должны. Допустимое число устройств на линии при этом уменьшается на 4.
Наш расчёт для проверки этих номиналов: два резистивных терминатора по 150 Ом вместе дают 75 Ом, и ток через резисторы поляризации создаёт на них в паузе примерно 0,38 В при 450 Ом и 0,27 В при 650 Ом — выше порога приёмника RS-485 в 200 мВ, но без большого запаса; входы приёмников нагружают линию дополнительно и немного снижают это напряжение. С терминаторами 120 Ом + 1 нФ постоянный ток через терминаторы не течёт, и напряжение в паузе получается намного выше. Посчитать его для своей шины можно калькулятором резисторов смещения.
Длина линии, отводы и число устройств
| Параметр | Требование руководства |
|---|---|
| Топология | магистраль, устройства — «цепочкой» или на коротких отводах; большие сети делят повторителями |
| Устройств без повторителя | 32 допустимы всегда; больше — если устройства нагружают линию слабее и это указано в их документации |
| Длина магистрали | до 1000 м при скорости до 9600 бит/с и проводе AWG 26 или толще |
| Отвод | не длиннее 20 м; у ответвителя на n отводов — не больше 40/n м каждый |
| Кабель | экранированный: витая пара и третий провод; AWG 24 достаточно всегда; кабель категории 5 — до 600 м |
| Волновое сопротивление | предпочтительно выше 100 Ом, особенно на 19 200 бит/с и выше |
Предельная длина зависит от скорости, кабеля, числа нагрузок и схемы включения. Адресов при этом больше, чем допускает электрика: адресовать можно 247 ведомых, а на одном сегменте без повторителя гарантированно работают 32 устройства.
Четырёхпроводная линия и RS-232
Четырёхпроводная схема — две пары и Common. По паре ведущего (RXD1–RXD0) передаёт только ведущий, и её слушают все ведомые; по паре ведомых (TXD1–TXD0) отвечают ведомые, и её слушает только ведущий. Цепи названы со стороны ведомого, поэтому у ведущего пары перекрещивают — кабелем или, что надёжнее, в ответвителе. Руководство отдельно замечает, что называть такую схему RS-422 неверно: RS-422 не допускает нескольких передатчиков на одной паре. Устройство с четырёхпроводным портом включают в двухпроводную шину, соединив у него TXD0 с RXD0 (получается D0) и TXD1 с RXD1 (получается D1).
RS-232 годится для соединения «точка — точка» на коротком расстоянии, по руководству — обычно меньше 20 м. TXD одного устройства соединяют с RXD другого, обязателен общий провод; RTS с CTS и DTR с DSR соединяют, если устройствам это нужно. Ограничение стандарта — ёмкость проводника на землю не больше 2500 пФ, что для кабеля с ёмкостью 100 пФ/м даёт 25 м. Кадры при этом те же, что и на RS-485; уровни и разъёмы — в статье RS-232. В руководстве Modicon 1996 года стандартный порт Modbus контроллера — именно RS-232C.
Разъёмы и цвета проводов
Винтовые клеммы допустимы всегда. Если же на устройстве стоит RJ45 или 9-контактный D-sub (DE-9), руководство требует такой разводки двухпроводного порта:
| Цепь | RJ45 | D-sub 9 | Статус |
|---|---|---|---|
| D1 | 4 | 5 | обязательна |
| D0 | 5 | 9 | обязательна |
| Common | 8 | 1 | обязательна |
| VP, питание 5–24 В | 7 | 2 | рекомендована |
| PMC, управление режимом порта | 3 | 3 | необязательна |
Рекомендованные цвета жил кабеля: D1 — жёлтый, D0 — коричневый, Common — серый. Перекрёстный кабель, включённый в двухпроводную шину, может повредить устройства — руководство требует предупреждать об этом в документации.
Формат символа: 11 бит, чётность и скорость
Каждый байт кадра RTU передаётся одним символом UART из 11 бит: старт-бит, 8 бит данных младшим битом вперёд, бит чётности и стоп-бит.
Правила руководства:
- Чётность even обязательна и включена по умолчанию. Формат по умолчанию — 8E1. Чётность odd (8O1) и режим без чётности допускаются как настраиваемые; режим без чётности руководство рекомендует поддерживать ради совместимости с другими изделиями.
- Без чётности — два стоп-бита. Место бита чётности занимает второй стоп-бит, формат называется 8N2, и символ остаётся 11-битным. Формат 8N1 — 10 бит на символ — руководству не соответствует.
- Настройки одинаковы у всех устройств линии. Ведомый, настроенный на другую чётность, увидит ошибку в символах запроса и просто не ответит.
Если в описании прибора всё же указано 8N1, с устройствами 8N2 он, скорее всего, договорится: приёмники USART микроконтроллеров AVR и STM32 и UART 16550 проверяют только первый стоп-бит, а второй для них — просто пауза (подробнее — в статье про UART). Чётность так обойти нельзя: 8E1 и 8N1 или 8N2 несовместимы.
Бит чётности ловит нечётное число искажённых битов в символе, CRC — искажения кадра в целом. Проверку CRC руководство требует всегда, проверку чётности — рекомендует.
| Скорость | Статус по руководству |
|---|---|
| 9600 бит/с | обязательна |
| 19 200 бит/с | обязательна, значение по умолчанию |
| 1200, 2400, 4800, 38 400 бит/с, 56 и 115 кбит/с | по выбору производителя |
В таблице классов устройств то же руководство мягче: для класса Basic обязательны только 9600 бит/с, а 19 200 бит/с рекомендованы и становятся значением по умолчанию, если реализованы.
Точность скорости тоже задана: передатчик должен выдерживать её с отклонением меньше 1 %, а приёмник — принимать при отклонении до 2 %. Ошибку делителя своего микроконтроллера проверьте в калькуляторе скорости UART: ATmega328P с кварцем 16 МГц даёт на 19 200 бит/с ошибку +0,16 %, а на 115 200 бит/с — +2,1 или −3,5 %, что в требование к передатчику уже не укладывается.
Структура кадра Modbus RTU
| Поле | Размер | Содержимое |
|---|---|---|
| Адрес | 1 байт | адрес ведомого: 1–247; 0 — широковещательный запрос; 248–255 зарезервированы |
| Код функции | 1 байт | действие, которое нужно выполнить; в ответе с ошибкой к коду прибавлено 0x80 |
| Данные | 0–252 байта | параметры запроса или результат: адреса, количества, значения |
| CRC | 2 байта | CRC-16 по всем предыдущим байтам кадра, младший байт первым |
Что важно помнить:
- В поле адреса всегда адрес ведомого — и в запросе, и в ответе: отвечая, ведомый ставит в кадр собственный адрес, чтобы ведущий видел, кто ответил. У ведущего адреса нет. Адреса на шине должны быть уникальными: руководство требует предупреждать в документации, что два устройства с одним адресом нарушают работу всей шины.
- Порядок байтов — старший первым (big-endian): адрес регистра 0x006B передаётся как
00 6B, значение 0x1234 — как12 34. Единственное исключение — CRC, у неё первым идёт младший байт. - Порядок битов — младший первым: так передаёт UART, и бит D0 символа на осциллограмме — младший бит байта.
- Наибольший кадр — 256 байт. На PDU остаётся 256 − 1 (адрес) − 2 (CRC) = 253 байта, из них один — код функции. Отсюда пределы функций: например, не больше 125 регистров в одном ответе.
- Наименьший кадр — 4 байта: адрес, код функции и CRC — у запросов без поля данных.
- Коды функций занимают диапазон 1–127; значения 128–255 отведены под ответы с ошибкой, ноль недопустим.
Собрать кадр из полей и разобрать принятый кадр по байтам удобно в калькуляторе кадров Modbus RTU.
Паузы t1,5 и t3,5: как приёмник находит границы кадра
В кадре RTU нет ни стартового символа, ни поля длины. Начало и конец кадра задаёт время:
- — тишина между кадрами. Кадры разделяет пауза не короче 3,5 символа. Приёмник считает кадр законченным, когда после очередного символа линия молчит дольше .
- — наибольшая пауза внутри кадра. Кадр передаётся сплошным потоком. Если между двумя символами тишина длится больше 1,5 символа, кадр считается неполным, и приёмник должен его отбросить.
Символ — это 11 бит, поэтому при скорости бит/с:
На высоких скоростях интервалы становятся короткими, а таймеры срабатывают часто и нагружают процессор. Поэтому руководство требует строго выдерживать оба интервала только до 19 200 бит/с включительно, а на более высоких скоростях рекомендует постоянные значения: 750 мкс для и 1,75 мс для .
| Скорость, бит/с | Бит | Символ, 11 бит | ||
|---|---|---|---|---|
| 1200 | 833 мкс | 9,17 мс | 13,75 мс | 32,08 мс |
| 2400 | 417 мкс | 4,58 мс | 6,88 мс | 16,04 мс |
| 4800 | 208 мкс | 2,29 мс | 3,44 мс | 8,02 мс |
| 9600 | 104 мкс | 1,146 мс | 1,72 мс | 4,01 мс |
| 19 200 | 52,1 мкс | 573 мкс | 859 мкс | 2,005 мс |
| 38 400 | 26,0 мкс | 286 мкс | 750 мкс | 1,75 мс |
| 57 600 | 17,4 мкс | 191 мкс | 750 мкс | 1,75 мс |
| 115 200 | 8,68 мкс | 95,5 мкс | 750 мкс | 1,75 мс |
На 115 200 бит/с постоянные 1,75 мс — это больше 18 символов, а 750 мкс — почти 8: пауза между кадрами получается намного длиннее расчётных 3,5 символа, зато требование к паузам внутри кадра мягче.
Приём по диаграмме состояний руководства идёт так:
- Первый символ после тишины — начало кадра. С каждым принятым символом приёмник перезапускает оба таймера.
- Если истёк таймер , новых символов в этом кадре быть уже не должно: приёмник проверяет CRC, чётность символов и адрес.
- Символ, который пришёл после , но до истечения , помечает кадр как ошибочный.
- Когда истекает , исправный кадр передаётся на обработку, ошибочный удаляется целиком. Только после этого устройство возвращается в состояние ожидания, из которого можно начинать и приём, и передачу.
Из последнего пункта следует, что ведомый начинает ответ не раньше чем через после последнего символа запроса, а ведущий — следующий запрос не раньше чем через после ответа. Адрес руководство разрешает сравнивать сразу, не дожидаясь конца кадра: тогда CRC считают только для кадров со своим или широковещательным адресом.
Как это делают на практике:
- Таймер в микроконтроллере. Таймер перезапускают в прерывании приёма каждого байта; если он досчитал до , кадр закончен. Учтите, что прерывание приходит в конце символа: между прерываниями двух символов, идущих вплотную, проходит ровно один символ. Поэтому паузе в 1,5 символа соответствует интервал 2,5 символа между прерываниями.
- Аппаратный таймаут приёмника. У USART некоторых микроконтроллеров есть счётчик тишины на линии. В STM32F0, например, библиотека HAL задаёт его функцией
HAL_UART_ReceiverTimeout_Config()в длительностях бита и включает функциейHAL_UART_EnableReceiverTimeout(); — это 38,5 бита. - Ведущий на компьютере. Кадр записывают в порт одним вызовом, а не побайтно: так меньше риск получить паузу между символами.
Модель данных: катушки, входы и регистры
Modbus представляет устройство как четыре таблицы данных:
| Таблица | Элемент | Доступ | Что в ней обычно лежит | Функции |
|---|---|---|---|---|
| Discrete Inputs — дискретные входы | 1 бит | только чтение | состояния входов устройства | 02 |
| Coils — катушки, дискретные выходы | 1 бит | чтение и запись | выходы и флаги, которыми управляет программа | 01, 05, 15 |
| Input Registers — входные регистры | 16 бит | только чтение | измеренные значения | 04 |
| Holding Registers — регистры хранения | 16 бит | чтение и запись | параметры и уставки, которые можно менять | 03, 06, 16, 22, 23 |
Названия пришли из контроллеров Modicon: катушкой (coil) там назывался дискретный выход. В каждой таблице протокол позволяет адресовать 65 536 элементов. Как таблицы связаны с памятью прибора, решает производитель: это могут быть четыре независимых блока, а могут быть разные способы доступа к одной и той же памяти — тогда один регистр читается и функцией 03, и функцией 04, а его биты доступны как катушки. Спецификация прямо называет такое наложение таблиц допустимым и очень распространённым.
Других типов данных, кроме бита и 16-битного слова, в протоколе нет. Знаковое число или беззнаковое, с каким множителем, в каких единицах — всё это описывает карта регистров конкретного прибора.
Номер регистра и адрес в кадре: ошибка на единицу
В модели данных элементы каждой таблицы нумеруются с единицы, а в кадре адресуются с нуля: элемент с номером X имеет адрес X − 1. Регистр хранения номер 1 — это адрес 0x0000, регистр номер 108 — адрес 107, то есть 0x006B.
В документации приборов поверх этого часто используется запись из контроллеров Modicon: перед номером элемента стоит цифра таблицы.
| Запись | Таблица | Функция чтения | Адрес в кадре |
|---|---|---|---|
| 0xxxx: 00001–09999 | катушки | 01 | номер − 1 |
| 1xxxx: 10001–19999 | дискретные входы | 02 | номер − 10001 |
| 3xxxx: 30001–39999 | входные регистры | 04 | номер − 30001 |
| 4xxxx: 40001–49999 | регистры хранения | 03 | номер − 40001 |
Первая цифра в кадр не попадает: таблицу выбирает код функции. Регистр 40108 — это функция 03 и адрес 40108 − 40001 = 107 = 0x006B. Пятизначная запись вмещает только 9999 элементов таблицы; чтобы охватить все 65 536, пишут шесть цифр: 400001–465536.
Отсюда три типичные ловушки:
- Сдвиг на единицу. В описании прибора может стоять и номер (с единицы), и адрес (с нуля), и не всегда сказано, что именно. Программы-ведущие тоже ведут себя по-разному: драйвер Kepware, например, по умолчанию вычитает единицу из введённого номера и позволяет это отключить. Если вместо ожидаемого значения читается соседний регистр, проверьте адрес на ±1.
- Цифра таблицы принята за часть адреса. Запрос с адресом 40108 (0x9CAC) вместо 107 обращается к совсем другому регистру и обычно заканчивается ошибкой 02.
- Не та таблица. Регистр 30010 читают функцией 04, регистр 40010 — функцией 03: это разные таблицы, даже если цифры после первой совпадают. Обратите внимание на несовпадение цифр: запись 4x — это функция 03, а запись 3x — функция 04.
Коды функций Modbus
Код функции говорит ведомому, что сделать. Спецификация делит коды на публичные — они описаны в самой спецификации, — пользовательские (65–72 и 100–110) и зарезервированные. Чаще всего нужны восемь функций:
| Код | Название в спецификации | Действие | За один запрос | Широковещательно |
|---|---|---|---|---|
| 01 (0x01) | Read Coils | чтение катушек | 1–2000 | нет |
| 02 (0x02) | Read Discrete Inputs | чтение дискретных входов | 1–2000 | нет |
| 03 (0x03) | Read Holding Registers | чтение регистров хранения | 1–125 | нет |
| 04 (0x04) | Read Input Registers | чтение входных регистров | 1–125 | нет |
| 05 (0x05) | Write Single Coil | запись одной катушки | 1 | да |
| 06 (0x06) | Write Single Register | запись одного регистра | 1 | да |
| 15 (0x0F) | Write Multiple Coils | запись группы катушек | 1–1968 | да |
| 16 (0x10) | Write Multiple registers | запись группы регистров | 1–123 | да |
Пределы следуют из размера PDU — 253 байта. Ответ на чтение 125 регистров — это код функции, счётчик байтов и 250 байт данных, всего 252 байта; 126 регистров дали бы уже 254. Запрос на запись 123 регистров занимает 1 + 2 + 2 + 1 + 246 = 252 байта. Широковещательными бывают только запросы на запись.
Устройство не обязано поддерживать все функции: их список приводят в документации. На неподдерживаемый код оно отвечает ошибкой 01.
В примерах ниже адрес ведомого — 17 (0x11), как в руководстве Modicon. Коды функций и данные взяты из примеров спецификации V1.1b3, CRC посчитаны нами; любой кадр можно проверить в калькуляторе CRC.
Чтение битов: функции 01 и 02
| Кадр | Поле | Размер | Значение |
|---|---|---|---|
| Запрос | код функции | 1 байт | 0x01 или 0x02 |
| адрес первого элемента | 2 байта | 0x0000–0xFFFF | |
| количество | 2 байта | 1–2000 (0x07D0) | |
| Ответ | код функции | 1 байт | 0x01 или 0x02 |
| счётчик байтов N | 1 байт | количество / 8 с округлением вверх | |
| состояния | N байт | бит на элемент: 1 — включён, 0 — выключен |
Биты упакованы так: младший бит первого байта данных — элемент с адресом из запроса, следующие идут к старшему биту и дальше в следующие байты. Лишние биты последнего байта равны нулю.
Функция 01, катушки 20–38:
Запрос: 11 01 00 13 00 13 8E 92
Ответ: 11 01 03 CD 6B 05 40 12
Функция 02, дискретные входы 197–218:
Запрос: 11 02 00 C4 00 16 BA A9
Ответ: 11 02 03 AC DB 35 20 18
В первом запросе адрес первой катушки 0x0013 = 19, количество 0x0013 = 19. В ответе три байта данных. Первый, CD = 1100 1101, — катушки 27…20: катушка 20 — младший бит, она включена. Последний, 05 = 0000 0101, — катушки 38, 37 и 36 в трёх младших битах; пять старших битов — нули. Во втором запросе адрес 0x00C4 = 196, количество 0x0016 = 22; байт AC = 1010 1100 — входы 204…197, байт 35 = 0011 0101 — входы 218…213.
Чтение регистров: функции 03 и 04
| Кадр | Поле | Размер | Значение |
|---|---|---|---|
| Запрос | код функции | 1 байт | 0x03 или 0x04 |
| адрес первого регистра | 2 байта | 0x0000–0xFFFF | |
| количество регистров | 2 байта | 1–125 (0x007D) | |
| Ответ | код функции | 1 байт | 0x03 или 0x04 |
| счётчик байтов | 1 байт | 2 × количество | |
| значения | 2 байта на регистр | старший байт первым |
Функция 03, регистры хранения 108–110:
Запрос: 11 03 00 6B 00 03 76 87
Ответ: 11 03 06 02 2B 00 00 00 64 C8 BA
Функция 04, входной регистр 9:
Запрос: 11 04 00 08 00 01 B2 98
Ответ: 11 04 02 00 0A F8 F4
В первом ответе 6 байт данных: 0x022B = 555, 0x0000 = 0 и 0x0064 = 100. Во втором запросе адрес 0x0008, количество 1, значение регистра — 0x000A = 10.
Длина обычного ответа на функции 03 и 04 известна заранее: 5 + 2 × количество байт. Ведущему это удобно: зная длину, он может проверить CRC сразу после последнего байта — паузу перед следующим запросом это не отменяет. Ответ с ошибкой всегда занимает 5 байт.
Запись одного значения: функции 05 и 06
| Кадр | Поле | Размер | Значение |
|---|---|---|---|
| Запрос | код функции | 1 байт | 0x05 или 0x06 |
| адрес катушки или регистра | 2 байта | 0x0000–0xFFFF | |
| значение | 2 байта | функция 05: 0xFF00 — включить, 0x0000 — выключить; функция 06: 0x0000–0xFFFF | |
| Ответ | те же поля | 5 байт | повтор запроса |
Функция 05, включить катушку 173:
Запрос: 11 05 00 AC FF 00 4E 8B
Ответ: 11 05 00 AC FF 00 4E 8B
Функция 06, записать 0x0003 в регистр 2:
Запрос: 11 06 00 01 00 03 9A 9B
Ответ: 11 06 00 01 00 03 9A 9B
Для функции 05 допустимы только два значения: FF 00 включает катушку, 00 00 выключает; на любое другое устройство отвечает ошибкой 03 и катушку не трогает. Ответ приходит после того, как запись выполнена, и повторяет запрос байт в байт — ведущему достаточно сравнить два кадра.
Запись группы: функции 15 и 16
| Кадр | Поле | Размер | Функция 15 (0x0F) | Функция 16 (0x10) |
|---|---|---|---|---|
| Запрос | код функции | 1 байт | 0x0F | 0x10 |
| адрес первого элемента | 2 байта | 0x0000–0xFFFF | 0x0000–0xFFFF | |
| количество | 2 байта | 1–1968 (0x07B0) катушек | 1–123 (0x007B) регистров | |
| счётчик байтов | 1 байт | количество / 8 с округлением вверх | 2 × количество | |
| значения | по счётчику | бит на катушку, первая — в младшем бите | 2 байта на регистр, старший первым | |
| Ответ | код функции | 1 байт | 0x0F | 0x10 |
| адрес первого элемента | 2 байта | как в запросе | как в запросе | |
| количество | 2 байта | как в запросе | как в запросе |
Функция 15, записать 10 катушек начиная с катушки 20:
Запрос: 11 0F 00 13 00 0A 02 CD 01 BF 0B
Ответ: 11 0F 00 13 00 0A 26 99
Функция 16, записать 0x000A и 0x0102 в регистры 2 и 3:
Запрос: 11 10 00 01 00 02 04 00 0A 01 02 C6 F0
Ответ: 11 10 00 01 00 02 12 98
В первом запросе два байта данных, CD 01: байт CD задаёт катушки 27…20, два младших бита байта 01 — катушки 29 и 28. Счётчик байтов должен соответствовать количеству: если они не сходятся, устройство отвечает ошибкой 03.
Многие приборы сторонних производителей принимают запись в регистры только функцией 16, даже когда регистр один, — об этом предупреждает документация драйвера Kepware. 32-битное значение, занимающее два регистра, в любом случае записывают одной командой 16, чтобы половины не разошлись.
Функции 22, 23 и 43/14
- 22 (0x16), Mask Write Register, устанавливает и сбрасывает отдельные биты регистра хранения, не затрагивая остальные. В запросе — адрес регистра и две маски, And_Mask и Or_Mask; результат = (текущее значение AND And_Mask) OR (Or_Mask AND NOT And_Mask). Пример спецификации: в регистре 5 (адрес 4) записано 0x12, And_Mask = 0x00F2, Or_Mask = 0x0025 — получится 0x17. Кадр —
11 16 00 04 00 F2 00 25 66 E2, ответ повторяет запрос. - 23 (0x17), Read/Write Multiple registers, записывает и читает регистры хранения за одну транзакцию; запись выполняется первой. За один запрос — до 121 регистра на запись и до 125 на чтение.
- 43/14 (0x2B/0x0E), Read Device Identification, читает текстовые сведения об устройстве. Обязательные объекты — название производителя, код изделия и номер версии; остальные — по выбору производителя. Запрос основных сведений:
11 2B 0E 01 00 B1 B4.
Диагностика: функция 08
Функции 07, 08, 11, 12 и 17 определены только для последовательной линии. При отладке полезнее всего функция 08 (Diagnostics) с подфункцией 0x0000, Return Query Data: ведомый возвращает запрос без изменений.
Запрос: 11 08 00 00 A5 37 D8 1D
Ответ: 11 08 00 00 A5 37 D8 1D
Это «пинг» Modbus: он не обращается к данным прибора и проверяет весь путь — провода, скорость, чётность, адрес и CRC. Другие подфункции возвращают счётчики, которые ведомый ведёт сам:
| Подфункция | Счётчик |
|---|---|
| 0x0B | кадры, которые устройство увидело на шине, без кадров с ошибкой CRC |
| 0x0C | ошибки связи: CRC, чётность, переполнение |
| 0x0D | ответы с ошибкой, отправленные устройством |
| 0x0E | запросы, адресованные устройству или всем и обработанные им |
| 0x0F | запросы, на которые устройство не ответило |
| 0x12 | переполнения приёмника |
Поддерживает ли прибор функцию 08, сказано в его документации. С подфункцией 0x04 осторожнее: она переводит устройство в режим «только приём», и оно перестаёт отвечать, пока не получит подфункцию 0x01 — перезапуск связи.
Коды ошибок Modbus: ответ с исключением
На запрос ведомый реагирует одним из трёх способов:
- запрос принят без ошибок связи и выполнен — обычный ответ;
- запрос не дошёл или дошёл с ошибкой связи (чётность, CRC) — ответа нет, и у ведущего истекает таймаут;
- запрос принят без ошибок связи, но выполнить его нельзя — ответ с ошибкой (exception response).
В ответе с ошибкой код функции возвращается с установленным старшим битом, то есть увеличенным на 0x80, а единственный байт данных — код исключения:
Запрос: 11 01 04 A1 00 01 AF 88 прочитать одну катушку по адресу 0x04A1
Ответ: 11 81 02 C0 54 0x81 = 0x01 + 0x80, код исключения 02
| Код | Название | Когда возвращается |
|---|---|---|
| 01 | ILLEGAL FUNCTION | функция не поддерживается устройством или недопустима в его текущем состоянии |
| 02 | ILLEGAL DATA ADDRESS | адрес или сочетание адреса и количества выходит за пределы таблицы |
| 03 | ILLEGAL DATA VALUE | недопустимое значение в полях запроса: количество вне пределов, не сходится счётчик байтов |
| 04 | SERVER DEVICE FAILURE | неустранимая ошибка при выполнении запроса |
| 05 | ACKNOWLEDGE | запрос принят, но выполняется долго; используется с командами программирования |
| 06 | SERVER DEVICE BUSY | устройство занято длительной командой; запрос нужно повторить позже |
| 08 | MEMORY PARITY ERROR | ошибка чётности памяти при работе с файловыми записями (функции 20 и 21) |
| 0A | GATEWAY PATH UNAVAILABLE | шлюз не смог проложить путь к адресату: неверно настроен или перегружен |
| 0B | GATEWAY TARGET DEVICE FAILED TO RESPOND | шлюз не получил ответа от адресата: обычно такого устройства нет в сети |
Уточнения из спецификации:
- Код 02 зависит и от количества. Если в устройстве 100 регистров с адресами 0–99, запрос четырёх регистров с адреса 96 выполнится, а запрос пяти вернёт ошибку 02.
- Код 03 говорит о неправильном строении запроса, а не о том, что значение не подходит прибору по смыслу: протокол не знает, что означает содержимое регистров.
- Сначала проверяется код функции, затем параметры запроса — количество и адреса, — и только потом запрос выполняется. Поэтому код 01 означает, что до проверки адреса дело не дошло.
- На широковещательный запрос не отвечают никогда — ни обычным ответом, ни ошибкой.
В старых документах коды 04 и 06 называются SLAVE DEVICE FAILURE и SLAVE DEVICE BUSY, а в руководстве Modicon 1996 года был ещё код 07, NEGATIVE ACKNOWLEDGE; в действующей спецификации его нет.
CRC-16 в Modbus RTU: алгоритм и код на C
Последние два байта кадра — 16-битная CRC, рассчитанная по всем остальным байтам: адресу, коду функции и данным. В расчёт входят только восемь бит данных каждого символа — старт-бит, стоп-бит и бит чётности в нём не участвуют. Алгоритм по приложению B руководства:
- Загрузить в 16-битный регистр значение 0xFFFF.
- Сложить по модулю 2 (XOR) очередной байт кадра с младшим байтом регистра.
- Сдвинуть регистр на один бит вправо, в старший бит вдвинуть ноль.
- Если выдвинутый бит был единицей, сложить регистр по модулю 2 с константой 0xA001.
- Повторить шаги 3 и 4, пока не будет сделано восемь сдвигов.
- Повторить шаги 2–5 для всех байтов кадра. То, что осталось в регистре, и есть CRC.
В кадр CRC записывают младшим байтом вперёд: если в регистре 0x1241, в линию уходит 41, затем 12. Константа 0xA001 — это порождающий полином x¹⁶ + x¹⁵ + x² + 1 (0x8005), записанный в обратном порядке битов; в каталогах алгоритм называется CRC-16/MODBUS.
#include <stddef.h>
#include <stdint.h>
/* CRC-16/MODBUS: initial value 0xFFFF, polynomial 0xA001 (0x8005 reflected), no final XOR.
* Check: for the bytes 02 07 the result is 0x1241, on the wire 41 12
* (the example in MODBUS over Serial Line V1.02, Appendix B). */
uint16_t modbus_crc16(const uint8_t *data, size_t len)
{
uint16_t crc = 0xFFFF;
while (len--) {
crc ^= *data++; /* the byte goes into the low half */
for (uint8_t bit = 0; bit < 8; bit++) {
if (crc & 0x0001)
crc = (uint16_t)((crc >> 1) ^ 0xA001);
else
crc >>= 1;
}
}
return crc;
}
/* Appends the CRC to a frame of len bytes, low byte first. Returns the new length. */
size_t modbus_append_crc(uint8_t *frame, size_t len)
{
uint16_t crc = modbus_crc16(frame, len);
frame[len] = (uint8_t)(crc & 0xFF); /* CRC low byte goes first */
frame[len + 1] = (uint8_t)(crc >> 8); /* CRC high byte is the last byte */
return len + 2;
}
/* A received frame is intact if the CRC over all its bytes, the CRC field included, is zero. */
int modbus_frame_ok(const uint8_t *frame, size_t len)
{
return len >= 4 && modbus_crc16(frame, len) == 0;
}
Проверить реализацию можно на примере из руководства: для кадра из двух байтов 02 07 в регистре получается 0x1241, и в линию уходит 41 12 — в руководстве итог так и записан, 4112, в порядке передачи. Второй ориентир — контрольное значение каталогов: CRC строки «123456789» равна 0x4B37. Этот и два следующих листинга собраны компилятором MSVC с предупреждениями уровня 4 и проверены на значениях из примеров статьи.
Приёмнику не обязательно сравнивать CRC с двумя последними байтами: если прогнать через тот же алгоритм весь кадр вместе с CRC, в регистре останется ноль. Кадр короче четырёх байтов заведомо негоден.
Табличный вариант. Побитовый расчёт делает восемь итераций на байт. Табличный быстрее: значения для всех 256 возможных байтов считают заранее, и на байт кадра уходит одно обращение к таблице. В приложении B руководства приведена такая функция с двумя таблицами по 256 байт — для старшего и для младшего байта CRC. Готовый код обоих вариантов выдаёт калькулятор CRC; им же удобно проверять кадры.
Если берёте функцию из руководства, проверьте её на том же примере. Мы воспроизвели оба листинга: в редакции V1.02 функция возвращает 0x1241 — обычное значение, младший байт которого передаётся первым, — хотя примечание рядом утверждает, что байты уже переставлены. Примечание осталось от руководства Modicon 1996 года, где такая же функция действительно возвращала 0x4112.
Пример: собираем запрос и разбираем ответ
Задача: прочитать регистры хранения 40108–40110 у прибора с адресом 17 на скорости 9600 бит/с в формате 8E1.
- Функция. Запись 4xxxx означает регистры хранения — функция 03.
- Адрес. 40108 − 40001 = 107 = 0x006B.
- Количество. Три регистра — 0x0003.
- Кадр без CRC:
11 03 00 6B 00 03. - CRC. Регистр начинается с 0xFFFF и после каждого байта принимает значения из таблицы ниже. Итог — 0x8776, в кадр идут байты
76 87. - Запрос целиком:
11 03 00 6B 00 03 76 87— 8 символов по 11 бит, 9,17 мс на линии.
| Байт кадра | 11 | 03 | 00 | 6B | 00 | 03 |
|---|---|---|---|---|---|---|
| Регистр CRC после байта | 0x4C7F | 0xE14D | 0x3521 | 0xF7B4 | 0x77F7 | 0x8776 |
Ответ прибора: 11 03 06 02 2B 00 00 00 64 C8 BA. Проверяем по порядку:
- CRC по всем 11 байтам равна нулю — кадр не искажён.
- Адрес 0x11 — ответил тот, кого спрашивали.
- Код функции 0x03, а не 0x83, — это обычный ответ, а не ошибка.
- Счётчик байтов 0x06 = 2 × 3, длина кадра 5 + 6 = 11 байт — сходится с запросом.
- Данные: 0x022B = 555, 0x0000 = 0, 0x0064 = 100.
То же самое на C — с функциями расчёта CRC из предыдущего раздела:
/* Builds a "read holding registers" request (function 03). Returns the frame length: 8. */
size_t modbus_read_holding_request(uint8_t *frame, uint8_t slave,
uint16_t address, uint16_t count)
{
frame[0] = slave;
frame[1] = 0x03;
frame[2] = (uint8_t)(address >> 8); /* high byte first */
frame[3] = (uint8_t)(address & 0xFF);
frame[4] = (uint8_t)(count >> 8);
frame[5] = (uint8_t)(count & 0xFF);
return modbus_append_crc(frame, 6);
}
/* Checks the response to that request and copies the register values.
* Returns 0 on success, the exception code (1..255) if the slave refused the request,
* -1 if the frame is damaged, comes from another slave or has an unexpected layout. */
int modbus_read_holding_response(const uint8_t *frame, size_t len, uint8_t slave,
uint16_t count, uint16_t *values)
{
if (!modbus_frame_ok(frame, len) || frame[0] != slave)
return -1;
if (frame[1] == 0x83) /* exception: 03 + 0x80, code, CRC */
return len == 5 ? frame[2] : -1;
if (frame[1] != 0x03 || len != 5u + 2u * count || frame[2] != 2u * count)
return -1;
for (uint16_t i = 0; i < count; i++)
values[i] = (uint16_t)((frame[3 + 2 * i] << 8) | frame[4 + 2 * i]);
return 0;
}
Сколько времени занимает опрос. Запрос — 9,17 мс, пауза перед ответом — не меньше = 4,01 мс, ответ из 11 символов — 12,6 мс, пауза перед следующим запросом — ещё 4,01 мс. Итого не меньше 29,8 мс, то есть не больше 33 опросов в секунду, — и это без времени, которое прибор тратит на обработку запроса. Чтение 125 регистров одним запросом (ответ — 255 байт) займёт на той же скорости около 0,31 с.
Обмен ведущего и ведомых: таймаут, широковещательный запрос, повторы
Адресный запрос (unicast). Ведущий отправляет кадр с адресом ведомого и запускает таймер ожидания — таймаут ответа (response time-out). Ведомый проверяет кадр, выполняет запрос и отвечает. Пока ответ не получен или таймаут не истёк, новый запрос отправлять нельзя: на шине в каждый момент идёт только одна транзакция.
Широковещательный запрос (broadcast). Кадр с адресом 0 принимают и выполняют все ведомые, и никто не отвечает. Широковещательными бывают только команды записи; в руководстве Modicon это функции 05, 06, 15 и 16. Раз ответа нет, ведущий не знает, дошла ли команда. Он лишь выдерживает паузу (turnaround delay), чтобы ведомые успели обработать запрос, и только потом передаёт снова.
Что делает ведущий с ответом:
- ответ от нужного ведомого без ошибок — транзакция завершена;
- ответ от другого ведомого — ведущий его не принимает и продолжает ждать, таймаут не перезапускается;
- кадр с ошибкой CRC или чётности — запрос можно повторить;
- ответа нет — по истечении таймаута фиксируется ошибка, после чего запрос можно повторить. Число повторов руководство оставляет на усмотрение ведущего.
Оба интервала зависят от приложения. Ориентиры руководства: таймаут ответа — от 1 с до нескольких секунд при 9600 бит/с, пауза после широковещательного запроса — 100–200 мс. Таймаут должен покрывать самую долгую обработку запроса самым медленным ведомым; пауза после широковещательного запроса короче, потому что ответ передавать не нужно.
Два практических следствия:
- Отсутствующий прибор тормозит опрос остальных. При каждом обращении к нему ведущий ждёт полный таймаут. С таймаутом 1 с и тремя попытками один неотвечающий адрес останавливает опрос на 3 с — такие адреса исключают из опроса или опрашивают реже.
- Слишком короткий таймаут хуже слишком длинного. Опоздавший ответ придёт, когда ведущий уже передаёт следующий запрос: кадры столкнутся на шине либо ведущий примет старый ответ за новый.
32-битные числа и float в двух регистрах
Регистр Modbus — 16 бит, и других числовых типов в протоколе нет. 32-битное целое или число с плавающей запятой прибор раскладывает на два соседних регистра, 64-битное — на четыре. Внутри регистра порядок определён — старший байт первым, — а в каком регистре лежит старшая половина числа, спецификация не говорит. Производители решили это по-разному, и вариантов четыре. Их принято обозначать буквами — так делают, например, библиотеки libmodbus и ESP-Modbus: A — старший байт числа, D — младший.
| Порядок | Регистр N | Регистр N + 1 | Байты в ответе | Как его называют |
|---|---|---|---|---|
| ABCD | 0x47F1 | 0x2000 | 47 F1 20 00 | big-endian; в библиотеке libmodbus — «обычный формат Modbus» |
| CDAB | 0x2000 | 0x47F1 | 20 00 47 F1 | перестановка слов (word swap), младшее слово первым; соглашение Modicon Modsoft |
| BADC | 0xF147 | 0x0020 | F1 47 00 20 | перестановка байтов (byte swap) |
| DCBA | 0x0020 | 0xF147 | 00 20 F1 47 | little-endian |
Если порядок в документации прибора не указан, его определяют так:
- Прочитайте оба регистра одним запросом: между двумя отдельными запросами значение может измениться, и половины окажутся от разных чисел.
- Возьмите параметр, значение которого известно хотя бы приблизительно: напряжение сети, температуру в комнате, уставку, которую видно на экране прибора.
- Расшифруйте четыре байта всеми четырьмя способами. Правильный порядок даст правдоподобное число, остальные — абсурдные. Например, байты
43 66 80 00— это 230,5 в порядке ABCD и −2,4 · 10⁻⁴¹, 2,3 · 10²³ или 1,2 · 10⁻³⁸ в трёх остальных. - У целых счётчиков смотрите, какой регистр меняется чаще: быстро меняющаяся половина — младшая.
Все четыре варианта сразу показывает калькулятор кадров Modbus RTU в режиме разбора ответа.
#include <stdint.h>
#include <string.h>
/* Builds an IEEE 754 single-precision value from two registers.
* ABCD order: modbus_to_float(reg[0], reg[1]).
* CDAB order (word swap): modbus_to_float(reg[1], reg[0]).
* Check: modbus_to_float(0x47F1, 0x2000) == 123456.0f.
* Assumes that float is a 32-bit IEEE 754 type, as on ARM, AVR and x86. */
float modbus_to_float(uint16_t high_word, uint16_t low_word)
{
uint32_t bits = ((uint32_t)high_word << 16) | low_word;
float value;
memcpy(&value, &bits, sizeof value); /* copy the bit pattern, no pointer casts */
return value;
}
Для порядков BADC и DCBA сначала меняют местами байты в каждом регистре — получаются соответственно ABCD и CDAB. Та же неоднозначность — у 64-битных чисел и у строк: в регистре помещаются два символа, и какой из них первый, тоже зависит от прибора.
Типичные ошибки
| Симптом | Вероятная причина | Что проверить |
|---|---|---|
| Ведомый не отвечает, у ведущего таймаут | разные скорость или формат символа (8E1 и 8N1); не тот адрес; перепутаны D1 и D0; CRC записана старшим байтом вперёд | настройки порта на обеих сторонах, адрес прибора, полярность линии в паузе, CRC кадра |
| Ответ с ошибкой 02 | адрес сдвинут на единицу, цифра таблицы попала в адрес, запрошено больше элементов, чем есть | адрес = номер − 1; количество; карту регистров |
| Читается соседний регистр | номер подставлен вместо адреса или наоборот | прочитать регистры N − 1, N и N + 1 и сравнить с известным значением |
| Ответ с ошибкой 01 | функция не поддерживается: 03 вместо 04, 06 вместо 16 | список функций в документации прибора |
| Ответ с ошибкой 03 на большой запрос | больше 125 регистров или 2000 битов за один запрос | разбить чтение на несколько запросов |
| Абсурдные значения 32-битных параметров | не тот порядок слов или байтов | четыре порядка на известном значении |
| Ошибки CRC, испорчен последний байт кадра | передатчик выключается раньше конца стоп-бита | сигнал DE и линию осциллографом |
| Теряется начало ответа | ведущий отпускает шину позже, чем через 3,5 символа после запроса | момент снятия DE после последнего байта |
| Ведомый не принимает запросы с компьютера, хотя CRC верна | паузы между байтами запроса длиннее 1,5 символа | запрос — логическим анализатором; запись кадра одним вызовом |
| Лишние байты между кадрами, ответы через раз | нет поляризации, и в паузе приёмники ловят шум; терминаторов больше двух | поляризацию в одной точке, число терминаторов |
| По одному приборы работают, вместе — сбои | два устройства с одним адресом; короткий таймаут, и опоздавший ответ сталкивается со следующим запросом | адреса; таймаут с запасом |
| Ведущий принимает собственный запрос | приёмник трансивера включён во время передачи | отбрасывать эхо или выключать приёмник на время передачи |
| На STM32 не сходится чётность | бит чётности входит в длину слова: для 8E1 нужно слово из 9 бит | настройку длины слова, см. UART в STM32 |
Про управление передатчиком стоит сказать отдельно. Ведомый вправе начать ответ уже через после запроса — это 4 мс при 9600 бит/с и 1,75 мс на высоких скоростях. К этому моменту ведущий должен отпустить шину, но не раньше, чем уйдёт стоп-бит последнего байта CRC. По какому флагу UART снимать сигнал DE, разобрано в статье про RS-485, в разделе «Когда включать и выключать передатчик».
Как отлаживать Modbus RTU
- Сначала линия. При выключенном питании омметр между D1 и D0 должен показать около 75 Ом, если стоят два терминатора по 150 Ом, или около 60 Ом, если два по 120 Ом. Терминаторы 120 Ом + 1 нФ омметр «не видит» — конденсатор не пропускает постоянный ток. Под напряжением в паузе D1 должна быть положительнее D0 не меньше чем на 0,2 В, если поляризация включена. Остальные проверки — в разделе «Как проверить и отладить линию RS-485».
- Параметры порта. Скорость, 8 бит данных, чётность и число стоп-битов должны совпадать у ведущего и всех ведомых. По руководству значения по умолчанию — 19 200 бит/с и 8E1, но заводские настройки конкретного прибора нужно смотреть в его документации.
- Один ведомый, простой запрос. Оставьте на шине одно устройство и отправьте самое простое: чтение одного регистра функцией 03 или эхо-запрос функцией 08. Запрос соберите в калькуляторе кадров, чтобы исключить ошибку в CRC.
- Смотрите байты. Логический анализатор с декодером UART на выводах RO и DI трансивера покажет запрос и ответ побайтно; декодеру нужно задать тот же формат символа, иначе он покажет ошибки чётности. Второй способ — слушать шину отдельным переходником USB–RS-485.
- Тишина или ошибка? Ответа нет — ищите проблему на уровне связи: адрес, скорость, чётность, CRC, паузы внутри кадра. Пришёл ответ с ошибкой — связь работает, а неверны функция, адрес или количество.
- Паузы и направление. Проверьте, что запрос идёт без разрывов, сигнал DE включается до старт-бита первого байта и выключается после стоп-бита последнего, а ответ начинается не раньше чем через .
- Таймаут. Измерьте, через сколько прибор отвечает на самый «тяжёлый» запрос, и задайте таймаут с запасом.
- Счётчики прибора. Если прибор поддерживает функцию 08, прочитайте счётчик кадров на шине (подфункция 0x0B) и счётчик ошибок связи (0x0C): они покажут, видит ли прибор ваши запросы и сколько из них приходит искажёнными.
Дальше по теме: RS-485 — линия, по которой обычно работает Modbus RTU, UART — формат символа, чётность и точность скорости, RS-232 — соединение «точка — точка». Если узлы должны передавать сами, без опроса ведущим, посмотрите на шину CAN. Остальные интерфейсы — в разделе «Интерфейсы».
Частые вопросы
Чем Modbus RTU отличается от Modbus ASCII и Modbus TCP?
Запросы и ответы — код функции и данные — у всех трёх одинаковы, различается оболочка. В RTU байты идут в двоичном виде, кадр ограничен паузами не короче 3,5 символа и защищён CRC-16. В ASCII каждый байт передаётся двумя символами, кадр начинается двоеточием, заканчивается символами CR и LF и защищён LRC. В Modbus TCP перед кодом функции стоит заголовок MBAP из 7 байт, своей контрольной суммы нет, порт — 502.
Какие настройки порта у Modbus RTU по умолчанию?
По руководству Modbus over Serial Line — 19 200 бит/с, 8 бит данных, чётность even и один стоп-бит (8E1); скорость 9600 бит/с тоже обязательна. Если чётность отключена, стоп-битов должно быть два (8N2), чтобы символ оставался 11-битным. У конкретного прибора заводские настройки могут быть другими, поэтому скорость, чётность и адрес сверяют по его документации: на одной линии они должны совпадать у всех устройств.
Чем регистры хранения отличаются от входных регистров?
Это две разные таблицы 16-битных слов. Входные регистры (input registers, запись 3xxxx) доступны только для чтения функцией 04. Регистры хранения (holding registers, запись 4xxxx) читают функцией 03 и записывают функциями 06 и 16. Адреса в каждой таблице считаются отдельно, с нуля. Производитель может и наложить таблицы друг на друга — тогда одно и то же значение читается обеими функциями.
Сколько устройств можно подключить к одной линии Modbus RTU?
Адресов хватает на 247 ведомых: 1–247, адрес 0 — широковещательный, 248–255 зарезервированы. Электрически руководство гарантирует 32 устройства на сегменте RS-485 без повторителя; больше — если устройства нагружают линию слабее и это указано в их документации. Поляризация линии уменьшает допустимое число устройств на 4. Сегменты соединяют повторителями.
Нужны ли терминаторы и подтяжка на линии Modbus RTU?
Терминаторы руководство требует: по одному у каждого из двух концов магистрали, между D1 и D0 — резистор 150 Ом или цепочка 120 Ом + 1 нФ. На отводах и в середине линии их не ставят. Подтяжка (поляризация) нужна, если она требуется хотя бы одному устройству: один резистор 450–650 Ом от D1 к 5 В и такой же от D0 к общему проводу, в одной точке на всю шину, обычно у ведущего.
Почему устройство Modbus RTU не отвечает на запрос?
Ведомый молчит, если кадр до него не дошёл или дошёл с ошибкой: не совпадают скорость или чётность, указан чужой адрес, перепутаны линии D1 и D0, CRC неверна или записана старшим байтом вперёд, между байтами запроса была пауза длиннее 1,5 символа. На широковещательный адрес 0 ответа не бывает никогда. Если же прибор ответил кадром с кодом функции, увеличенным на 0x80, связь исправна, а ошибка — в функции, адресе или количестве.
Источники
- Modbus Organization. MODBUS over Serial Line Specification and Implementation Guide V1.02, 20.12.2006 — разд. 2.1–2.4 — ведущий и ведомые, адреса, таймаут ответа и пауза после широковещательного запроса; разд. 2.5 — символ из 11 бит, кадр RTU, паузы t1,5 и t3,5, режим ASCII; разд. 3 — RS-485 и RS-232, скорости, терминаторы, поляризация, длина линии, разъёмы; разд. 5 — классы устройств; прил. A и B — счётчики диагностики, алгоритм CRC и пример для кадра 02 07
- Modbus Organization. MODBUS Application Protocol Specification V1.1b3, 26.04.2012 — разд. 4 — PDU не больше 253 байт, порядок байтов, модель данных и адресация с нуля; разд. 5 и 6 — коды функций, пределы и побайтные примеры запросов и ответов; разд. 7 — ответы с ошибкой и коды исключений
- Modbus Organization. MODBUS Messaging on TCP/IP Implementation Guide V1.0b, 24.10.2006 — разд. 3.1 — заголовок MBAP из 7 байт, поле Unit Identifier вместо адреса ведомого, порт 502
- Modicon, Inc. Modbus Protocol Reference Guide, PI-MBUS-300 Rev. J, июнь 1996 — исходное руководство Modicon, копия на сайте ProSoft Technology: порт Modbus на RS-232C, ссылки 0X, 1X, 3X и 4X, регистр 40001 как адрес 0000, функции с широковещательным запросом, код исключения 07, табличная функция CRC
- Modbus Organization. Introduction to Modbus — история: Modicon, 1979 год; диапазоны номеров 00001–09999, 10001–19999, 30001–39999 и 40001–49999; относительные адреса в кадре
- Kepware Technologies. Modbus RTU Serial Driver Help, 2012 — шестизначные номера 400001–465536; вычитание единицы из номера при формировании кадра; порядок слов first word low как соглашение Modicon Modsoft; устройства, принимающие запись только функцией 16; строки с порядком байтов HiLo и LoHi
- libmodbus. Справочник функций: modbus_get_float_abcd(), _badc(), _cdab(), _dcba() — четыре порядка байтов 32-битного числа в двух регистрах и пример: 123456,0 — регистры 0x47F1 и 0x2000
- Greg Cook. Catalogue of parametrised CRC algorithms (CRC RevEng): CRC-16/MODBUS — параметры алгоритма: полином 0x8005, начальное значение 0xFFFF, отражение входа и выхода, контрольное значение 0x4B37, остаток 0x0000
- Espressif Systems. ESP-Modbus Programming Guide: Modbus messaging and mapping — те же обозначения порядков ABCD, CDAB, BADC и DCBA для 32-битных типов
- MaxLinear. SP3485: 3.3V Low Power Half-Duplex RS-485 Transceiver with 10Mbps Data Rate, ред. 2.0.2, 2021 — вывод A — неинвертирующий, B — инвертирующий; таблица истинности передатчика; чувствительность приёмника ±200 мВ
- STMicroelectronics. STM32F0 HAL: stm32f0xx_hal_uart.c — функции HAL_UART_ReceiverTimeout_Config() и HAL_UART_EnableReceiverTimeout(): аппаратный таймаут приёмника, значение — в длительностях бита