Modbus — это сетевой протокол прикладного уровня, широко используемый в промышленном производстве для обмена данными между устройствами (Machine-to-Machine, M2M).

С момента разработки в 1979 году он не теряет своей популярности. Согласно статистике HMS Industrial Networks в 2021 году Modbus занимает 10% мирового рынка промышленных сетей (по 5% приходится на Modbus RTU и Modbus TCP).

В статье расскажем об основных особенностях протокола Modbus, его преимуществах и недостатках, а также наиболее частых сценариях использования.

Базовые принципы работы Modbus

Modbus использует архитектуру Master-Slave, которая относительно недавно была переименована разработчиком в Client-Server. Согласно этому подходу в сети выделяется клиентское (ведущее) устройство, которое периодически отправляет запросы на серверные (ведомые) устройства с целью чтения или записи их параметров.

Все запросы может инициировать только клиентское устройство: передача сообщений от серверных устройств без предварительного опроса со стороны клиента в протоколе не предусмотрена.

Архитектура Client-Server (ранее Master-Slave), лежащая в основе протокола Modbus

Пакет данных Modbus включает в себя постоянную часть PDU (Protocol Data Unit), общую для всех реализаций протокола и состоящую из кода функции и данных. Кроме этого, возможен ряд специфических полей, которые будут различаться в зависимости от физического уровня сети — чаще всего это адрес серверного устройства и контрольная сумма для выявления ошибок. С учетом дополнительных полей полный пакет Modbus носит название ADU (Application Data Unit). Рассмотрим более подробно каждое поле пакета ADU в обобщенном виде. Особенности, присущие различным вариантам протокола, будут описаны в следующем разделе.

  • Адрес серверного устройства (Additional address). Определяет, по какому адресу следует отправить клиентский запрос. Может принимать значения в диапазоне от 1 до 247. Адрес 0 используется для широковещательной передачи данных от клиента всем серверным устройствам (ответ сервера при этом не предусмотрен), а адреса 248–255 считаются зарезервированными.

    В некоторых реализациях протокола поле игнорируется — например, в Modbus TCP, где чаще всего применяется стандартная IP-адресация.
  • Код функции (Function code). Определяет, какое действие необходимо выполнить серверному устройству. Значения кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках. Код 0 не используется.

    Для кодов из диапазонов 65-72 и 100-110 пользователи могут реализовать собственные функции (User-Defined Function Codes). Некоторые коды, например 9, 10, 13 и другие, зарезервированы определенными поставщиками для своего оборудования и закрыты для общего использования (Reserved Function Codes). Не входящие в эти два подмножества коды относятся к публичным (Public Function Codes) — это задокументированные функции, находящиеся в открытом доступе.
  • Данные (Data). Данные, необходимые для выполнения выбранной функции на серверном устройстве. Чаще всего это адреса регистров для чтения или записи, их количество и так далее. Длина и формат поля зависят от кода функции. Некоторые функции не требуют передачи данных.
  • Контрольная сумма (Error check). Содержит рассчитанное при помощи специального алгоритма число для проверки целостности пакета. В качестве алгоритма для расчетов используется CRC-16 или LRC-8. В некоторых реализациях протокола поле отсутствует — например, в Modbus TCP, где контроль целостности пакета обеспечивается средствами протокола TCP/IP.
Структура пакета данных Modbus в обобщенном виде

Рассмотрим передачу пакетов в Modbus. Протокол обеспечивает клиент-серверное взаимодействие в режиме Request/Response. Клиент инициирует запрос в серверное устройство, передавая в PDU код функции и данные. В зависимости от физического уровня сети в пакете могут быть дополнительные поля, рассмотренные выше.

Если обработка запроса проходит без ошибок, то сервер возвращает пакет, содержащий исходный код функции и запрошенные данные.

Схема работы Modbus в случае отсутствия ошибок на серверном устройстве

При возникновении ошибки серверное устройство возвращает в качестве данных код исключения, а вместо исходного кода функции — его значение, увеличенное на 128 (0x80 в шестнадцатеричной системе HEX).

Также предусмотрены тайм-ауты на стороне клиента во избежание длительного ожидания ответа от вышедших из строя устройств.

Схема работы Modbus в случае ошибок на серверном устройстве

Разновидности Modbus: ASCII, TCP и RTU

Modbus — это протокол прикладного (седьмого) уровня модели OSI (Open Systems Interconnection model). Он не зависит от нижележащих уровней и может использоваться совместно с другими протоколами, например Ethernet TCP/IP или UDP/IP, а в качестве физической среды для передачи сигналов применять последовательные интерфейсы RS-232, RS-422, RS-485, оптоволокно, радиоканалы и другое.

Разновидности протокола Modbus

Опишем отличия наиболее известных реализаций протокола Modbus: RTU, ASCII и TCP.

Modbus RTU (Remote Terminal Unit). Это разновидность протокола, которая в качестве физического уровня сети чаще всего использует последовательный интерфейс RS-485, реже — RS-232 и RS-422. По сути, все эти интерфейсы определяют связь с помощью витых пар, но различаются характеристиками вида максимальной длины кабеля, количества узлов и так далее.

Формат пакета Modbus RTU в целом совпадает с обобщенной формой, описанной ранее: дополнительные поля не используются. Контроль целостности пакетов ведется с помощью алгоритма CRC-16.

Важная особенность Modbus RTU в том, что для разделения пакетов должны использоваться временные паузы продолжительностью не менее чем произведение 3,5*t, где t — время передачи одного байта в текущей сети. А передача байтов данных в пределах одного пакета производится последовательно с промежутком времени между соседними байтами не более 1,5*t, иначе передача будет считаться ложной. Эти правила не дают использовать Modbus RTU в медленных, например модемных, сетях.

Структура пакета данных в Modbus RTU

Modbus ASCII. Это разновидность протокола, также работающая поверх интерфейсов RS-232/RS-485, но для кодирования сообщений использующая ASCII-символы.

По сравнению с Modbus RTU в формате пакета добавляются еще два поля — специальные символы для отметки начала и конца сообщения: двоеточие и символы возврата каретки / перевода строки. Временные паузы между пакетами не нужны. Для проверки целостности применяется алгоритм LRC-8.

В целом этот вариант протокола сейчас используется крайне редко — из-за сложностей кодирования и большого размера сообщений. Однако он может стать хорошей альтернативой Modbus RTU на линиях с сетевыми задержками и оборудовании с менее точными таймерами.

Структура пакета данных в Modbus ASCII

Modbus TCP. Это реализация ModBus в сетях Ethernet. Работает поверх TCP/IP стека.

В отличие от Modbus RTU и ASCII, в Modbus TCP соединение устанавливается с конкретным устройством средствами TCP/IP. Поэтому адрес в пакете Modbus чаще всего игнорируется, а широковещательная рассылка сообщений не используется. Однако адрес может потребоваться, если соединение устанавливается со шлюзом, который, в свою очередь, выводит на сеть RS485 — чтобы далее общаться с устройствами уже на языке Modbus.

Контроль целостности пакетов также обеспечивается средствами протокола TCP/IP, поэтому нет необходимости в его Modbus-реализации.

Наряду с адресом в заголовке пакета Modbus TCP присутствует ряд дополнительных полей:

  1. ID транзакции (или ID обмена)

    Чаще всего заполняется нулями. Необходим для случаев, когда клиентское устройство отправляет несколько сообщений, не дожидаясь ответа на предыдущие, чтобы затем связать ответы с запросами.

  2. ID протокола

    Всегда заполняется нулями, зарезервирован для будущего использования.

  3. Длина остатка пакета

    Длина оставшейся части пакета: адреса и PDU (кода функции и данных).

Структура пакета данных в Modbus TCP

Мы рассмотрели только открытые и самые распространенные реализации протокола Modbus. Но их гораздо больше, например MODBUS Plus — проприетарный протокол от Schneider Electric, поддерживающий режим Multi-Master.

Регистры и функции Modbus

Так как Modbus предназначен для работы с промышленной автоматикой, обмен данными с Modbus-устройствами происходит через регистры. Они делятся на входы и выходы. Входы можно только читать, а выходы — читать и писать. Бывают 1-битные регистры Modbus для описания дискретных входов/выходов (Discrete Inputs и Coils) и 16-битные регистры для аналоговых входов/выходов (Input Registers и Holding Registers).

Доступ к регистрам осуществляется с помощью 16-битного адреса. Первому элементу в каждой группе регистров соответствует адрес 0. То есть адрес любого регистра может принимать значения из диапазона 0-65535 (0x0000-0xFFFF в HEX-формате). При этом спецификация протокола не определяет, что физически из себя представляют адресные пространства и по каким внутренним адресам устройства должны быть доступны регистры. В общем случае значения регистров с одинаковым адресом, но разными типами отличаются друг от друга.

Примечание

В документации ряда производителей на некоторые, особенно старые устройства адреса регистров могут быть указаны в других форматах — где адресация начинается не с нуля и первая цифра адреса определяет тип регистра. Например, Input Register с адресом 0 может быть описан как 30001, а Holding Register — как 40001. В таких случаях в пакетах данных следует передавать адреса в стандартном формате Modbus независимо от способа представления их в документации. Для получения верного адреса достаточно вычесть смещение, соответствующее типу регистра. В некоторые программные пакеты заложена автоматическая корректировка адресов.

Тип регистров Назначение Размер Доступ Стандартный адрес Примеры нестандартных адресов
Coils Регистры флагов, обозначающие текущее состояние выхода устройства. Например, при включенном реле значение 1. 1 бит Чтение и запись (выход) 0-65535 (0x0000-0xFFFF в HEX-формате) 00001-09999 или 000001-065536
Discrete Inputs Дискретные входы, описывающие состояние входа устройства. Например, при поданном напряжении значение 1. 1 бит Чтение (вход) 0-65535 (0x0000-0xFFFF в HEX-формате) 10001-19999 или 100001-165536
Input Registers Регистры ввода, предназначенные для чтения настроек (например, текущего значения температуры). 16 битов Чтение (вход) 0-65535 (0x0000-0xFFFF в HEX-формате) 30001-39999 или 300001-365536
Holding Registers Регистры, предназначенные для хранения настроек с возможностью их чтения и записи. 16 битов Чтение и запись (выход) 0-65535 (0x0000-0xFFFF в HEX-формате) 40001-49999 или 400001-465536

Для работы с каждым типом регистров определены функции чтения и записи. Наиболее часто используемые функции описаны ниже.

Код HEX-код для PDU Название функции Тип данных Назначение
1 0x01 Read Coils Coils Чтение значений нескольких регистров флагов
2 0x02 Read Discrete Inputs Discrete Inputs Чтение значений нескольких дискретных входов
3 0x03 Read Holding Registers Holding Registers Чтение значений нескольких регистров хранения
4 0x04 Read Input Registers Input Registers Чтение значений нескольких регистров ввода
5 0x05 Write Single Coil Coils Запись одного регистра флагов
6 0x06 Write Single Register Holding Registers Запись одного регистра хранения
15 0x0F Write Multiple Coils Coils Запись нескольких регистров флагов
16 0x10 Write Multiple Register Holding Registers Запись нескольких регистров хранения

Для каждой функции в спецификации протокола Modbus определена структура PDU: какие данные и в каком порядке должны использоваться в запросах и ответах. Рассмотрим формирование пакетов Modbus RTU на примере функции Read Coils с кодом 1. Эта функция, кроме передачи собственного кода, требует наличия в запросе адреса первого Coil-регистра и количества регистров, которые необходимо прочитать. В случае успешного выполнения запроса в ответе будут возвращены код функции, число байт, необходимое для вывода запрошенных Coil-регистров, и статус всех этих регистров.

Предположим, нам нужно обратиться к серверному устройству с адресом 1 и прочитать 19 его Coil-регистров с номерами 20–38. Адресация регистров ведется с 0, поэтому адрес первого нужного нам регистра будет 0x13 (это 19 в HEX-системе). Требуемое для чтения количество регистров также будет равно 0x13 (для чтения запрошено 19). В качестве адреса и кода функции указываем 01. Контрольная сумма формируется по алгоритму CRC-16 на основе других полей пакета.

В случае отсутствия ошибок в ответе вернутся без изменений адрес серверного устройства и код функции. Для расчета числа байтов, которые потребуются для возврата состояния регистров, нужно разделить запрошенное количество регистров на 8 и к результату прибавить 1, если остаток от деления не равен 0. В нашем случае результат деления 19 на 8 равен 2, но остаток положительный — поэтому для вывода регистров потребуется 2+1=3 байта. Это значение будет указано в ответе после кода функции. И далее будут следовать 3 байта, описывающие состояние выбранных регистров. Например, первый байт будет описывать состояние 8 Coil-регистров с номерами 27-20. Если в поле, к примеру, содержится HEX-значение CD — статус соответствующих 8 регистров такой: 1100 1101.

Пример успешного выполнения функции Read Coils

Если в процессе обработки запроса на серверном устройстве возникнет ошибка (например, обнаружен несуществующий адрес регистра), то в ответе будет содержаться измененный код функции, равный исходному коду плюс смещение 0x80 — в нашем примере 0x81, и код исключения — в нашем примере 03, что значит неверный формат запроса. С полным перечнем возможных исключений можно ознакомиться в документации.

Пример возврата исключения для функции Read Coils

Преимущества и недостатки Modbus

К преимуществам Modbus относятся:

  1. Простота реализации, диагностики и отладки

    Использование стандартных интерфейсов (RS-232/RS-485 и Ethernet) делает Modbus удобным как для разработчиков, так и для пользователей оборудования. При разработке контроллеров и устройств не нужно устанавливать заказные микросхемы для реализации протокола, в отличие от конкурентов-аналогов Profibus и CAN.

  2. Высокая скорость внедрения

    Для развертывания первого Modbus-решения нужно всего пара дней, тогда как некоторые протоколы требуют месяцев на подготовку.

  3. Нетребовательность к ресурсам

    Разработанный в эпоху 8-битных процессоров, Modbus не предъявляет высоких требований к CPU и RAM. Для начала работы требуется минимум оборудования, и разработка проста в любой операционной системе.

  4. Высокая надежность и достоверность при передаче данных

    Поддержка CRC и LRC позволяет определять ошибки в передаче данных с высокой точностью.

  5. Универсальность и открытость

    Практически все промышленные АСУ ТП имеют программные драйверы для работы с Modbus-сетями. Благодаря этому Modbus принято считать стандартом де-факто в интеграции мультивендорного оборудования. Протокол реализован сотнями поставщиков на множестве различных датчиков и исполнительных устройств для передачи дискретной и аналоговой информации. Благодаря единому протоколу устройства от различных производителей могут без труда общаться друг с другом.

Разумеется, у использования протокола есть и недостатки:

  1. Отсутствие встроенной аутентификации и шифрования передаваемых данных

    Поэтому при использовании протокола Modbus TCP необходимо настраивать дополнительные VPN-тоннели. Относительно недавно для Modbus TCP было разработано расширение Modbus Security (с поддержкой TLS), но оно пока не получило широкого распространения.

  2. Отсутствие начальной инициализации системы

    Назначать сетевые адреса и настраивать параметры каждого конкретного устройства требуется вручную. Некоторые производители разрабатывают шаблоны для своих Modbus-устройств, но это не упрощает их взаимодействие с контроллерами и ПО других производителей.

  3. Спецификации для ограниченного набора типов данных

    В протоколе определен метод передачи только для битов и 16-битных регистров. С другими типами данных (строки, числа с плавающей запятой и так далее) различные производители Modbus-решений поступали по собственному усмотрению. По этой причине впоследствии невозможно было внести дополнения в протокол, так как это могло привести к проблемам из-за уже существующего несовпадения форматов.

  4. Недостатки Master-Slave-взаимодействия

    Модель «ведущий — ведомый», изначально положенная в основу протокола, предполагает обмен данными только по инициативе клиентского (ведущего) устройства, которое по очереди опрашивает все серверные (ведомые). Из-за этого возникают следующие ограничения:

    • У серверных устройств нет возможности отправить оперативную информацию клиенту (например, сигнал прерывания): нужно ждать своей очереди в опросе.
    • Серверные устройства не способны обнаружить потерю связи с клиентом.
    • Серверные устройства не могут обмениваться данными друг с другом без участия клиента.
  5. Отсутствие поддержки режима Multi-Master для интерфейсов RS-232/RS-485

    Другие протоколы, основанные на этих же интерфейсах, поддерживают работу с несколькими ведущими устройствами (например, CAN и Profibus).

Однако стоит отметить, что именно описанные выше недостатки обеспечивают простоту использования протокола и высокую скорость его промышленного внедрения. В какой-то степени отсутствие «лишнего» функционала в Modbus и есть его главное достоинство.

Где используется Modbus

Чаще всего Modbus применяется для передачи сигналов от контрольно-измерительных приборов к главному контроллеру или системе сбора данных. Основные сценарии использования Modbus:

  • Клиент-серверные приложения для мониторинга и программирования устройств (в том числе дистанционного) в промышленности, строительстве, инфраструктуре, транспорте, энергетике. Примеры: мониторинг энергопотребления, контроль производственных процессов, надзор за ходом строительства и так далее.
  • Передача данных от датчиков и приборов интеллектуальным устройствам в интернете вещей (Internet of Things, IoT).
  • Связь диспетчерских компьютеров с удаленными терминалами в SCADA-системах.
  • Приложения, где требуется беспроводная связь, например в газовой и нефтяной промышленности.

Несмотря на свой возраст, Modbus активно используется и с современными технологиями — например, он отлично чувствует себя в облаке. Многие провайдеры предлагают возможность создания облачных IoT-платформ — для снижения затрат на разработку IoT-сервисов, обеспечения сбора данных и управления устройствами в real-time-режиме. И поддержка Modbus — обязательный пункт для подобных решений, так как невозможно построить межмашинное взаимодействие без протокола, реализованного множеством поставщиков на тысячах различных устройств.

Такая сочетаемость с современными трендами лишний раз показывает, что за прошедшие годы Modbus не только не утратил своей популярности, но и до сих пор остается одним из самых востребованных протоколов в промышленной производственной среде.