Modbus: различия между версиями

Материал из Wiren Board
(не показано 13 промежуточных версий 3 участников)
Строка 5: Строка 5:


<!--T:2-->
<!--T:2-->
Modbus - это протокол прикладного (седьмого) уровня модели [https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_OSI OSI], он служит для обмена данными, чаще всего между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)".  
Modbus - это протокол прикладного (седьмого) уровня модели [https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_OSI OSI]. Чаще всего он служит для обмена данными между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)".  


<!--T:3-->
<!--T:3-->
В устройствах Wirenboard данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети (кроме ведущего см. далее) имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется.
В устройствах Wiren Board данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети (кроме ведущего см. далее) имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется.


<!--T:4-->
<!--T:4-->
Существует две спецификации протокола: Modbus RTU и Modbus ASCII. В Modbus RTU передается 11-битный символ, состоящий из 1 стартового бита, 8 бит данных (начиная с младшего бита), бит четности (необязателен) и 2 стоповых бита, если бит четности не передается, или 1 стоповый бит, если бит четности передается. Такой символ позволяет передать 1 байт данных. В устройствах Wiren Board бит контроля четности не передается и используется 2 стоповых бита. В Modbus ASCII каждый байт передается двумя символами, представляющими ASCII-коды младшей и старшей четырехбитной группы байта ([http://www.simplymodbus.ca/ASCII.htm пример]). Modbus RTU позволяет передавать больше информации при той же скорости последовательной линии и в устройствах Wiren Board используется именно он. Все дальнейшее описание относится к Modbus RTU.
Существует две спецификации протокола: Modbus RTU и Modbus ASCII. В Modbus RTU передается 11-битный символ, состоящий из 1 стартового бита, 8 бит данных (начиная с младшего бита), бит четности (необязателен) и 2 стоповых бита - если бит четности не передается, или 1 стоповый бит - если бит четности передается. Такой символ передает 1 байт данных. В устройствах Wiren Board по умолчанию бит контроля четности не передается и используется 2 стоповых бита. В Modbus ASCII каждый байт передается двумя символами, представляющими ASCII-коды младшей и старшей четырехбитной группы байта ([http://www.simplymodbus.ca/ASCII.htm пример]). Modbus RTU передает больше информации при той же скорости последовательной линии, и в устройствах Wiren Board используется именно он. Все дальнейшее описание относится к Modbus RTU.
 


<!--T:5-->
<!--T:5-->
Строка 18: Строка 17:


<!--T:6-->
<!--T:6-->
[[File:Modbus_Datagram.png|900px|thumb|left|Датаграмма Modbus в общем виде]]
[[File:Modbus_Datagram.png|700px|thumb|right|Датаграмма Modbus в общем виде]]


<!--T:7-->
<!--T:7-->
Строка 42: Строка 41:
----
----
Стоит определить таймаут ожидания ответа от ведомого устройства — бессмысленно долго ждать ответ, который, возможно, из-за какой-то ошибки никогда и не придет.
Стоит определить таймаут ожидания ответа от ведомого устройства — бессмысленно долго ждать ответ, который, возможно, из-за какой-то ошибки никогда и не придет.


===Структуры данных Modbus=== <!--T:14-->
===Структуры данных Modbus=== <!--T:14-->
Строка 48: Строка 46:
<!--T:15-->
<!--T:15-->
В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой (float), текстовых строк, даты и времени суток и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства.
В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой (float), текстовых строк, даты и времени суток и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства.


===Модель данных Modbus=== <!--T:16-->
===Модель данных Modbus=== <!--T:16-->
Строка 74: Строка 71:


<!--T:19-->
<!--T:19-->
'''Дискретные входы''' (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например подано напряжение — 1). Эти регистры поддерживают только чтение.
'''Дискретные входы''' (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например, подано напряжение — 1). Эти регистры поддерживают только чтение.


<!--T:20-->
<!--T:20-->
Строка 80: Строка 77:
Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства.
Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства.


===Адреса и номера регистров=== <!--T:21-->
=== Адреса регистров ===
Регистры в стандарте Modbus адресуются с помощью 16-битных адресов. Адресация начинается с нуля. Адрес регистра, таким образом, может принимать значения от 0 до 65535.
 
Адресные пространства регистров, также называемые таблицами иди блоками, могут быть различны для всех четырёх типов регистров. Это значит, что значения регистров с одинаковым адресом, но разным типом, в общем случае разные.
 
Например, при чтении регистра флагов (coil) номер 42, регистра дискретного входа (Discrete), регистров ввода и хранения (Input и Holding) с теми же адресами, можно получить четыре разных значения.
 
==== Нестандартная адресация ====
В документации на некоторые, особенно старые, устройства адреса элементов (регистров) указываются в формате, не соответствующем стандарту. В этом формате тип элемента кодируется первой цифрой адреса, а адресация начинается не с нуля.
 
Например, регистр хранения с адресом 0 может записываться как 40001 или 400001, а Coil с адресом 0 как 000001.


<!--T:22-->
В таблице перевода адресов в стандартный формат показаны диапазоны для двух разных нестандартных типов указания адресов и соответствующие им типы данных и диапазоны стандартных адресов.
В стандарте Modbus для каждого из четырех типов регистров используются разные таблицы с номерами 0,1,3,4. Таким образом, регистр определенного типа с определенным номером (иначе его называют физическим адресом) имеет свой адрес в соответствующей таблице.  


<!--T:23-->
{|class="wikitable" align="center"
{|class="wikitable" align="center"
! Таблица || Номер таблицы || Начальный логический адрес || Номер регистра (физический адрес) || Диапазон логических адресов
! Тип данных || Стандартные адреса || Стандартные адреса (hex) || Нестандартные адреса (5 цифр) || Нестандартные адреса (6 цифр)
|-
! Флагов (Coils)
| 0-65535 || 0x0000 - 0xFFFF || 00001 - 09999 || 000001 - 065536
|-
|-
! Регистры флагов (Coils)
! Дискретных входов (Discrete)
| 0 || 000001 || 0 || 000001 — 065535
| 0-65535 || 0x0000 - 0xFFFF || 10001 - 19999 || 100001 - 165536
|-
|-
! Дискретные входы (Discrete Inputs)
! Регистры входов (Input Registers)
| 1 || 100001 || 0 || 100001 — 165535
| 0-65535 || 0x0000 - 0xFFFF || 30001 - 39999 || 300001 - 365536
|-
|-
! Регистры хранения (Holding Registers)
! Регистры хранения (Holding Registers)
| 3 || 300001 || 0 || 300001 — 365535
| 0-65535 || 0x0000 - 0xFFFF || 40001 - 49999 || 400001 - 465536
|-
! Регистры ввода (Input Registers)
| 4 || 400001 || 0 || 400001 — 465535
|}
|}


<!--T:24-->
Признаки использования нестандартной адресации:
Это вносит некоторую путаницу в понимание, по какому же адресу обратиться к регистру с нужным номером. Более того, понятия "адрес" и "регистр" могут применяться производителем произвольно. Чаще всего указываются номера регистров, как, например для устройств Wiren Board. В некоторых устройствах применяются более короткие логические адреса (.0001 — .9999), и для адреса используется 5, а не 6 цифр.
* Адреса записываются в десятичном формате
 
* Во всех адресах пять или шесть цифр
<!--T:25-->
* Адреса с недискретными данными (показания датчиков и т.п.) начинаются на 30 или 40
Иногда в описаниях устройства указываются только логические адреса. Например, coil-регистр 0 имеет адрес 000001, регистр ввода 4 — 400005 и т.д.


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


==== Пример описания регистров в документации ====
<!--T:26-->
<!--T:26-->
В готовых шаблонах устройств контроллера Wiren Board 5 есть шаблон для однофазного счетчика электроэнергии SDM220 (/usr/share/wb-mqtt-serial/templates/config-sdm220.json). В документации от производителя "Eastron SDM
В готовых шаблонах устройств контроллера Wiren Board 5 есть шаблон для однофазного счетчика электроэнергии SDM220 (/usr/share/wb-mqtt-serial/templates/config-sdm220.json). В документации от производителя "Eastron SDM
Строка 166: Строка 173:
|-
|-
!    6   
!    6   
| 0x06 ||Write Single Register || Запись одного регистра (ввода или хранения)
| 0x06 ||Write Single Register || Запись одного регистра хранения
|-
|-
!    15   
!    15   
Строка 172: Строка 179:
|-
|-
!    16   
!    16   
| 0x10 ||Write Multiple Register || Запись нескольких регистров (ввода или хранения)
| 0x10 ||Write Multiple Register || Запись нескольких регистров хранения
|-
|-
|}
|}
Строка 178: Строка 185:
<!--T:34-->
<!--T:34-->
Команды условно можно разделить по типам: чтение значений — запись значений; операция с одним значением — операция с несколькими значениями.
Команды условно можно разделить по типам: чтение значений — запись значений; операция с одним значением — операция с несколькими значениями.


=== Формат данных запросов и ответов Modbus === <!--T:35-->
=== Формат данных запросов и ответов Modbus === <!--T:35-->
Строка 224: Строка 230:


<!--T:42-->
<!--T:42-->
В случае, если запрос не может по той или иной причине быть обработан устройством-сервером, то в ответ он отправляет сообщение об ошибке. Соообщение об ошибке содержит адрес Modbus-устройства, код функции, при выполнении которой произошла ошибка, увеличенный на 0x80, код ошибки и контрольную сумму:
Если запрос не может по той или иной причине быть обработан устройством-сервером, то в ответ он отправляет сообщение об ошибке. Соообщение об ошибке содержит адрес Modbus-устройства, код функции, при выполнении которой произошла ошибка, увеличенный на 0x80, код ошибки и контрольную сумму:


<!--T:43-->
<!--T:43-->
Строка 244: Строка 250:
|-
|-
!    3   
!    3   
| Illegal Data Value || В поле данных передано неверное значение
| Illegal Data Value || Неверный формат запроса, например количество байт в запросе не соответствует ожидаемому.
'''Примечание''': несмотря на название, эта ошибка не говорит о том, что само значение регистра неправильное или ошибочное, и должна использоваться только для ошибок формата запроса.
|-
|-
!    4   
!    4   
Строка 262: Строка 269:
|-
|-
|}
|}


=== Вычисление контрольной суммы Modbus === <!--T:46-->
=== Вычисление контрольной суммы Modbus === <!--T:46-->


<!--T:47-->
<!--T:47-->
Для протокола Modbus RTU 16-битная контрольная сумма (CRC) вычисляется по алгоритму, описанному в [http://www.modbus.org/specs.php спецификации Modbus], в документе "Modbus Serial Line Protocol and Implementation Guide", раздел "CRC-generation". Передающее устройство формирует два байта контрольной суммы на основе данных сообщения, а принимающее устройство заново вычисляет контрольную сумму и сравнивает с полученной. Совпадение принятой и вычисленной контрольной суммы Modbud RTU считается индикатором успешного обмена данными.
Для протокола Modbus RTU 16-битная контрольная сумма (CRC) вычисляется по алгоритму, описанному в [http://www.modbus.org/specs.php спецификации Modbus], в документе "Modbus Serial Line Protocol and Implementation Guide", раздел "CRC-generation". Передающее устройство формирует два байта контрольной суммы на основе данных сообщения, а принимающее устройство заново вычисляет контрольную сумму и сравнивает с полученной. Совпадение принятой и вычисленной контрольной суммы Modbus RTU считается индикатором успешного обмена данными.


<!--T:48-->
<!--T:48-->
В случае ограниченных вычислительных ресурсов для вычисления контрольной суммы существует функция, использующая табличные значения (так же приведена в спецификации).
В случае ограниченных вычислительных ресурсов для вычисления контрольной суммы существует функция, использующая табличные значения (также приведена в спецификации).
</translate>
</translate>

Версия 16:06, 21 декабря 2020

Другие языки:

Основные понятия

Modbus - это протокол прикладного (седьмого) уровня модели OSI. Чаще всего он служит для обмена данными между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)".

В устройствах Wiren Board данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети (кроме ведущего см. далее) имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется.

Существует две спецификации протокола: Modbus RTU и Modbus ASCII. В Modbus RTU передается 11-битный символ, состоящий из 1 стартового бита, 8 бит данных (начиная с младшего бита), бит четности (необязателен) и 2 стоповых бита - если бит четности не передается, или 1 стоповый бит - если бит четности передается. Такой символ передает 1 байт данных. В устройствах Wiren Board по умолчанию бит контроля четности не передается и используется 2 стоповых бита. В Modbus ASCII каждый байт передается двумя символами, представляющими ASCII-коды младшей и старшей четырехбитной группы байта (пример). Modbus RTU передает больше информации при той же скорости последовательной линии, и в устройствах Wiren Board используется именно он. Все дальнейшее описание относится к Modbus RTU.

Ведущее устройство ("мастер", или "клиент") периодически опрашивает "ведомое", или "сервер". Ведущее устройство не имеет адреса, передача сообщений от устройства-сервера ведущему без запроса ведущего в протоколе не предусмотрена.

Датаграмма Modbus в общем виде

Пакет данных Modbus выглядит, как это показано на рисунке. PDU (Protocol Data Unit) — общая часть пакета MODBUS, включающая код функции и данные пакета. ADU (Application Data Unit) — полный пакет MODBUS. Включает в себя специфичную для физического уровня часть пакета и PDU. Для последовательных линий в заголовке ADU передается адрес устройства, а в конце — контрольная сумма CRC16. Максимальный размер ADU в последовательных коммуникационных линиях составляет 253 байта (из максимальных, разрешенных спецификацией 256 байт вычитается 1 байт адреса и два байта контрольной суммы). Для справки — в Modbus TCP максимальная длина пакета составляет 260 байт.


Функция кодируется одним байтом и определяет, какое действие должно выполнить устройство-сервер. Значение кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках со стороны устройства-сервера. Код 0 не используется. Размер блока данных может варьироваться от нуля до максимально допустимого. Если обработка запроса прошла без ошибок, то устройство-сервер возвращает пакет ADU, содержащий запрошенные данные.

Modbus-транзакция, прошедшая без ошибок

При возникновении ошибки устройством возвращается код ошибки. В случае обычной транзакции код функции в ответе возвращается без изменений; в случае ошибки старший бит кода функции устанавливается в единицу (то есть код функции + 0x80)

Modbus-транзакция с ошибками

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

Структуры данных Modbus

В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой (float), текстовых строк, даты и времени суток и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства.

Модель данных Modbus

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

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

Регистры флагов (Coils) хранят однобитные значения - то есть могут находится в состоянии 0 или 1. Такие регистры могут обозначать текущее состояние выхода (включено реле). Название "coil" буквально и означает обмотку-актюатор электромеханического реле. Регистры флагов допускают как чтение, так и запись.

Дискретные входы (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например, подано напряжение — 1). Эти регистры поддерживают только чтение.

Регистры хранения (Holding Registers) и регистры ввода (Input Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 — 0xFFFF). Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства.

Адреса регистров

Регистры в стандарте Modbus адресуются с помощью 16-битных адресов. Адресация начинается с нуля. Адрес регистра, таким образом, может принимать значения от 0 до 65535.

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

Например, при чтении регистра флагов (coil) номер 42, регистра дискретного входа (Discrete), регистров ввода и хранения (Input и Holding) с теми же адресами, можно получить четыре разных значения.

Нестандартная адресация

В документации на некоторые, особенно старые, устройства адреса элементов (регистров) указываются в формате, не соответствующем стандарту. В этом формате тип элемента кодируется первой цифрой адреса, а адресация начинается не с нуля.

Например, регистр хранения с адресом 0 может записываться как 40001 или 400001, а Coil с адресом 0 как 000001.

В таблице перевода адресов в стандартный формат показаны диапазоны для двух разных нестандартных типов указания адресов и соответствующие им типы данных и диапазоны стандартных адресов.

Тип данных Стандартные адреса Стандартные адреса (hex) Нестандартные адреса (5 цифр) Нестандартные адреса (6 цифр)
Флагов (Coils) 0-65535 0x0000 - 0xFFFF 00001 - 09999 000001 - 065536
Дискретных входов (Discrete) 0-65535 0x0000 - 0xFFFF 10001 - 19999 100001 - 165536
Регистры входов (Input Registers) 0-65535 0x0000 - 0xFFFF 30001 - 39999 300001 - 365536
Регистры хранения (Holding Registers) 0-65535 0x0000 - 0xFFFF 40001 - 49999 400001 - 465536

Признаки использования нестандартной адресации:

  • Адреса записываются в десятичном формате
  • Во всех адресах пять или шесть цифр
  • Адреса с недискретными данными (показания датчиков и т.п.) начинаются на 30 или 40

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

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

В готовых шаблонах устройств контроллера Wiren Board 5 есть шаблон для однофазного счетчика электроэнергии SDM220 (/usr/share/wb-mqtt-serial/templates/config-sdm220.json). В документации от производителя "Eastron SDM 220 Modbus Smart Meter Modbus Protocol Implementation V1.0" перечислены регистры и соответствующие им измеряемые параметры, например:

Address (Register) Description Units Modbus Protocol Start Address Hex (Hi Byte Lo Byte)
30001 Line to neutral volts. Volts 00 00
30007 Current. Amps. 00 06
30013 Active power Whatts 00 0C
30019 Apparent power VoltAmps 00 12
... ... ... ... ...

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

Фрагмент шаблона счетчика SDM220

Коды функций чтения и записи регистров

В следующей таблице приведены наиболее распространенные коды функций Modbus:

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

Команды условно можно разделить по типам: чтение значений — запись значений; операция с одним значением — операция с несколькими значениями.

Формат данных запросов и ответов Modbus

Рассмотрим подробнее, как происходит обмен данными между устройством-клиентом, отправляющим запрос, и устройством-сервером, отвечающим ему. На следующем рисунке показан обмен данными контроллера с устройством с адресом 0x01. Мы хотим прочесть 8 coil-регистров, начиная с первого.

Обмен данными в Modbus

В качестве данных мы получили шестнадцатеричное число 0x2D, то есть состояние восьми coil-регистров в двоичном виде такое: 0b10110100.


В следующей таблице приведены структуры данных запросов и ответов для основных функций Modbus.

Код функции Запрос Ответ
1 (Read Coils) и 2 (Read Discrete Inputs)
  • Адрес первого регистра флагов или входного регистра (16 бит)
  • Количество данных (8 значений на байт) (16 бит)
    • Число передаваемых байт (8 бит)
    • Значения регистров флагов или входных регистров (8 значений на байт)
    3 (Read Holding Registers) и 4 (Read Input Registers)
    • Адрес первого регистра (16 бит)
    • Количество регистров, которые нужно прочесть
      • Число передаваемых байт (8 бит)
      • Значения регистров (16 бит на 1 регистр)
      5 (Write Single Coil)
      • Адрес регистра (16 бит)
      • Значение, которое нужно записать (0 — выключить, 0xFF00 — включить)
        Ответ аналогичен запросу
        6 (WriteSingle Register)
        • Адрес регистра(16 бит)
        • Новое значение регистра (16 бит)
        Ответ аналогичен запросу
        15 (WriteMultipleCoils)
        • Адрес первого регистра флагов для записи (16 бит)
        • Количество регистров флагов для записи (16 бит)
        • Количество передаваемых байт данных для регистров флагов (8 бит)
        • Данные (8 регистров флагов на байт)
        • Адрес первого coil-регистра (16 бит)
        • Количество записанных coil-регистров(16 бит)
        16 (Write Multiple register )
        • Адрес первого регистра хранения для записи (16 бит)
        • Количество регистров хранения для записи (16 бит)
        • Количество передаваемых байт данных для регистров (8 бит)
        • Данные (16 байт на регистр)
        • Адрес первого регистра хранения (16 бит)
        • Количество записанных регистров хранения(16 бит)


        Коды исключений (ошибки) Modbus

        Если запрос не может по той или иной причине быть обработан устройством-сервером, то в ответ он отправляет сообщение об ошибке. Соообщение об ошибке содержит адрес Modbus-устройства, код функции, при выполнении которой произошла ошибка, увеличенный на 0x80, код ошибки и контрольную сумму:

        Транзакция завершилась с ошибкой

        В этом случае мы попытались обратиться к несуществующему адресу регистра 0xFFFF и попытались прочесть 8 регистров флагов. В результате мы получили код ошибки 0x03 — "В поле данных передано неверное значение".

        Наиболее распространенные коды ошибок Modbus приведены в следующей таблице:

        Код ошибки Название ошибки Что означает
        1 Illegal Function В запросе был передан недопустимый код функции
        2 Illegal Data Address Указанный в запросе адрес не существует
        3 Illegal Data Value Неверный формат запроса, например количество байт в запросе не соответствует ожидаемому.

        Примечание: несмотря на название, эта ошибка не говорит о том, что само значение регистра неправильное или ошибочное, и должна использоваться только для ошибок формата запроса.

        4 Slave Device Failure Произошла невосстановимая ошибка на устройстве при выполнении запрошенной операции
        5 Acknowledge Запрос принят, выполняется, но выполнение потребует много времени; необходимо увеличить таймаут.
        6 Slave Device Busy Устройство занято обработкой предыдущего запроса.
        7 Negative Acknowledge Устройство не может выполнить запрос, необходимо получить от устройства дополнительную диагностическую информацию. Возможно, требуется тех. обслуживание.
        8 Memory Parity Error Ошибка четности при обращении к внутренней памяти устройства.

        Вычисление контрольной суммы Modbus

        Для протокола Modbus RTU 16-битная контрольная сумма (CRC) вычисляется по алгоритму, описанному в спецификации Modbus, в документе "Modbus Serial Line Protocol and Implementation Guide", раздел "CRC-generation". Передающее устройство формирует два байта контрольной суммы на основе данных сообщения, а принимающее устройство заново вычисляет контрольную сумму и сравнивает с полученной. Совпадение принятой и вычисленной контрольной суммы Modbus RTU считается индикатором успешного обмена данными.

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