Modbus tcp коды ошибок

Modbus TCP

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

Оглавление:

  • Куда посылать команду Modbus TCP?
  • Описание протокола Modbus TCP
  • Типы команд Modbus TCP
  • Как послать команду на чтение дискретного вывода? Команда 0x01
  • Как послать команду на чтение дискретного ввода? Команда 0x02
  • Как послать команду на чтение аналогового вывода? Команда 0x03
  • Как послать команду на чтение аналогового ввода? Команда 0x04
  • Как послать команду на запись дискретного вывода? Команда 0x05
  • Как послать команду на запись аналогового вывода? Команда 0x06
  • Как послать команду на запись нескольких дискретных выводов? Команда 0x0F
  • Как послать команду на запись нескольких аналоговых выводов? Команда 0x10
  • Ошибки запроса Modbus TCP
  • Программы для работы с протоколом Modbus TCP

Куда посылать команду 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 написано в этой статье.

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

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

11 03 006B 0003 7687

11 Адрес устройства SlaveID (17 = 11 hex)
03 Функциональный код Function Code (читаем Analog Output Holding Registers)
006B Адрес первого регистра (40108-40001 = 107 =6B hex)
0003 Количество требуемых регистров (чтение 3-х регистров с 40108 по 40110)
7687 Контрольная сумма CRC

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

03 006B 0003

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

MBAP 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
Modbus TCP 0001 0000 0006 11 03 006B 0003
Modbus TCP MBAP Header PDU
Modbus TCP ADU, Application Data Unit

Где:

0001 Идентификатор транзакции Transaction Identifier
0000 Идентификатор протокола Protocol Identifier
0006 Длина (6 байтов идут следом) Message Length
11 Адрес устройства (17 = 11 hex) Unit Identifier
03 Функциональный код (читаем Analog Output Holding Registers) Function Code
006B Адрес первого регистра (40108-40001 = 107 =6B hex) Data Address of the first register
0003 Количество требуемых регистров (чтение 3-х регистров с 40108 по 40110) The total number of registers

В ответе от 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 Адрес первого регистра Hi байт 01 Количество байт далее
00 Адрес первого регистра Lo байт 02 Значение регистра DO 0-1
00 Количество регистров Hi байт
02 Количество регистров Lo байт

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

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

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

Каналы DO 1 DO 0
Биты 0 0 0 0 0 0 1 0
Hex 02

Модули с дискретным выводом: 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 байт

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

Модули с дискретным выводом: 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 Кол-во записанных рег. Hi байт
02 Количество регистров Lo байт 02 Кол-во записанных рег. Lo байт
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.

Состояние выхода AO1 поменялось на 01 02 hex, или в десятичной системе 258.

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

Наверх к оглавлению

Ошибки запроса Modbus TCP

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

Ответ будет содержать измененный Функциональный код, его старший бит будет равен 1.

Пример:

Было Стало
Функциональный код в запросе Функциональный код ошибки в ответе
01 (01 hex) 0000 0001 129 (81 hex) 1000 0001
02 (02 hex) 0000 0010 130 (82 hex) 1000 0010
03 (03 hex) 0000 0011 131 (83 hex) 1000 0011
04 (04 hex) 0000 0100 132 (84 hex) 1000 0100
05 (05 hex) 0000 0101 133 (85 hex) 1000 0101
06 (06 hex) 0000 0110 134 (86 hex) 1000 0110
15 (0F hex) 0000 1111 143 (8F hex) 1000 1111
16 (10 hex) 0001 0000 144 (90 hex) 1001 0000

Пример запроса и ответ с ошибкой:

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

Расшифровка кодов ошибок

01 Принятый код функции не может быть обработан.
02 Адрес данных, указанный в запросе, недоступен.
03 Значение, содержащееся в поле данных запроса, является недопустимой величиной.
04 Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие.
05 Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет ведущее устройство от генерации ошибки тайм-аута.
06 Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится.
07 Ведомое устройство не может выполнить программную функцию, заданную в запросе. Этот код возвращается для не успешного программного запроса, использующего функции с номерами 13 или 14. Ведущее устройство должно запросить диагностическую информацию или информацию об ошибках от ведомого.
08 Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Ведущее устройство может повторить запрос, но обычно в таких случаях требуется ремонт.
10
(0A hex)
Шлюз неправильно настроен или перегружен запросами.
11
(0B hex)
Slave устройства нет в сети или от него нет ответа.

Наверх к оглавлению

Программы для работы с протоколом Modbus TCP

Ниже представлены программы, которые помогут легко взаимодействовать с устройствами Modbus TCP.

Modbus Master Tool с поддержкой Modbus RTU, ASCII, TCP. Скачать

Modbus Master Tool

Modbus TCP client с поддержкой Modbus TCP. Скачать

Modbus TCP client

Наверх к оглавлению

Оставить заявку

Это утверждённая версия страницы. Она же — наиболее свежая версия.

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

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-транзакция, прошедшая без ошибок

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

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

Структуры данных 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 есть шаблон для однофазного счетчика электроэнергии 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-регистров, начиная с первого.

В качестве данных мы получили шестнадцатеричное число 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 Server Device Failure Произошла невосстановимая ошибка на устройстве при выполнении запрошенной операции
        5 Acknowledge Запрос принят, выполняется, но выполнение потребует много времени; необходимо увеличить таймаут.
        6 Server 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 считается индикатором успешного обмена данными.

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

        Расширение протокола Modbus от Wiren Board

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

        Всё описываемое ниже справедливо только для Modbus-устройств Wiren Board.

        Торговое название расширения протокола «Быстрый Modbus».

        Настраиваемое время задержки ответа устройством

        Устройства работают по стандарту, поэтому отвечают master-устройству через 3.5 символа после конца кадра запроса.

        Но некоторые сторонние master-устройства могут не соблюдать стандарт и после отправки запроса продолжают удерживать приемопередатчик в режиме отправки некоторое время.

        В устройствах есть специальный регистр 113, в котором можно настроить время ответа slave-устройства в миллисекундах. Нужное значение подбирается опытным путём.

        Стопбиты

        Устройства всегда ожидают от мастера 1 стопбит, а отправляют ответ с 2.

        Благодаря этому невозможно неправильно настроить стопбиты в master- и в slave-устройстве. Передача ответов более надежная даже, если мастер ожидает 1 стопбит. В последних прошивках настройка стопбита в регистре 112 игнорируется.

        Режим сплошного чтения регистров

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

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

        При таком запросе устройство вернёт пакет со значением регистров. Если регистры отсутствуют в устройстве, то для них будет возвращено значение 0xFFFE.

        Сканирование устройств на шине

        Обычно инсталляция содержит несколько slave-устройств в щите или в поле на одной шине RS-485. Каждое устройство имеет адрес, который пользователь может менять. Обычно при монтаже адреса slave-устройств переписываются с корпуса устройства и вносятся вручную в конфигурацию мастера. Это не очень удобно.

        Раньше для сканирования шины использовался специальный скрипт, который перебирал все возможные адреса на шине и ждал от них ответа в течение определённого времени. Процесс занимал несколько минут и зависел от настроек связи устройств: скорости, стоповых битов и т.п.

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

        Теперь можно собрать щит не обращая внимания на modbus-адреса устройств. В процессе сканирования будут прочитаны модели устройств, настройки связи, их серийные номера и адреса на шине. Притом, вы можете изменить адреса подключённых устройств, обращаясь к устройству по уникальному серийному номеру.

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

        Поддержка быстрого Modbus в прошивках

        Устройство Версия прошивки с поддержкой «быстрого Modbus»
        WB-MRx, WB-MWAC 1.19.0
        WB-MDM3 2.6.0
        WB-LED, WB-MRGBW-D 3.2.0
        WB-MSx, WB-MSWx, WB-MIR, WB-M1W2 4.23.0
        WB-MAI11 не поддерживается
        WB-MAI6 2.0.0
        WB-MAO4 2.2.0
        WB-MAPx 2.4.0
        WB-MIO 1.6.0
        WB-REF-U 1.4.0
        WB-REF-DF 1.1.0

        Содержание:

        1. Компоненты СИМП Лайт
        2. Редактор каналов
        3. Источники данных
        4. Modbus driver
        5. Коды ошибок Modbus

        Расшифровка кодов ошибок Modbus:

         

        01

          Принятый код функции не может быть обработан.
         

        02

          Адрес данных, указанный в запросе, недоступен.
         

        03

          Значение, содержащееся в поле данных запроса,
          является недопустимой величиной.
         

        04

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

        05

          Ведомое устройство приняло запрос и обрабатывает
          его, но это требует много времени. Этот ответ
          предохраняет ведущее устройство от генерации
          ошибки тайм-аута.
         

        06

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

        07

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

        08

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

        10 (0A hex)

          

          Шлюз неправильно настроен или перегружен запросами 
         

        11 (0B hex)

          Slave устройства нет в сети или от него нет ответа 

        Понравилась статья? Поделить с друзьями:
      • Mlsd total commander ошибка
      • Mlp все время закрывается ошибка на телефоне samsung
      • Ml 2240 индикация ошибок
      • Ml 350 ошибка srs
      • Ml 2015 ошибка сети горит красным