Команды modbus rtu. Просто о Modbus RTU с подробным описанием и примерами

03.08.2019 Разное

Ну что же, пора рассмотреть, чем протокол Modbus TCP отличается от протокола Modbus RTU . Так как отличий не очень много, то и статья будет не очень большая.
Итак, в предыдущей стать о функциях Modbus RTU можно узнать, какие есть функции и их бинарный формат. Теперь стоит рассказать что такое Modbus TCP , как он применяется и чем отличается от стандартного Modbus RTU .

Modbus RTU через TCP соединение

Самый простой способ обмена Modbus сообщениями через сеть – просто передавать Modbus RTU пакеты через TCP сокет (соединение). В этом случае формат пакетов такой же, как и для Modbus RTU протокола. В принципе на этом можно и закончить по этому типу протокола.

Modbus TCP

Для обмена Modbsu сообщениями по сети решили использовать модифицированный протокол. Взяли стандартный Modbus RTU и немного его изменили. Во-первых убрали из него последних 2 байта CRC16 . Так как каждый пакет TCP/IP содержит свою контрольную суму, решили что делать проверку еще раз не нужно. Кроме того убрали первый байт Slave ID . В принципе, Как будет видно дальше, Его не убрали, а просто переименовали. Вот эти байты, без Slave ID и CRC16 назвали PDU – Protocol Data Unit .

Например, возьмем запрос Modbus RTU , который читает несколько HOLDING регистров с устройства #17 (Slave ID = 17)

11 03 006B 0003 7687

Теперь убираем первый и последних 2 байта. Получаем PDU !

03 006B 0003

С этим вроде все ясно. Теперь, что бы получить полноценный пакет Modbus TCP нам нужно добавить впереди MBAP Header — Modbus Application Header . Т.е. нам нужно добавить некий заголовок. Этот заголовок включает в себя Transaction ID , Protocol ID , Length и Unit ID .

Transaction ID – 2 байта, которые устанавливаются клиентом, что бы однозначно идентифицировать каждый запрос. Т.е. это просто число от 0 до 65535 уникальное для каждого запроса.

Protocol ID – 2 байта, которые определяют версию протокола. В текущей реализации всегда должны быть равны 0x00 0x00

Length – 2 байта, которые определяют длину пакета (за исключением байтов Protocol ID , Transaction ID и Length )

Unit ID – уникальный адрес устройства, которое опрашивается данной командой. Идентично Slave ID .

Небольшое отступление по поводу адресации. Может показаться что это излишне, так как TCP соединение может быть установлено только на конкретный IP адрес и порт. Т.е. у нас уже есть конкретный адрес сервера, поэтому назначение Unit ID не совсем понятно.

Но на самом деле вполне обычна ситуация, когда есть некий сервер, который просто маршрутизирует Modbus RTU запросы на другие устройства, которые подсоединены к нему по различным каналам (локальная сеть, последовательный порт, CAN интерфейс). Поэтому клиент может использовать Modbus TCP сервер как шлюз (Gateway ) для общения с устройствами за ним.

Пример Modbus TCP сервера, который используется как шлюз для перенаправления запросов на Modbus RTU устройства

Вот пример из жизни. Есть некое устройство основанное на Linux. Это устройство выступает Modbus TCP сервером. Любой клиент может подсоединиться к публичному IP адресу на порт 502 и инициировать Modbus TCP соединение. К данному Linux устройству подключены сенсоры, которые использую последовательный порт RS485. Сенсоров много, они очень простые и не могут быть подключены к Internet, у них есть только порт RS485 и они понимают только Modbus RTU . Поэтому клиенты посылают Modbus TCP запросы с Unit ID сенсоров на Modbus TCP Сервер. Сервер декодирует Modbus TCP запрос и преобразует его в Modbus RTU и отправляет в порт RS485. После того как сенсор отвечает ему, он преобразует Modbus RTU ответ в Modbus TCP ответ и отсылает его назад, к Modbus TCP клиенту, который инициировал запрос. Таким образом, имея всего один публичный IP адрес можно опрашивать онлайн сотню сенсоров, которые даже не могут быть подсоединены к Интернету или локальной сети.

А теперь наглядная схема, чем отличается Modbus RTU запрос от Modbus TCP запроса.

Посмотрим пример байтов для двух запросов:

Modbus RTU: 11 03 006B 0003 7687 Modbus TCP: 0001 0000 0006 11 03 006B 0003

Пример ответа:

Modbus TCP: 0001 0000 0009 11 03 06 AE41 5652 4340 Modbus RTU: 11 03 06 AE41 5652 4340 49AD

Как видите, конвертировать запросы между Modbus RTU и Modbus TCP очень просто. Хотя реализация Modbus RTU через TCP может показаться самым простым способом для маршрутизации запросов, на самом деле в Modbus TCP есть несколько положительных моментов:

  • Не нужно вычислять CRC16
  • Есть возможность идентифицировать пару ответ / запрос используя Transaction ID
  • Можно легко добавлять свои версии протоколов, меняя константу Protocol ID

Статья посвящена промышленному протоколу ModBus — наиболее простому, а потому широко распространённому цифровому протоколу передачи данных.

Стандарт ModBus был изобретён ещё в 1979 году компанией Modicon (ныне Schneider Electric) и с того времени не утратил своей актуальности, а даже наоборот получил широкое распространение и большую популярность среди разработчиков АСУ ТП.

Преимущества и недостатки протокола ModBus

Преимущества:

  • прост в реализации
  • отсутствует необходимость установки специальных микросхем для реализации протокола при разработке контроллеров и устройств
  • простота диагностики и отладки
  • поддерживается большинством устройств, применяемых при построении АСУ ТП
  • высокая надёжность и достоверность при передаче данных

Недостатки:

  • ModBus сеть построена по принципу «ведущий-ведомый», где ведущее устройство может быть только одно. Поэтому обмен данными происходит только по инициативе ведущего устройства (оно по очереди опрашивает все ведомые). Если ведомому устройству нужно срочно передать данные, оно не может этого сделать, пока его не опросит «ведущий».

Общие сведения о ModBus сети

ModBus сеть объединяет одно ведущее (мастер) и несколько ведомых (слейвов). Обмен данными в сети происходит по инициативе мастера. Он может отправить запрос одному из подчинённых устройств или широковещательное сообщение сразу всем ведомым устройствам сети.

После отправки запроса мастер ожидает ответ в течение заданного времени («время таймаута»). Если в течение этого времени ответ не получен, мастер считает, что связь с ведомым отсутствует. На широковещательное сообщение ответ не предусмотрен.

Слейвы (ведомые устройства) не могут самостоятельно инициировать передачу данных. Они могут передать данные только после запроса мастера (и только те данные, которые мастер запросит).

Существует три разновидности протокола:

  • ModBus ASCII — разновидность протокола, в которой сообщения кодируются с помощью ASCII-символов. Сообщения разделяются символами «:» и CR/LF. Не очень удобен, в России используется крайне редко.
  • ModBus RTU — разновидность протокола, в которой сообщения кодируются «как есть» (числами). Между собой сообщения разделяются временной паузой в 3,5 символа при заданной скорости передачи.
  • ModBus TCP — разновидность протокола для работы поверх TCP/IP стека, требуется при соединении устройств по Ethernet.

Физический уровень протокола ModBus

Для передачи ModBus сообщений используется последовательные асинхронные интерфейсы (RS232, RS485, RS422) в случае использования протоколов ASCII и RTU и Ethernet интерфейс для протокола ModBus TCP.

Использование стандартных интерфейсов делает ModBus удобным для пользователей и разработчиков.

Типы данных ModBus

Любой узел сети ModBus — это интеллектуальное устройство (контроллер, регулятор, датчик и др.). Согласно спецификации узел сети может иметь следующие структуры данных:

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

Указанные типы данных необязательны для всех устройств, поддерживающих ModBus. Например, Discrete Inputs и Coils характерны больше для .

Производитель устройства сам решает, какой тип данных сделать доступным для чтения и записи по ModBus, и об этом написано в руководстве устройства. В большинстве случае пользуются типом Holding Registers, поскольку он самый универсальный.

Структура обмена данными по ModBus

Как уже было сказано, обмен данными по ModBus состоит из запросов и ответов. Ведущее устройство посылает запрос одному из подчинённых устройств, указывая в запросе его адрес, или всем устройствам сразу, указывая адрес 0.

Рис. Структура ModBus-пакета

Типовой запрос или ответ состоит из следующих блоков:

  • адрес подчинённого устройства
  • номер функции — определяет тип запрашиваемых данных и что с ними нужно сделать (прочитать/записать)
  • данные — содержит параметры функции («куда», «сколько» и «какие» данные записывать или читать)
  • блок контроля подлинности — содержит контрольную сумму для проверки целостности полученных данных.

Состав данных блоков отличается для RTU и TCP реализаций ModBus. Далее мы подробно рассотрим каждый из них.

ModBus ASCII мы не будем подробно рассматривать, поскольку он используется крайне редко. Состав пакета в ModBus ASCII такой же как и ModBus RTU, и отличается только типом кодирования и способом разделения пакетов.

Номер функции определяет тип запрашиваемых данных и что с ними нужно сделать (прочитать/записать).

Функций ModBus достаточно много и они разделены на три категории:

  • стандартные — функции, описанные в стандарте протокола. Среди них много устаревших и неиспользуемых.
  • пользовательские — диапазон номеров функций (с 65 по 72 и с 100 по 110), которые может использовать любой производитель устройств для реализации своих специфичных функций. При этом вполне возможно, что у устройств различных производителей под одинаковыми номерами будут разные по смыслу функции.
  • зарезервированные — функции, не описанные в базовом стандарте, но реализованные в устройствах различных производителей. При этом гарантируется, что данные производители зарезервировали эти номера для себя и другие производители не могут ими воспользоваться.

Однако, это всё лирика… На практике в большинстве случаев используются всего несколько функций, мы подробно поговорим о них в , а в этой будем рассматривать всё на примере функции Read Holding Registers (чтение регистров общего назначения).

Функция Read Holding Registers (0x03)

Функция под номером 3 — одна из самых употребимых функций, предназначена для чтения регистров общего назначения устройства.

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

Ответ содержит количество байт (количество регистров умноженное на 2) и значения запрошенных регистров.


Рис. Запрос от мастера

Рис. Ответ слейва

Количество байт в ответе помогает ведущему устройству по мере получения данных понять, когда все данные уже получены. То есть если мастер получил третий байт с числом 200 — это означает, что ему осталось получить еще 100 байт + 2 байта контроля целостности. Это позволит ему посчитать количество пришедших байт и закончить приём, не дожидаясь, когда закончится время таймаута, отведённое слейву на ответ.

Вместо нормального ответа, содержащего запрошенные данные, подчинённое устройство может ответить ошибкой. При этом к номеру функции в ответе добавляется код 0х80 в шестнадцатеричной системе исчисления.

Обратимся к предыдущему примеру. Там подчинённое устройство ответило без ошибки и второй байт в ответе был 0х03. Если бы ответ содержал код ошибки, то к номеру функции подчинённое устройство добавило бы 0х80 и получилось бы 0х83. Вот так:

Рис. Ответ слейва с признаком ошибки

В этом примере код ошибки 02 — это один из стандартных кодов. Вот какие они бывают:

01 — функция не поддерживается. Это значит, что, возможно, функция не стандартная или просто не реализована конкретно в этом устройстве.

02 — запрошенная область памяти не доступна. Каждое устройство содержит определённое количество данных определённого типа. Например, в устройстве доступно 100 регистров общего назначения. Если при этом запросить чтение 101 регистров — возникнет ошибка 02.

03 — функция не поддержит запрошенное количество данных. Например, функция №3 «Read Holding Registers» позволяет читать от 1 до 2000 регистров общего назначения. Поэтому, даже если в подчинённом устройстве доступно для чтения 10 000 регистров, при запросе более 2000 с помощью функции №3 — возникнет эта ошибка.

04 — функция выполнена с ошибкой. Такой код ошибки будет возвращён, если есть какое-то иное препятствие для нормального выполнения команды, не охваченное тремя предыдущими кодами ошибки. Проще говоря, это такая заглушка «на всякий случай», если что-то пошло не так, но в протоколе специального кода для такой ошибки не предусмотрено.

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

ModBus RTU

Как уже говорилось, в протоколе ModBus RTU данные передаются в виде сообщений, разделённых между собой временными паузами длиной в 3,5 символа при заданной скорости передачи.

В сообщении обязательно указывается адрес получателя (или 0, если сообщение широковещательное) и номер функции.Номер функции определяет какие данные содержит сообщение и как их интерпретировать.

За номером функции идут данные. Регистры данных в ModBus 32-битные, а передаются ввиде двух 16-битных сло. Сначала идёт старший байт, затем младший.

Пример. Допустим, мы хотим прочитать из удалённого модуля сбора данных 2 регистра, начиная с первого. Адрес удалённого модуля в сети ModBus «4». Для этого воспользуемся функцией №3 Read Holding Registers.


Рис. Запрос на чтение 2-х регистров, начиная с 1-го

Рис. Ответ от слейва на запрос

В ответе подчинённое устройство повторяет свой адрес и номер функции, далее следует количество полезных байт в ответе. Каждый регистр состоит из двух байт (сначала идёт старший, затем младший). Значение запрошенных регистров оказались равны 11 и 22 в десятичной системе исчисления (0B и 16 в шестнадцатеричной соответственно).

О том, как использовать другие ModBus функции мы выпустим отдельную статью.

Контроль целостности пакета в ModBus RTU (CRC-16)

В предыдущем примере за байтами данных идут два байта проверки целостности пакета. Они являются результатом вычисления кода CRC-16 для всего сообщения.

Мастер, передавая запрос, вычисляет CRC-код и добавляет его в конец сообщения. Слейв, получив сообщение, проверяет сообщение на целостность согласно алгоритму CRC-16. Затем подчинённое устройство составляет ответ, точно так же вычисляет для него CRC и добавляет в конец пакета.

Подробно рассматривать алгоритм CRC-16 мы не будем, т.к. мы стараемся быть ближе к практике… А на практике программисту практически никогда не приходится писать блок вычисления CRC — в любой среде программирования можно найти соответствующую функцию или функциональный блок.

Заключение

В данной статье мы рассмотрели общую структуру протокола ModBus и его классическую разновидность ModBus RTU. Вообще говоря, ModBus RTU — это и есть «истинный Modbus» (если отбросить ModBus ASCII, который уже устарел).

В мы поговорим о разновидности протокола ModBus TCP, который является «притягиванием за уши» классического ModBus с целью использования его в Ethernet-сетях, что, конечно же, накладывает определённые ограничения. Но об этом в следующей статье. Следите за обновлениями на LAZY SMART .

Modbus - открытый протокол последовательной связи. Был разработан в 1979 году для использования с устройствами программируемого логического контроллера (PLC), в настоящее время широко используется для подключения многих типов промышленных электронных устройств, подключенных к различным типам сетей.

Наиболее широко используемый протокол в промышленной автоматизации (исключение - локальные предприятия). Modbus очень популярен. Это достаточно простое и понятное в использовании устройство со стандартной последовательной связью. В сети Modbus каждое устройство смотрит в сеть как набор катушек (бит) и регистров. Мастер считывает и записывает эти катушки и регистры, используя очень простой и сжатый набор команд. Коммуникация движется только в одном направлении за раз.

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

Modbus — протокол расширенного применения

Преобразователь протоколов широко используется по ряду причин:

  • Modbus — протокол с открытым исходным кодом. Это означает, что он может быть включен в широкий диапазон типов устройств от любого поставщика оборудования.
  • Использует простую структуру сообщений, что делает ее менее сложной для развертывания. Может потребовать всего несколько дней для реализации. Это явное конкурентное преимущество в сравнении с другими протоколами, которые могут потребовать месяцев для изучения и развертывания.
  • Поддерживает последовательные или Ethernet-соединения.
  • Используется с двумя типами последовательных соединений: RS-232 и RS-485. Некоторые версии протокола Modbus tcp также могут быть отправлены через Ethernet или TCP/IP. Эти сообщения Modbus упакованы как однобитовые или 16-битные пакеты слов.

Modbus не является частью физического уровня в сети. Связь передается над физическими уровнями, что позволяет использовать ее во многих различных типах сетей. Это свойство нефизического уровня делает Modbus протоколом прикладного характера.

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

Как правило, ПК настроен на запуск таких программ, как Wonderware, Intellution или LabVIEW в одном месте для сбора данных из разных процессов по всему предприятию. Другое приложение предназначено для настройки удаленных контроллеров производственных процессов (ПЛК, Allen-Bradley, Siemens, PLCDirect и другие). Для реагирования на различные уровни или режимы, которые передаются с устройства.

Два варианта протокола

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

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

Протокол Modbus для чайников

Modbus - это протокол последовательной связи, используемый для передачи информации по последовательным линиям между электронными устройствами. То, которое запрашивает информацию, называется ведущим (Master), а информация о поставке устройств — подчиненные устройства (Slaves). В стандартной сети Modbus есть один Master и до 247 Slaves, каждый из которых имеет уникальный подчиненный адрес от 1 до 247. Master может также записывать информацию в Slaves.

Для чего его используют?

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

Modbus обычно используется для передачи сигналов от приборов и устройств управления обратно в главный контроллер или систему сбора данных, например, систему, которая измеряет температуру и влажность, передает результаты на компьютер. Modbus часто используется для подключения контрольного компьютера с удаленным терминальным блоком (RTU) в системах диспетчерского управления и сбора данных (SCADA). Версии протокола Modbus существуют для последовательных линий (RTU и ASCII) и для Ethernet (TCP).

Как это работает?

Modbus передается по последовательным линиям между устройствами. Самой простой установкой был бы один последовательный кабель, соединяющий последовательные порты на двух устройствах: Master и Slave.

Данные отправляются как серия единиц и нулей, называемых битами. Каждый бит передается как напряжение, нули - положительные, а единицы - отрицательные напряжения. Биты отправляются очень быстро. Типичная скорость передачи составляет 9600 бод (бит в секунду).

Протокол Master/Slave

При описании протокола Modbus RTU связь осуществляется между централизованным ведущим оборудованием, 247 подключенными электронными устройствами в одной сети. Конструкцию обычно называют протоколом «ведущий/ведомый», поскольку система Master запрашивает информацию у подключенных устройств, которые называются «подчиненными». Ведомые устройства отправляют информацию только мастеру в ответ на эти запросы, они не работают автономно. Ведущий может также записывать информацию на подчиненные устройства, но подчиненные устройства не могут записывать информацию ведущему устройству.

Когда ведомое устройство передает сообщение Modbus, оно начинает формировать сообщение с уникальным идентификатором адреса. Это число от 1 до 247, что позволяет мастеру определять, какое конкретное устройство отвечает запрошенной информации.

Связь и устройства

Каждому устройству, предназначенному для связи с использованием Modbus, присваивается уникальный адрес. В последовательных сетях только узел, назначенный мастером, может инициировать команду. В Ethernet любое устройство может отправлять команду Modbus, хотя обычно это делает только одно ведущее. Команда содержит адрес устройства, для которого он предназначен (от 1 до 247). Все команды включают информацию контрольной суммы, чтобы позволить получателю обнаруживать ошибки передачи. Базовые команды Modbus указывают RTU на изменение значения в одном из своих регистров, управление или чтение порта ввода-вывода, команду устройству отправить обратно одно или несколько значений, содержащихся в его регистрах.

Существует много модемов и шлюзов, поддерживающих Modbus, поскольку это очень простой протокол и часто копируется. Некоторые из них были специально разработаны для него. Различные реализации используют проводную, беспроводную связь, например, в диапазоне ISM, и даже службу коротких сообщений (SMS), а также услугу общей пакетной радиосвязи (GPRS). Типичные проблемы, с которыми приходится сталкиваться дизайнерам, включают проблемы с высокой задержкой и временем.

Обзор типов регистра Modbus

Типы регистров, на которые ссылаются устройства, включают:

Катушку (дискретный выход); . дискретный вход; . входной регистр; . регистрацию холдинга.

Коды функций

  • Коды общих функций - от 1 до 127, за исключением пользовательских кодов, проверенных сообществом Modbus, публично задокументированы и гарантированно уникальны.
  • Пользовательские коды функций - находятся в двух диапазонах от 65 до 72, от 100 до 110.
  • Коды зарезервированных функций - используются некоторыми компаниями для устаревших продуктов, недоступны для общего пользования.

Преимущества

Некоторые преимущества использования протокола Modbus:

  • Если драйвер уже установлен, а пользователь знаком с Ethernet и сокетами TCP/IP, драйвер может работать и обмениваться данными с ПК через несколько часов. Расходы на разработку считаются низкими. Требуется минимальное число оборудования. Драйвер совместим с любой операционной системой.
  • Нет необходимости в «экзотических» наборах микросхем, поэтому система может использовать стандартные ПК-карты Ethernet для общения с недавно реализованным устройством. Поскольку стоимость Ethernet падает, сокращаются затраты на аппаратное обеспечение. Пользователи не привязаны к одному поставщику услуг для поддержки, но могут воспользоваться нынешними разработками.
  • Спецификация доступна бесплатно для скачивания, никаких дополнительных лицензионных сборов, необходимых для использования протоколов Modbus, не требуется.
  • Взаимодействие между устройствами разных производителей и совместимость с установленной базой совместимых устройств.

Стоят преобразователи протоколов Modbus дорого. Цена промышленных шлюзов составляет 1000 долларов.

Ограничения

Поскольку Modbus был разработан в конце 1970-х годов для связи с численность типов данных ограничена теми, которые были поняты ПЛК в то время. Большие двоичные объекты не поддерживаются.

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

Поскольку Modbus является протоколом типа «ведущий/ведомый», для устройства нет возможности «сообщать об исключении» (кроме Ethernet TCP/IP, называемого open-mbus). Главный узел должен регулярно получать данные с дочерних устройств, а также искать изменения в данных. Это нагружает полосу пропускания, увеличивает время подключения к сети в приложениях, где пропускная способность может быть дорогой, например, в каналах с низкой скоростью передачи данных.

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

Протокол ModBus, несмотря на множество специализированных протоколов, появившихся в последние десятилетия, все еще занимает лидирующие позиции в задачах автоматизации и диспетчеризации зданий и технологических процессов. Многие специалисты уже привыкли к его использованию, несмотря на его явную архаичность. Тем не менее, судя по статистике поисковых запросов и популярности статей о ModBus, явно существует пласт специалистов, надеюсь, что это молодое поколение, для которых будет полезно, еще раз на пальцах объяснить, что такое ModBus.

В российской википедии существует довольно обширная , в которой рассказывается история протокола, его основные достоинства и недостатки, терминология, модель данных и функционал. Не претендуя на полноту изложения, но в то же время, не боясь повториться, рассмотрим некоторые базовые вещи для тех, кому надо всего-то «два байта переслать».

Прежде всего, как представлены данные в устройстве поддерживающем ModBus. Это четыре таблицы с данными:

Таблица Тип элемента Тип доступа
Дискретные входы (Discrete Inputs) один бит только чтение
Регистры флагов (Coils) один бит чтение и запись
Регистры ввода (Input Registers) 16-битное слово только чтение
Регистры хранения (Holding Registers) 16-битное слово чтение и запись

В реальной практике чаще всего встречаются устройства, в которых есть только таблица Holding Registers, иногда объединённая с таблицей Input Registers.

Для доступа к этим таблицам существует ряд стандартный функций ModBus:

  • 1 (0x01) - чтение значений из нескольких регистров флагов (Read Coil Status).
  • 2 (0x02) - чтение значений из нескольких дискретных входов (Read Discrete Inputs).
  • 3 (0x03) - чтение значений из нескольких регистров хранения (Read Holding Registers).
  • 4 (0x04) - чтение значений из нескольких регистров ввода (Read Input Registers).

Запись одного значения:

  • 5 (0x05) - запись значения одного флага (Force Single Coil).
  • 6 (0x06) - запись значения в один регистр хранения (Preset Single Register).

Запись нескольких значений:

  • 15 (0x0F) - запись значений в несколько регистров флагов (Force Multiple Coils)
  • 16 (0x10) - запись значений в несколько регистров хранения (Preset Multiple Registers)

Из сказанного выше следует, что самые часто используемые функции ModBus это 3, 6 и 16 («Read Holding Registers», «Preset Single Register» и «Preset Multiple Registers» — соответственно).

Что происходит при чтении или записи регистра в ModBus устройство? Рассмотрим, для начала, протокол ModBus RTU. Он применяется для передачи данных по последовательным интерфейсам, таким как RS-232 или RS-485. Большинство современных устройств используют RS-485, так как он, во первых, как правило, двух проводной и во вторых, позволяет подключить несколько устройств в один шлейф.

Важно то, что при подобной топологии на одном шлейфе может быть только один ModBus Master, то есть устройства не могут свободно «общаться» между собой. На каждом шлейфе организуется четкая иерархия Master – Slave («Ведущий» – «Ведомый»). Ведомых, как уже было сказано, может быть несколько, а ведущий только один!

Адресная модель ModBus позволяет использовать адреса устройств с 1 по 247, что иногда вводит в заблуждение некоторых «проектологов», т.к. RS-485 позволяет подключить к одной шине, без усилителей и репитеров, только 32 устройства. На самом деле я рекомендую для стабильной работы, с приемлемым количеством повторных запросов, не превышать значение 20 устройств на одну шину RS-485.

Итак, для чтения одного Holding Register ведущий посылает запрос на адрес ведомого устройства с кодом функции 3 (Read Holding Registers), указанием адреса интересующего регистра и количеством регистров для чтения, в данном случае = 1. На что ведомый отвечает пакетом, в котором повторяет собственный адрес, номер обрабатываемой функции и, в поле данных размещает значение запрашиваемого регистра. Для чтения нескольких последовательных регистров в запросе ведущий просто указывает адрес первого и их количество.

В общем виде, работу функции 3 (Read Holding Registers) протокола ModBus можно представить так:

Теперь рассмотрим, чем отличается ModBus TCP от ModBus RTU. Во первых, нет ограничения на одного ведущего в сети, все устройства могут практически свободно «общаться» между собой. Во вторых используется другой формат пакета, добавился заголовок, что более типично для данной среды передачи.

Так как транспортом для передачи служит протокол TCP, то для адресации устройств ведущему необходимо знать IP адрес ведомого устройства и порт, на котором ведомый ожидает запросов. Стандартный порт для ModBus TCP протокола 502 , но некоторые среды программирования контроллеров, например CODESYS, позволяют его изменить. Тот же самый CODESYS, а точнее контроллеры, запрограммированные в этой среде или средах производных от CODESYS, при работе по протоколу ModBus TCP игнорируют поле «Unit ID» и отвечают на запросы для любого «Unit ID», а не выдают сообщение об ошибке. Это значит, что иногда, достаточно знать IP адрес и порт контроллера.

Довольно часто сталкиваюсь с непониманием модели OSI среди инженеров и проектировщиков АСУ ТП и АСУЗ. Поэтому вот еще одна картинка, разъясняющая то, как пакет ModBus TCP передается по Ethernet сети:

UPD (26.09.2016): Довольно неплохое русскоязычное видео на тему:

В этой статье вы узнаете о протоколе Modbus TCP, который является развитием протокола Modbus RTU. Англоязычная версия статьи доступна на ipc2u.com .

Куда посылать команду Modbus TCP?

В сети Ethernet адресом устройства является его IP-адрес. Обычно устройства находятся в одной подсети, где IP адреса отличаются последними цифрами 192.168.1.20 при использовании самой распространённой маски подсети 255.255.255.0.

Интерфейсом является сеть Ethernet , протоколом передачи данных – TCP/IP .

Используемый TCP-порт: 502 .

Описание протокола Modbus TCP

Команда Modbus TCP состоит из части сообщения Modbus RTU и специального заголовка.

Из сообщения Modbus RTU удаляется SlaveID адрес в начале и CRC контрольная сумма в конце, что образует PDU, Protocol Data Unit.

Ниже приведен пример запроса Modbus RTU для получения значения AO аналогового выхода (holding registers) из регистров от #40108 до 40110 с адресом устройства 17.

11 03 006B 0003 7687

Отбрасываем адрес устройства SlaveID и контрольную сумму CRC и получаем PDU:

03 006B 0003

К началу получившегося сообщения PDU добавляется новый 7-байтовый заголовок, который называется MBAP Header (Modbus Application Header). Этот заголовок имеет следующие данные:

Transaction Identifier (Идентификатор транзакции) : 2 байта устанавливаются Master, чтобы однозначно идентифицировать каждый запрос. Может быть любыми. Эти байты повторятся устройством Slave в ответе, поскольку ответы устройства Slave не всегда могут быть получены в том же порядке, что и запросы.

Protocol Identifier (Идентификатор протокола) : 2 байта устанавливаются Master, всегда будут = 00 00, что соответствует протоколу Modbus.

Length (Длина) : 2 байта устанавливаются Master, идентифицирующие число байтов в сообщении, которые следуют далее. Считается от Unit Identifier до конца сообщения.

Unit Identifier (Идентификатор блока или адрес устройства) : 1 байт устанавливается Master. Повторяется устройством Slave для однозначной идентификации устройства Slave.

Итого получаем:

Modbus RTU Slave ID Запрос CRC
Modbus RTU 11 03 006B 0003 7687
0001 0000 0006 11 03 006B 0003
PDU
ADU, Application Data Unit

В ответе от Modbus TCP Slave устройства мы получим:

0001 0000 0009 11 03 06 022B 0064 007F

0001 Идентификатор транзакции Transaction Identifier
0000 Идентификатор протокола Protocol Identifier
0009 Длина (9 байтов идут следом) Message Length
11 Адрес устройства (17 = 11 hex) Unit Identifier
03 Функциональный код (читаем Analog Output Holding Registers) Function Code
06 Количество байт далее (6 байтов идут следом) Byte Count
02 (02 hex) Register value Hi (AO0)
2B (2B hex) Register value Lo (AO0)
00 Значение старшего разряда регистра (00 hex) Register value Hi (AO1)
64 Значение младшего разряда регистра (64 hex) Register value Lo (AO1)
00 Значение старшего разряда регистра (00 hex) Register value Hi (AO2)
7F Значение младшего разряда регистра (7F hex) Register value Lo (AO2)

Регистр аналогового выхода AO0 имеет значение 02 2B HEX или 555 в десятичной системе.

Регистр аналогового выхода АО1 имеет значение 00 64 HEX или 100 в десятичной системе.

Регистр аналогового выхода АО2 имеет значение 00 7F HEX или 127 в десятичной системе.

Типы команд Modbus TCP

Приведем таблицу с кодами функций чтения и записи регистров Modbus TCP.

Код функции Что делает функция Тип значения Тип доступа
01 (0x01) Чтение DO Read Coil Status Дискретное Чтение
02 (0x02) Чтение DI Read Input Status Дискретное Чтение
03 (0x03) Чтение AO Read Holding Registers 16 битное Чтение
04 (0x04) Чтение AI Read Input Registers 16 битное Чтение
05 (0x05) Запись одного DO Force Single Coil Дискретное Запись
06 (0x06) Запись одного AO Preset Single Register 16 битное Запись
15 (0x0F) Запись нескольких DO Force Multiple Coils Дискретное Запись
16 (0x10) Запись нескольких AO Preset Multiple Registers 16 битное Запись

Как послать команду Modbus TCP на чтение дискретного вывода? Команда 0x01

Эта команда используется для чтения значений дискретных выходов DO.

В запросе PDU задается начальный адрес первого регистра DO и последующее количество необходимых значений DO. В PDU значения DO адресуются, начиная с нуля.

Значения DO в ответе находятся в одном байте и соответствуют значению битов.

Значения битов определяются как 1 = ON и 0 = OFF.

Младший бит первого байта данных содержит значение DO адрес которого указывался в запросе. Остальные значения DO следуют по нарастающей к старшему значению байта. Т.е. справа налево.

Если запрашивалось меньше восьми значений DO, то оставшиеся биты в ответе будут заполнены нулями (в направлении от младшего к старшему байту). Поле Byte Count Количество байт далее указывает количество полных байтов данных в ответе.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 04
01 Адрес устройства 01 Адрес устройства
01 Функциональный код 01 Функциональный код
00 01 Количество байт далее
00 02 Значение регистра DO 0-1
00 Количество регистров Hi байт
02 Количество регистров Lo байт

Состояния выходов DO0-1 показаны как значения байта 02 hex, или в двоичной системе 0000 0010.

Значение DO1 будет вторым справа, а значение DO0 будет первым справа (младший бит).

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

Модули с дискретным выводом: ioLogik E1211 , ET-7060 , ADAM-6060

Как послать команду Modbus TCP на чтение дискретного ввода? Команда 0x02

Эта команда используется для чтения значений дискретных входов DI.

Запрос и ответ для DI похож на запрос для DO.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 04
01 Адрес устройства 01 Адрес устройства
02 Функциональный код 02 Функциональный код
00 Адрес первого регистра Hi байт 01 Количество байт далее
00 Адрес первого регистра Lo байт 03 Значение регистра DI 0-1
00 Количество регистров Hi байт
02 Количество регистров Lo байт

Состояния выходов DI 0-1 показаны как значения байта 03 hex, или в двоичной системе 0000 0011.

Значение DI1 будет вторым справа, а значение DI0 будет первым справа (младший бит).

Шесть остальных битов заполнены нулями.

Модули с дискретным вводом: ioLogik E1210 , ET-7053 , ADAM-6050

Как послать команду Modbus TCP на чтение аналогового вывода? Команда 0x03

Эта команда используется для чтения значений аналоговых выходов AO.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 07
01 Адрес устройства 01 Адрес устройства
03 Функциональный код 03 Функциональный код
00 Адрес первого регистра Hi байт 04 Количество байт далее
00 Адрес первого регистра Lo байт 02 Значение регистра Hi (AO0)
00 Количество регистров Hi байт 2B Значение регистра Lo (AO0)
02 Количество регистров Lo байт 00 Значение регистра Hi (AO1)
64 Значение регистра Lo (AO1)

Состояния выхода AO0 показаны как значения байта 02 2B hex, или в десятичной системе 555.

Состояния выхода AO1 показаны как значения байта 00 64 hex, или в десятичной системе 100.

Модули с дискретным вводом: ioLogik E1210 , ET-7053 , ADAM-6050

Как послать команду Modbus TCP на чтение аналогового ввода? Команда 0x04

Эта команда используется для чтения значений аналоговых входов AI.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 07
01 Адрес устройства 01 Адрес устройства
04 Функциональный код 04 Функциональный код
00 Адрес первого регистра Hi байт 04 Количество байт далее
00 Адрес первого регистра Lo байт 00 Значение регистра Hi (AI0)
00 Количество регистров Hi байт 0A Значение регистра Lo (AI0)
02 Количество регистров Lo байт 00 Значение регистра Hi (AI1)
64 Значение регистра Lo (AI1)

Состояния выхода AI0 показаны как значения байта 00 0A hex, или в десятичной системе 10.

Состояния выхода AI1 показаны как значения байта 00 64 hex, или в десятичной системе 100.

Модули с аналоговым вводом: ioLogik E1240 , ET-7017-10 , ADAM-6217

Как послать команду Modbus TCP на запись дискретного вывода? Команда 0x05

Эта команда используется для записи одного значения дискретного выхода DO.

Значение FF 00 hex устанавливает выход в состояние включен ON.

Значение 00 00 hex устанавливает выход в состояние выключен OFF.

Все остальные значения недопустимы и не будут влиять на состояние выхода.

Нормальный ответ на такой запрос - это эхо (повтор запроса в ответе), возвращается после того, как состояние DO было изменено.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 06
01 Адрес устройства 01 Адрес устройства
05 Функциональный код 05 Функциональный код
00 Адрес регистра Hi байт 00 Адрес регистра Hi байт
01 Адрес регистра Lo байт 01 Адрес регистра Lo байт
FF Значение Hi байт FF Значение Hi байт
00 Значение Lo байт 00 Значение Lo байт

Модули с дискретным выводом: ioLogik E1211 , ET-7060 , ADAM-6060

Как послать команду Modbus TCP на запись аналогового вывода? Команда 0x06

Эта команда используется для записи одного значения аналогового выхода AO.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
06 06
01 Адрес устройства 01 Адрес устройства
06 Функциональный код 06 Функциональный код
00 Адрес регистра Hi байт 00 Адрес регистра Hi байт
01 Адрес регистра Lo байт 01 Адрес регистра Lo байт
55 Значение Hi байт 55 Значение Hi байт
FF Значение Lo байт FF Значение Lo байт

Состояние выхода AO0 поменялось на 55 FF hex, или в десятичной системе 22015.

Модули с аналоговым выводом: ioLogik E1241 , ET-7028 , ADAM-6224

Как послать команду Modbus TCP на запись нескольких дискретных выводов? Команда 0x0F

Эта команда используется для записи нескольких значений дискретного выхода DO.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
08 06
01 Адрес устройства 01 Адрес устройства
0F Функциональный код 0F Функциональный код
00 Адрес первого регистра Hi байт 00 Адрес первого регистра Hi байт
00 Адрес первого регистра Lo байт 00 Адрес первого регистра Lo байт
00 Количество регистров Hi байт 00
02 Количество регистров Lo байт 02
01 Количество байт далее
02 Значение байт

Состояние выхода DO1 поменялось с выключен OFF на включен ON.

Состояние выхода DO0 осталось выключен OFF.

Модули с дискретным выводом: ioLogik E1211 , ET-7060 , ADAM-6060

Как послать команду Modbus TCP на запись нескольких аналоговых выводов? Команда 0x10

Эта команда используется для записи нескольких значений аналогового выхода AO.

Байт Запрос Байт Ответ
(Hex) Название поля (Hex) Название поля
01 Идентификатор транзакции 01 Идентификатор транзакции
02 02
00 Идентификатор протокола 00 Идентификатор протокола
00 00
00 Длина сообщения 00 Длина сообщения
0B 06
01 Адрес устройства 01 Адрес устройства
10 Функциональный код 10 Функциональный код
00 Адрес первого регистра Hi байт 00 Адрес первого регистра Hi байт
00 Адрес первого регистра Lo байт 00 Адрес первого регистра Lo байт
00 Количество регистров Hi байт 00 Кол-во записанных рег. Hi байт
02 Количество регистров Lo байт 02 Кол-во записанных рег. Lo байт
04 Количество байт далее
00 Значение Hi AO0 байт
0A Значение Lo AO0 байт
01 Значение Hi AO1 байт
02 Значение Lo AO1 байт

Состояние выхода AO0 поменялось на 00 0A hex, или в десятичной системе 10.