Перейти к содержанию

Протокол Modbus RTU

Modbus RTU — двоичный протокол «ведущий — ведомые» поверх UART: кадр состоит из адреса устройства, кода функции, данных и CRC-16, а границей кадра служит тишина на линии не короче 3,5 символа. Ниже — физический уровень, формат символа и кадра, функции с примерами побайтно, расчёт CRC на C и разбор типичных ошибок.

Обновлено Редакция GAW

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 RTUModbus ASCIIModbus 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 у устройства 1711 03 00 6B 00 03 76 87:1103006B00037E и CR LF00 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 RTU: D1, D0 и Common, терминаторы и поляризацияМагистраль из витой пары D1 и D0 и проводника Common идёт от ведущего к последнему ведомому. На двух концах магистрали между D1 и D0 включены терминаторы LT — резистор 120 Ом последовательно с конденсатором 1 нФ. В одной точке шины, обычно у ведущего, стоят резисторы поляризации 450–650 Ом: один подтягивает D1 к +5 В, другой соединяет D0 с Common. Проводник Common в одной точке соединён с защитной землёй. Устройства подключены к магистрали короткими отводами.D1D0CommonLT120 Ом1 нФLT120 Ом1 нФ+5 ВR1450–650 ОмR2450–650 Омполяризация — одна пара резисторов на всю шину, обычно у ведущегозащитная земля,в одной точкеэкранированная витая пара,до 1000 м при 9600 бит/сВедущийМК + трансиверВедомый 1адрес 1Ведомый 2адрес 2Ведомый Nадрес до 247…D1 в паузе положительнее D0: по TIA/EIA-485 это линия B/B′, у большинства микросхем — вывод A. D0 — линия A/A′, вывод B микросхем.LT — терминаторы на двух концах магистрали: 120 Ом + 1 нФ или резистор 150 Ом. Отводы к устройствам — не длиннее 20 м.
Двухпроводная линия Modbus: магистраль D1, D0 и Common, терминаторы LT на двух концах, одна пара резисторов поляризации на всю шину, общий провод заземлён в одной точке.
Цепь ModbusПо TIA/EIA-485У микросхем трансиверовПризнак
D1B/B′вывод A, неинвертирующийпри двоичной единице напряжение на D1 выше, чем на D0
D0A/A′вывод B, инвертирующийпри двоичном нуле напряжение на D0 выше, чем на D1
CommonC/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), руководство требует такой разводки двухпроводного порта:

ЦепьRJ45D-sub 9Статус
D145обязательна
D059обязательна
Common81обязательна
VP, питание 5–24 В72рекомендована
PMC, управление режимом порта33необязательна

Рекомендованные цвета жил кабеля: D1 — жёлтый, D0 — коричневый, Common — серый. Перекрёстный кабель, включённый в двухпроводную шину, может повредить устройства — руководство требует предупреждать об этом в документации.

Формат символа: 11 бит, чётность и скорость

Каждый байт кадра RTU передаётся одним символом UART из 11 бит: старт-бит, 8 бит данных младшим битом вперёд, бит чётности и стоп-бит.

Символ Modbus RTU: 11 бит в форматах 8E1 и 8N2Байт 0x6B передаётся младшим битом вперёд: старт-бит 0, биты данных 1, 1, 0, 1, 0, 1, 1, 0. В формате 8E1 за данными идут бит чётности even, здесь равный 1, и один стоп-бит. В формате 8N2 бита чётности нет, а стоп-битов два. В обоих случаях символ занимает 11 бит: 1,146 мс при 9600 бит/с и 573 мкс при 19 200 бит/с.8E1: бит чётности even — формат по умолчаниюСтарт0D01D11D20D31D40D51D61D70Чётн.1Стоп1TXD10в байте 0x6B единиц 5, бит чётности равен 1: вместе с ним единиц 6 — чётное число8N2: без чётности — два стоп-битаСтарт0D01D11D20D31D40D51D61D70Стоп1Стоп1TXD10второй стоп-бит занимает место бита чётности — символ по-прежнему 11 бит1 символ = 11 бит: 1,146 мс при 9600 бит/с, 573 мкс при 19 200 бит/с
Символ Modbus RTU на выводе TXD: байт 0x6B в формате 8E1 и в формате 8N2. В обоих случаях символ занимает 11 бит.

Правила руководства:

  • Чётность 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

Кадр Modbus RTU: адрес, код функции, данные и CRC-16Кадр Modbus RTU начинается и заканчивается тишиной не короче 3,5 символа. Между паузами идут адрес ведомого (1 байт), код функции (1 байт), данные (от 0 до 252 байт) и CRC-16 (2 байта, младший байт первым). Код функции и данные образуют PDU не больше 253 байт, весь кадр — не больше 256 байт; CRC считается по адресу, коду функции и данным. Пример запроса: 11 03 00 6B 00 03 76 87 — ведомый 17, функция 03, адрес первого регистра 0x006B, количество 3, CRC 0x8776.по этим байтам считается CRCтишина≥ 3,5 символаАдрес1 байтФункция1 байтДанные0–252 байтаCRC мл.1 байтCRC ст.1 байттишина≥ 3,5 символаPDU: код функции и данные — не больше 253 байткадр RTU целиком — не больше 256 байтПример: чтение регистров хранения 108–110 у ведомого с адресом 17запрос, hex1103006B00037687адрес 17функция 03адрес регистра0x006B = 107количество0x0003 = 3CRC = 0x8776,младший байт первым8 байт = 88 бит на линии:9,17 мс при 9600 бит/с
Кадр Modbus RTU и пример запроса: чтение трёх регистров хранения, начиная с адреса 0x006B, у ведомого 17. Ширина полей условная.
ПолеРазмерСодержимое
Адрес1 байтадрес ведомого: 1–247; 0 — широковещательный запрос; 248–255 зарезервированы
Код функции1 байтдействие, которое нужно выполнить; в ответе с ошибкой к коду прибавлено 0x80
Данные0–252 байтапараметры запроса или результат: адреса, количества, значения
CRC2 байта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 нет ни стартового символа, ни поля длины. Начало и конец кадра задаёт время:

  • t3,5t_{3,5} — тишина между кадрами. Кадры разделяет пауза не короче 3,5 символа. Приёмник считает кадр законченным, когда после очередного символа линия молчит дольше t3,5t_{3,5}.
  • t1,5t_{1,5} — наибольшая пауза внутри кадра. Кадр передаётся сплошным потоком. Если между двумя символами тишина длится больше 1,5 символа, кадр считается неполным, и приёмник должен его отбросить.
Паузы t1,5 и t3,5 в Modbus RTU: границы кадра и пауза внутри кадраВверху — запрос из 8 символов и ответ из 11 символов: перед ответом и перед следующим запросом линия молчит не меньше 3,5 символа. Внизу — два варианта паузы между символами одного кадра: пауза короче 1,5 символа допустима, и кадр принимается; пауза длиннее 1,5 символа делает кадр недействительным, приёмник отбрасывает его целиком. Один прямоугольник — один символ из 11 бит. До 19 200 бит/с включительно t1,5 равно 16,5, а t3,5 — 38,5 длительности бита; на более высоких скоростях рекомендованы постоянные 750 мкс и 1,75 мс.Между кадрами: тишина не короче 3,5 символавремя1103006B00037687110306022B00000064C8BA11…≥ t3,5≥ t3,5запрос ведущего: 8 символов подрядответ ведомого: 11 символов подрядследующий запросВнутри кадра: пауза между символами не длиннее 1,5 символа1103006B00037687< t1,51103006B00037687> t1,5кадр приняткадр отброшен целикомодин символ:11 битt1,5t3,5До 19 200 бит/с включительно: t1,5 = 16,5 бита, t3,5 = 38,5 бита — при 9600 бит/с это 1,72 и 4,01 мс.Выше 19 200 бит/с — постоянные значения: t1,5 = 750 мкс, t3,5 = 1,75 мс.
Вверху — запрос и ответ, разделённые тишиной не короче t3,5. Внизу — пауза внутри кадра: короче t1,5 — кадр принят, длиннее — отброшен целиком. Один прямоугольник — один символ из 11 бит, масштаб времени в обоих рядах одинаков.

Символ — это 11 бит, поэтому при скорости vv бит/с:

tсимв=11v,t1,5=1,5⋅tсимв=16,5v,t3,5=3,5⋅tсимв=38,5v.t_\text{симв} = \frac{11}{v}, \qquad t_{1,5} = 1{,}5 \cdot t_\text{симв} = \frac{16{,}5}{v}, \qquad t_{3,5} = 3{,}5 \cdot t_\text{симв} = \frac{38{,}5}{v}.

На высоких скоростях интервалы становятся короткими, а таймеры срабатывают часто и нагружают процессор. Поэтому руководство требует строго выдерживать оба интервала только до 19 200 бит/с включительно, а на более высоких скоростях рекомендует постоянные значения: 750 мкс для t1,5t_{1,5} и 1,75 мс для t3,5t_{3,5}.

Скорость, бит/сБитСимвол, 11 битt1,5t_{1,5}t3,5t_{3,5}
1200833 мкс9,17 мс13,75 мс32,08 мс
2400417 мкс4,58 мс6,88 мс16,04 мс
4800208 мкс2,29 мс3,44 мс8,02 мс
9600104 мкс1,146 мс1,72 мс4,01 мс
19 20052,1 мкс573 мкс859 мкс2,005 мс
38 40026,0 мкс286 мкс750 мкс1,75 мс
57 60017,4 мкс191 мкс750 мкс1,75 мс
115 2008,68 мкс95,5 мкс750 мкс1,75 мс

На 115 200 бит/с постоянные 1,75 мс — это больше 18 символов, а 750 мкс — почти 8: пауза между кадрами получается намного длиннее расчётных 3,5 символа, зато требование к паузам внутри кадра мягче.

Приём по диаграмме состояний руководства идёт так:

  1. Первый символ после тишины — начало кадра. С каждым принятым символом приёмник перезапускает оба таймера.
  2. Если истёк таймер t1,5t_{1,5}, новых символов в этом кадре быть уже не должно: приёмник проверяет CRC, чётность символов и адрес.
  3. Символ, который пришёл после t1,5t_{1,5}, но до истечения t3,5t_{3,5}, помечает кадр как ошибочный.
  4. Когда истекает t3,5t_{3,5}, исправный кадр передаётся на обработку, ошибочный удаляется целиком. Только после этого устройство возвращается в состояние ожидания, из которого можно начинать и приём, и передачу.

Из последнего пункта следует, что ведомый начинает ответ не раньше чем через t3,5t_{3,5} после последнего символа запроса, а ведущий — следующий запрос не раньше чем через t3,5t_{3,5} после ответа. Адрес руководство разрешает сравнивать сразу, не дожидаясь конца кадра: тогда CRC считают только для кадров со своим или широковещательным адресом.

Как это делают на практике:

  • Таймер в микроконтроллере. Таймер перезапускают в прерывании приёма каждого байта; если он досчитал до t3,5t_{3,5}, кадр закончен. Учтите, что прерывание приходит в конце символа: между прерываниями двух символов, идущих вплотную, проходит ровно один символ. Поэтому паузе в 1,5 символа соответствует интервал 2,5 символа между прерываниями.
  • Аппаратный таймаут приёмника. У USART некоторых микроконтроллеров есть счётчик тишины на линии. В STM32F0, например, библиотека HAL задаёт его функцией HAL_UART_ReceiverTimeout_Config() в длительностях бита и включает функцией HAL_UART_EnableReceiverTimeout(); t3,5t_{3,5} — это 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
счётчик байтов N1 байтколичество / 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 сразу после последнего байта — паузу t3,5t_{3,5} перед следующим запросом это не отменяет. Ответ с ошибкой всегда занимает 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 байт0x0F0x10
адрес первого элемента2 байта0x0000–0xFFFF0x0000–0xFFFF
количество2 байта1–1968 (0x07B0) катушек1–123 (0x007B) регистров
счётчик байтов1 байтколичество / 8 с округлением вверх2 × количество
значенияпо счётчикубит на катушку, первая — в младшем бите2 байта на регистр, старший первым
Ответкод функции1 байт0x0F0x10
адрес первого элемента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
КодНазваниеКогда возвращается
01ILLEGAL FUNCTIONфункция не поддерживается устройством или недопустима в его текущем состоянии
02ILLEGAL DATA ADDRESSадрес или сочетание адреса и количества выходит за пределы таблицы
03ILLEGAL DATA VALUEнедопустимое значение в полях запроса: количество вне пределов, не сходится счётчик байтов
04SERVER DEVICE FAILUREнеустранимая ошибка при выполнении запроса
05ACKNOWLEDGEзапрос принят, но выполняется долго; используется с командами программирования
06SERVER DEVICE BUSYустройство занято длительной командой; запрос нужно повторить позже
08MEMORY PARITY ERRORошибка чётности памяти при работе с файловыми записями (функции 20 и 21)
0AGATEWAY PATH UNAVAILABLEшлюз не смог проложить путь к адресату: неверно настроен или перегружен
0BGATEWAY 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 руководства:

  1. Загрузить в 16-битный регистр значение 0xFFFF.
  2. Сложить по модулю 2 (XOR) очередной байт кадра с младшим байтом регистра.
  3. Сдвинуть регистр на один бит вправо, в старший бит вдвинуть ноль.
  4. Если выдвинутый бит был единицей, сложить регистр по модулю 2 с константой 0xA001.
  5. Повторить шаги 3 и 4, пока не будет сделано восемь сдвигов.
  6. Повторить шаги 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.

  1. Функция. Запись 4xxxx означает регистры хранения — функция 03.
  2. Адрес. 40108 − 40001 = 107 = 0x006B.
  3. Количество. Три регистра — 0x0003.
  4. Кадр без CRC: 11 03 00 6B 00 03.
  5. CRC. Регистр начинается с 0xFFFF и после каждого байта принимает значения из таблицы ниже. Итог — 0x8776, в кадр идут байты 76 87.
  6. Запрос целиком: 11 03 00 6B 00 03 76 87 — 8 символов по 11 бит, 9,17 мс на линии.
Байт кадра1103006B0003
Регистр CRC после байта0x4C7F0xE14D0x35210xF7B40x77F70x8776

Ответ прибора: 11 03 06 02 2B 00 00 00 64 C8 BA. Проверяем по порядку:

  1. CRC по всем 11 байтам равна нулю — кадр не искажён.
  2. Адрес 0x11 — ответил тот, кого спрашивали.
  3. Код функции 0x03, а не 0x83, — это обычный ответ, а не ошибка.
  4. Счётчик байтов 0x06 = 2 × 3, длина кадра 5 + 6 = 11 байт — сходится с запросом.
  5. Данные: 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 мс, пауза перед ответом — не меньше t3,5t_{3,5} = 4,01 мс, ответ из 11 символов — 12,6 мс, пауза перед следующим запросом — ещё 4,01 мс. Итого не меньше 29,8 мс, то есть не больше 33 опросов в секунду, — и это без времени, которое прибор тратит на обработку запроса. Чтение 125 регистров одним запросом (ответ — 255 байт) займёт на той же скорости около 0,31 с.

Обмен ведущего и ведомых: таймаут, широковещательный запрос, повторы

Обмен в Modbus RTU: адресный запрос, широковещательный запрос и таймаутТри сценария на одной шине. Адресный запрос: ведущий передаёт кадр с адресом ведомого 1, тот обрабатывает запрос и отвечает; остальные ведомые молчат. Широковещательный запрос с адресом 0: его выполняют все ведомые, ответа нет, а ведущий выдерживает паузу, обычно 100–200 мс, прежде чем передавать снова. Запрос без ответа: ведомого нет на шине или кадр искажён; ведущий ждёт, пока не истечёт таймаут ответа, и повторяет запрос. Масштаб времени условный.Адресный запросШироковещательный запросНет ответа: таймаут и повторВедущийВедомый 1Ведомый Nзапрос → 1обработкаответждёт ответачужой адрес — молчитзапрос → 0выполняют все, ответа нетпауза 100–200 мсзапрос → Nнет ответатаймаут ответаповторкадр ведущегокадр ведомоговедомый обрабатывает запрос
Три сценария обмена: адресный запрос с ответом, широковещательный запрос с паузой после него и запрос без ответа, после которого ведущий ждёт таймаут и повторяет попытку. Масштаб времени условный.

Адресный запрос (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 — младший.

Порядок байтов 32-битного числа в двух регистрах Modbus: ABCD, CDAB, BADC, DCBAЧисло 123456,0 в формате IEEE 754 одинарной точности — 0x47F12000, байты A = 47, B = F1, C = 20, D = 00. Порядок ABCD: в первом регистре 47F1, во втором 2000. CDAB: 2000 и 47F1. BADC: F147 и 0020. DCBA: 0020 и F147. Если ведущий расшифрует байты в порядке ABCD, а устройство передаёт их иначе, получится 1,09 · 10⁻¹⁹, −9,85 · 10²⁹ или 3,03 · 10⁻³⁹ вместо 123456.123456,0 = 0x47F12000float, IEEE 754 одинарной точности47AF1B20C00DA — старший байт числа,D — младшийПорядок в устройстверегистр Nрегистр N + 1байты в порядке передачи →Если прочитатькак ABCDABCDстарший байт первым47AF1B20C00D123456,0CDABпереставлены слова20C00D47AF1B1,09 · 10⁻¹⁹BADCпереставлены байтыF1B47A00D20C−9,85 · 10²⁹DCBAмладший байт первым00D20CF1B47A3,03 · 10⁻³⁹
Число 123456,0 (0x47F12000) в двух регистрах при четырёх порядках байтов. Справа — что получит ведущий, если расшифрует принятые байты как ABCD.
ПорядокРегистр NРегистр N + 1Байты в ответеКак его называют
ABCD0x47F10x200047 F1 20 00big-endian; в библиотеке libmodbus — «обычный формат Modbus»
CDAB0x20000x47F120 00 47 F1перестановка слов (word swap), младшее слово первым; соглашение Modicon Modsoft
BADC0xF1470x0020F1 47 00 20перестановка байтов (byte swap)
DCBA0x00200xF14700 20 F1 47little-endian

Если порядок в документации прибора не указан, его определяют так:

  1. Прочитайте оба регистра одним запросом: между двумя отдельными запросами значение может измениться, и половины окажутся от разных чисел.
  2. Возьмите параметр, значение которого известно хотя бы приблизительно: напряжение сети, температуру в комнате, уставку, которую видно на экране прибора.
  3. Расшифруйте четыре байта всеми четырьмя способами. Правильный порядок даст правдоподобное число, остальные — абсурдные. Например, байты 43 66 80 00 — это 230,5 в порядке ABCD и −2,4 · 10⁻⁴¹, 2,3 · 10²³ или 1,2 · 10⁻³⁸ в трёх остальных.
  4. У целых счётчиков смотрите, какой регистр меняется чаще: быстро меняющаяся половина — младшая.

Все четыре варианта сразу показывает калькулятор кадров 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

Про управление передатчиком стоит сказать отдельно. Ведомый вправе начать ответ уже через t3,5t_{3,5} после запроса — это 4 мс при 9600 бит/с и 1,75 мс на высоких скоростях. К этому моменту ведущий должен отпустить шину, но не раньше, чем уйдёт стоп-бит последнего байта CRC. По какому флагу UART снимать сигнал DE, разобрано в статье про RS-485, в разделе «Когда включать и выключать передатчик».

Как отлаживать Modbus RTU

  1. Сначала линия. При выключенном питании омметр между D1 и D0 должен показать около 75 Ом, если стоят два терминатора по 150 Ом, или около 60 Ом, если два по 120 Ом. Терминаторы 120 Ом + 1 нФ омметр «не видит» — конденсатор не пропускает постоянный ток. Под напряжением в паузе D1 должна быть положительнее D0 не меньше чем на 0,2 В, если поляризация включена. Остальные проверки — в разделе «Как проверить и отладить линию RS-485».
  2. Параметры порта. Скорость, 8 бит данных, чётность и число стоп-битов должны совпадать у ведущего и всех ведомых. По руководству значения по умолчанию — 19 200 бит/с и 8E1, но заводские настройки конкретного прибора нужно смотреть в его документации.
  3. Один ведомый, простой запрос. Оставьте на шине одно устройство и отправьте самое простое: чтение одного регистра функцией 03 или эхо-запрос функцией 08. Запрос соберите в калькуляторе кадров, чтобы исключить ошибку в CRC.
  4. Смотрите байты. Логический анализатор с декодером UART на выводах RO и DI трансивера покажет запрос и ответ побайтно; декодеру нужно задать тот же формат символа, иначе он покажет ошибки чётности. Второй способ — слушать шину отдельным переходником USB–RS-485.
  5. Тишина или ошибка? Ответа нет — ищите проблему на уровне связи: адрес, скорость, чётность, CRC, паузы внутри кадра. Пришёл ответ с ошибкой — связь работает, а неверны функция, адрес или количество.
  6. Паузы и направление. Проверьте, что запрос идёт без разрывов, сигнал DE включается до старт-бита первого байта и выключается после стоп-бита последнего, а ответ начинается не раньше чем через t3,5t_{3,5}.
  7. Таймаут. Измерьте, через сколько прибор отвечает на самый «тяжёлый» запрос, и задайте таймаут с запасом.
  8. Счётчики прибора. Если прибор поддерживает функцию 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, связь исправна, а ошибка — в функции, адресе или количестве.

Источники

  1. 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
  2. Modbus Organization. MODBUS Application Protocol Specification V1.1b3, 26.04.2012 — разд. 4 — PDU не больше 253 байт, порядок байтов, модель данных и адресация с нуля; разд. 5 и 6 — коды функций, пределы и побайтные примеры запросов и ответов; разд. 7 — ответы с ошибкой и коды исключений
  3. Modbus Organization. MODBUS Messaging on TCP/IP Implementation Guide V1.0b, 24.10.2006 — разд. 3.1 — заголовок MBAP из 7 байт, поле Unit Identifier вместо адреса ведомого, порт 502
  4. 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
  5. Modbus Organization. Introduction to Modbus — история: Modicon, 1979 год; диапазоны номеров 00001–09999, 10001–19999, 30001–39999 и 40001–49999; относительные адреса в кадре
  6. Kepware Technologies. Modbus RTU Serial Driver Help, 2012 — шестизначные номера 400001–465536; вычитание единицы из номера при формировании кадра; порядок слов first word low как соглашение Modicon Modsoft; устройства, принимающие запись только функцией 16; строки с порядком байтов HiLo и LoHi
  7. libmodbus. Справочник функций: modbus_get_float_abcd(), _badc(), _cdab(), _dcba() — четыре порядка байтов 32-битного числа в двух регистрах и пример: 123456,0 — регистры 0x47F1 и 0x2000
  8. Greg Cook. Catalogue of parametrised CRC algorithms (CRC RevEng): CRC-16/MODBUS — параметры алгоритма: полином 0x8005, начальное значение 0xFFFF, отражение входа и выхода, контрольное значение 0x4B37, остаток 0x0000
  9. Espressif Systems. ESP-Modbus Programming Guide: Modbus messaging and mapping — те же обозначения порядков ABCD, CDAB, BADC и DCBA для 32-битных типов
  10. MaxLinear. SP3485: 3.3V Low Power Half-Duplex RS-485 Transceiver with 10Mbps Data Rate, ред. 2.0.2, 2021 — вывод A — неинвертирующий, B — инвертирующий; таблица истинности передатчика; чувствительность приёмника ±200 мВ
  11. STMicroelectronics. STM32F0 HAL: stm32f0xx_hal_uart.c — функции HAL_UART_ReceiverTimeout_Config() и HAL_UART_EnableReceiverTimeout(): аппаратный таймаут приёмника, значение — в длительностях бита