Статья посвящена промышленному протоколу 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
Номер функции определяет тип запрашиваемых данных и что с ними нужно сделать (прочитать/записать).
Функций ModBus достаточно много и они разделены на три категории:
- стандартные — функции, описанные в стандарте протокола. Среди них много устаревших и неиспользуемых.
- пользовательские — диапазон номеров функций (с 65 по 72 и с 100 по 110), которые может использовать любой производитель устройств для реализации своих специфичных функций. При этом вполне возможно, что у устройств различных производителей под одинаковыми номерами будут разные по смыслу функции.
- зарезервированные — функции, не описанные в базовом стандарте, но реализованные в устройствах различных производителей. При этом гарантируется, что данные производители зарезервировали эти номера для себя и другие производители не могут ими воспользоваться.
Однако, это всё лирика… На практике в большинстве случаев используются всего несколько функций, мы подробно поговорим о них в отдельной статье, а в этой будем рассматривать всё на примере функции Read Holding Registers (чтение регистров общего назначения).
Функция Read Holding Registers (0x03)
Функция под номером 3 — одна из самых употребимых функций, предназначена для чтения регистров общего назначения устройства.
В запросе указывается количество регистров, которые нужно прочитать и адрес первого из них.
Ответ содержит количество байт (количество регистров умноженное на 2) и значения запрошенных регистров.
Рис. Запрос от мастера
Рис. Ответ слейва
Количество байт в ответе помогает ведущему устройству по мере получения данных понять, когда все данные уже получены. То есть если мастер получил третий байт с числом 200 — это означает, что ему осталось получить еще 100 байт + 2 байта контроля целостности. Это позволит ему посчитать количество пришедших байт и закончить приём, не дожидаясь, когда закончится время таймаута, отведённое слейву на ответ.
Коды ошибок ModBus
Вместо нормального ответа, содержащего запрошенные данные, подчинённое устройство может ответить ошибкой. При этом к номеру функции в ответе добавляется код 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 RTU, который широко применяется в АСУ ТП. Англоязычная версия статьи доступна на сайте ipc2u.com. Описание протокола Modbus TCP можно найти в статье.
Оглавление:
- Описание протокола Modbus RTU
- Какие бывают команды Modbus RTU?
- Как послать команду Modbus RTU на чтение дискретного вывода? Команда 0x01
- Как послать команду Modbus RTU на чтение дискретного ввода? Команда 0x02
- Как послать команду Modbus RTU на чтение аналогового вывода? Команда 0x03
- Как послать команду Modbus RTU на чтение аналогового ввода? Команда 0x04
- Как послать команду Modbus RTU на запись дискретного вывода? Команда 0x05
- Как послать команду Modbus RTU на запись аналогового вывода? Команда 0x06
- Как послать команду Modbus RTU на запись нескольких дискретных выводов? Команда 0x0F
- Как послать команду Modbus RTU на запись нескольких аналоговых выводов? Команда 0x10
- Какие бывают ошибки запроса Modbus?
- Программы для работы с протоколом Modbus RTU
Описание протокола Modbus RTU
Modbus — коммуникационный протокол, основан на архитектуре ведущий-ведомый (master-slave). Использует для передачи данных интерфейсы RS-485, RS-422, RS-232, а также Ethernet сети TCP/IP (протокол Modbus TCP).
Сообщение Modbus RTU состоит из адреса устройства SlaveID, кода функции, специальных данных в зависимости от кода функции и CRC контрольной суммы.
SlaveID | Код функции | Специальные данные | CRC |
Если отбросить SlaveID адрес и CRC контрольную сумму, то получится PDU, Protocol Data Unit.
SlaveID – это адрес устройства, может принимать значение от 0 до 247, адреса с 248 до 255 зарезервированы.
Данные в модуле хранятся в 4 таблицах.
Две таблицы доступны только для чтения и две для чтения-записи.
В каждой таблице помещается 9999 значений.
Номер регистра | Адрес регистра HEX | Тип | Название | Тип |
---|---|---|---|---|
1-9999 | 0000 до 270E | Чтение-запись | Discrete Output Coils | DO |
10001-19999 | 0000 до 270E | Чтение | Discrete Input Contacts | DI |
30001-39999 | 0000 до 270E | Чтение | Analog Input Registers | AI |
40001-49999 | 0000 до 270E | Чтение-запись | Analog Output Holding Registers | AO |
В сообщении Modbus используется адрес регистра.
Например, первый регистр AO Holding Register, имеет номер 40001, но его адрес равен 0000.
Разница между этими двумя величинами есть смещение offset.
Каждая таблица имеет свое смещение, соответственно: 1, 10001, 30001 и 40001.
Ниже приведен пример запроса 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 |
В ответе от Modbus RTU Slave устройства мы получим:
11 03 06 AE41 5652 4340 49AD
Где:
11 | Адрес устройства (17 = 11 hex) | SlaveID |
03 | Функциональный код | Function Code |
06 | Количество байт далее (6 байтов идут следом) | Byte Count |
AE | Значение старшего разряда регистра (AE hex) | Register value Hi (AO0) |
41 | Значение младшего разряда регистра (41 hex) | Register value Lo (AO0) |
56 | Значение старшего разряда регистра (56 hex) | Register value Hi (AO1) |
52 | Значение младшего разряда регистра (52 hex) | Register value Lo (AO1) |
43 | Значение старшего разряда регистра (43 hex) | Register value Hi (AO2) |
40 | Значение младшего разряда регистра (40 hex) | Register value Lo (AO2) |
49 | Контрольная сумма | CRC value Lo |
AD | Контрольная сумма | CRC value Hi |
Регистр аналогового выхода AO0 имеет значение AE 41 HEX или 44609 в десятичной системе.
Регистр аналогового выхода AO1 имеет значение 56 52 HEX или 22098 в десятичной системе.
Регистр аналогового выхода AO2 имеет значение 43 40 HEX или 17216 в десятичной системе.
Значение AE 41 HEX — это 16 бит 1010 1110 0100 0001, может принимать различное значение, в зависимости от типа представления.
Значение регистра 40108 при комбинации с регистром 40109 дает 32 бит значение.
Пример представления.
Тип представления | Диапазон значений | Пример в HEX | Будет в десятичной форме |
---|---|---|---|
16-bit unsigned integer | 0 до 65535 | AE41 | 44,609 |
16-bit signed integer | -32768 до 32767 | AE41 | -20,927 |
two character ASCII string | 2 знака | AE41 | ® A |
discrete on/off value | 0 и 1 | 0001 | 0001 |
32-bit unsigned integer | 0 до 4,294,967,295 | AE41 5652 | 2,923,517,522 |
32-bit signed integer | -2,147,483,648 до 2,147,483,647 | AE41 5652 | -1,371,449,774 |
32-bit single precision IEEE floating point number | 1,2·10−38 до 3,4×10+38 | AE41 5652 | -4.395978 E-11 |
four character ASCII string | 4 знака | AE41 5652 | ® A V R |
Наверх к оглавлению
Какие бывают команды Modbus RTU?
Приведем таблицу с кодами функций чтения и записи регистров Modbus RTU.
Код функции | Что делает функция | Тип значения | Тип доступа | |
---|---|---|---|---|
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 RTU на чтение дискретного вывода? Команда 0x01
Эта команда используется для чтения значений дискретных выходов DO.
В запросе PDU задается начальный адрес первого регистра DO и последующее количество необходимых значений DO. В PDU значения DO адресуются, начиная с нуля.
Значения DO в ответе находятся в одном байте и соответствуют значению битов.
Значения битов определяются как 1 = ON и 0 = OFF.
Младший бит первого байта данных содержит значение DO адрес которого указывался в запросе. Остальные значения DO следуют по нарастающей к старшему значению байта. Т.е. справа на лево.
Если запрашивалось меньше восьми значений DO, то оставшиеся биты в ответе будут заполнены нулями (в направлении от младшего к старшему байту). Поле Byte Count Количество байт далее указывает количество полных байтов данных в ответе.
Пример запроса DO с 20 по 56 для SlaveID адреса устройства 17. Адрес первого регистра будет 0013 hex = 19, т.к. счет ведется с 0 адреса (0014 hex = 20, -1 смещение нуля = получаем 0013 hex = 19).
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
01 | Функциональный код | 01 | Функциональный код |
00 | Адрес первого регистра Hi байт | 05 | Количество байт далее |
13 | Адрес первого регистра Lo байт | CD | Значение регистра DO 27-20 (1100 1101) |
00 | Количество регистров Hi байт | 6B | Значение регистра DO 35-28 (0110 1011) |
25 | Количество регистров Lo байт | B2 | Значение регистра DO 43-36 (1011 0010) |
0E | Контрольная сумма CRC | 0E | Значение регистра DO 51-44 (0000 1110) |
84 | Контрольная сумма CRC | 1B | Значение регистра DO 56-52 (0001 1011) |
45 | Контрольная сумма CRC | ||
E6 | Контрольная сумма CRC |
Состояния выходов DO 27-20 показаны как значения байта CD hex, или в двоичной системе 1100 1101.
В регистре DO 56-52 5 битов справа были запрошены, а остальные биты заполнены нулями до полного байта (0001 1011).
Каналы | — | — | — | DO 56 | DO 55 | DO 54 | DO 53 | DO 52 |
---|---|---|---|---|---|---|---|---|
Биты | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 |
Hex | 1B |
Модули с дискретным выводом: M-7065, ioLogik R1214, ADAM-4056S
Наверх к оглавлению
Как послать команду Modbus RTU на чтение дискретного ввода? Команда 0x02
Эта команда используется для чтения значений дискретных входов DI.
Пример запроса DI с регистров от #10197 до 10218 для SlaveID адреса устройства 17. Адрес первого регистра будет 00C4 hex = 196, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
02 | Функциональный код | 02 | Функциональный код |
00 | Адрес первого регистра Hi байт | 03 | Количество байт далее |
C4 | Адрес первого регистра Lo байт | AC | Значение регистра DI 10204-10197 (1010 1100) |
00 | Количество регистров Hi байт | DB | Значение регистра DI 10212-10205 (1101 1011) |
16 | Количество регистров Lo байт | 35 | Значение регистра DI 10218-10213 (0011 0101) |
BA | Контрольная сумма CRC | 20 | Контрольная сумма CRC |
A9 | Контрольная сумма CRC | 18 | Контрольная сумма CRC |
Модули с дискретным вводом: M-7053, ioLogik R1210, ADAM-4051
Наверх к оглавлению
Как послать команду Modbus RTU на чтение аналогового вывода? Команда 0x03
Эта команда используется для чтения значений аналоговых выходов AO.
Пример запроса AO с регистров от #40108 до 40110 для SlaveID адреса устройства 17. Адрес первого регистра будет 006B hex = 107, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
03 | Функциональный код | 03 | Функциональный код |
00 | Адрес первого регистра Hi байт | 06 | Количество байт далее |
6B | Адрес первого регистра Lo байт | AE | Значение регистра Hi #40108 |
00 | Количество регистров Hi байт | 41 | Значение регистра Lo #40108 |
03 | Количество регистров Lo байт | 56 | Значение регистра Hi #40109 |
76 | Контрольная сумма CRC | 52 | Значение регистра Lo #40109 |
87 | Контрольная сумма CRC | 43 | Значение регистра Hi #40110 |
40 | Значение регистра Lo #40110 | ||
49 | Контрольная сумма CRC | ||
AD | Контрольная сумма CRC |
Модули с аналоговым выводом: M-7024, ioLogik R1241, ADAM-4024
Наверх к оглавлению
Как послать команду Modbus RTU на чтение аналогового ввода? Команда 0x04
Эта команда используется для чтения значений аналоговых входов AI.
Пример запроса AI с регистра #30009 для SlaveID адреса устройства 17. Адрес первого регистра будет 0008 hex = 8, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
04 | Функциональный код | 04 | Функциональный код |
00 | Адрес первого регистра Hi байт | 02 | Количество байт далее |
08 | Адрес первого регистра Lo байт | 00 | Значение регистра Hi #30009 |
00 | Количество регистров Hi байт | 0A | Значение регистра Lo #30009 |
01 | Количество регистров Lo байт | F8 | Контрольная сумма CRC |
B2 | Контрольная сумма CRC | F4 | Контрольная сумма CRC |
98 | Контрольная сумма CRC |
Модули с аналоговым вводом: M-7017, ioLogik R1240, ADAM-4017+
Наверх к оглавлению
Как послать команду Modbus RTU на запись дискретного вывода? Команда 0x05
Эта команда используется для записи одного значения дискретного выхода DO.
Значение FF 00 hex устанавливает выход в значение включен ON.
Значение 00 00 hex устанавливает выход в значение выключен OFF.
Все остальные значения недопустимы и не будут влиять значение на выходе.
Нормальный ответ на такой запрос — это эхо (повтор запроса в ответе), возвращается после того, как состояние DO было изменено.
Пример записи в DO с регистром #173 для SlaveID адреса устройства 17. Адрес регистра будет 00AC hex = 172, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
05 | Функциональный код | 05 | Функциональный код |
00 | Адрес первого регистра Hi байт | 00 | Адрес первого регистра Hi байт |
AC | Адрес первого регистра Lo байт | AC | Адрес первого регистра Lo байт |
FF | Значение Hi байт | FF | Значение Hi байт |
00 | Значение Lo байт | 00 | Значение Lo байт |
4E | Контрольная сумма CRC | 4E | Контрольная сумма CRC |
8B | Контрольная сумма CRC | 8B | Контрольная сумма CRC |
Состояние выхода DO173 поменялось с выключен OFF на включен ON.
Модули с дискретным выводом: M-7053, ioLogik R1210, ADAM-4051
Наверх к оглавлению
Как послать команду Modbus RTU на запись аналогового вывода? Команда 0x06
Эта команда используется для записи одного значения аналогового выхода AO.
Пример записи в AO с регистром #40002 для SlaveID адреса устройства 17. Адрес первого регистра будет 0001 hex = 1, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
06 | Функциональный код | 06 | Функциональный код |
00 | Адрес первого регистра Hi байт | 00 | Адрес первого регистра Hi байт |
01 | Адрес первого регистра Lo байт | 01 | Адрес первого регистра Lo байт |
00 | Значение Hi байт | 00 | Значение Hi байт |
03 | Значение Lo байт | 03 | Значение Lo байт |
9A | Контрольная сумма CRC | 9A | Контрольная сумма CRC |
9B | Контрольная сумма CRC | 9B | Контрольная сумма CRC |
Модули с аналоговым выводом: M-7024, ioLogik R1241, ADAM-4024
Наверх к оглавлению
Как послать команду Modbus RTU на запись нескольких дискретных выводов? Команда 0x0F
Эта команда используется для записи нескольких значений дискретного выхода DO.
Пример записи в несколько DO с регистрами от #20 до #29 для SlaveID адреса устройства 17. Адрес регистра будет 0013 hex = 19, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
0F | Функциональный код | 0F | Функциональный код |
00 | Адрес первого регистра Hi байт | 00 | Адрес первого регистра Hi байт |
13 | Адрес первого регистра Lo байт | 13 | Адрес первого регистра Lo байт |
00 | Количество регистров Hi байт | 00 | Кол-во записанных рег. Hi байт |
0A | Количество регистров Lo байт | 0A | Кол-во записанных рег. Lo байт |
02 | Количество байт далее | 26 | Контрольная сумма CRC |
CD | Значение байт DO 27-20 (1100 1101) | 99 | Контрольная сумма CRC |
01 | Значение байт DO 29-28 (0000 0001) | ||
BF | Контрольная сумма CRC | ||
0B | Контрольная сумма CRC |
В ответе возвращается количество записанных регистров.
Модули с дискретным выводом: M-7053, ioLogik R1210, ADAM-4051
Наверх к оглавлению
Как послать команду Modbus RTU на запись нескольких аналоговых выводов? Команда 0x10
Эта команда используется для записи нескольких значений аналогового выхода AO.
Пример записи в несколько AO с регистрами #40002 и #40003 для SlaveID адреса устройства 17. Адрес первого регистра будет 0001 hex = 1, т.к. счет ведется с 0 адреса.
Байт | Запрос | Байт | Ответ |
---|---|---|---|
(Hex) | Название поля | (Hex) | Название поля |
11 | Адрес устройства | 11 | Адрес устройства |
10 | Функциональный код | 10 | Функциональный код |
00 | Адрес первого регистра Hi байт | 00 | Адрес первого регистра Hi байт |
01 | Адрес первого регистра Lo байт | 01 | Адрес первого регистра Lo байт |
00 | Количество регистров Hi байт | 00 | Кол-во записанных рег. Hi байт |
02 | Количество регистров Lo байт | 02 | Кол-во записанных рег. Lo байт |
04 | Количество байт далее | 12 | Контрольная сумма CRC |
00 | Значение Hi 40002 | 98 | Контрольная сумма CRC |
0A | Значение Lo 40002 | ||
01 | Значение Hi 40003 | ||
02 | Значение Lo 40003 | ||
C6 | Контрольная сумма CRC | ||
F0 | Контрольная сумма CRC |
Модули с аналоговым выводом: M-7024, ioLogik R1241, ADAM-4024
Наверх к оглавлению
Какие бывают ошибки запроса Modbus?
Если устройство получило запрос, но запрос не может быть обработан, то устройство ответит кодом ошибки.
Ответ будет содержать измененный Функциональный код, старший бит будет равен 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) | Название поля |
0A | Адрес устройства | 0A | Адрес устройства |
01 | Функциональный код | 81 | Функциональный код с измененным битом |
04 | Адрес первого регистра Hi байт | 02 | Код ошибки |
A1 | Адрес первого регистра Lo байт | B0 | Контрольная сумма CRC |
00 | Количество регистров Hi байт | 53 | Контрольная сумма CRC |
01 | Количество регистров Lo байт | ||
AC | Контрольная сумма CRC | ||
63 | Контрольная сумма CRC |
Расшифровка кодов ошибок
01 | Принятый код функции не может быть обработан. |
02 | Адрес данных, указанный в запросе, недоступен. |
03 | Значение, содержащееся в поле данных запроса, является недопустимой величиной. |
04 | Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие. |
05 | Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет ведущее устройство от генерации ошибки тайм-аута. |
06 | Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится. |
07 | Ведомое устройство не может выполнить программную функцию, заданную в запросе. Этот код возвращается для неуспешного программного запроса, использующего функции с номерами 13 или 14. Ведущее устройство должно запросить диагностическую информацию или информацию об ошибках от ведомого. |
08 | Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Ведущее устройство может повторить запрос, но обычно в таких случаях требуется ремонт. |
10 (0A hex) |
Шлюз неправильно настроен или перегружен запросами. |
11 (0B hex) |
Slave устройства нет в сети или от него нет ответа. |
Наверх к оглавлению
Программы для работы с протоколом Modbus RTU
Ниже перечислены программы, которые облегчают работу с Modbus.
DCON Utility Pro с поддержкой Modbus RTU, ASCII, DCON. Скачать
Modbus Master Tool с поддержкой Modbus RTU, ASCII, TCP. Скачать
Modbus TCP client с поддержкой Modbus TCP. Скачать
Наверх к оглавлению
Оставить заявку
Во время обмена
данными могут возникать ошибки двух
типов:
-
ошибки, связанные
с искажениями при передаче данных; -
логические ошибки.
Ошибки первого
типа обнаруживаются при помощи фреймов
символов, контроля чётности и циклической
контрольной суммы CRC-16-IBM
(используется число-полином
= 0xA001).
Rtu фрейм
В RTU режиме сообщение
должно начинаться и заканчиваться
интервалом тишины — временем передачи
не менее 3.5 символов при данной скорости
в сети. Первым полем затем передаётся
адрес устройства.
Вслед за последним
передаваемым символом также следует
интервал тишины продолжительностью не
менее 3.5 символов. Новое сообщение может
начинаться после этого интервала.
Фрейм сообщения
передаётся непрерывно. Если интервал
тишины продолжительностью 1.5 возник во
время передачи фрейма, принимающее
устройство должно игнорировать этот
фрейм как неполный.
Таким образом,
новое сообщение должно начинаться не
раньше 3.5 интервала, т.к. в этом случае
устанавливается ошибка.
Немного об интервалах
(речь идёт о Serial Modbus RTU): при скорости
9600 и 11 битах в кадре (стартовый бит + 8
бит данных + бит контроля чётности +
стоп-бит): 3.5 * 11 / 9600 = 0,00401041(6), т.е. более
4 мс; 1.5 * 11 / 9600 = 0,00171875, т.е. не более 1 мс.
Для скоростей более 19200 бод допускается
использовать интервалы 1,75 и 0,75 мс
соотвественно.
Логические ошибки
Для сообщений об
ошибках второго типа протокол Modbus RTU
предусматривает, что устройства могут
отсылать ответы, свидетельствующие об
ошибочной ситуации. Признаком того, что
ответ содержит сообщение об ошибке,
является установленный старший бит
кода команды. Пример кадра при выявлении
ошибки ведомым устройством, в ответ на
запрос приведён в (Таблица 2-1).
1. Если Slave принимает
корректный запрос и может его нормально
обработать, то возвращает нормальный
ответ.
2. Если Slave не
принимает какого либо значения, никакого
ответа не отправляется. Master диагностирует
ошибку по таймауту.
3. Если Slave принимает
запрос, но обнаруживает ошибку (parity,
LRC, or CRC), никакого ответа не отправляется.
Master диагностирует ошибку по таймауту.
4. Если Slave принимает
запрос, но не может его обработать
(обращение к несуществующему регистру
и т.д.), отправляется ответ содержащий
в себе данные об ошибке.
Направление |
адрес |
номер |
данные |
CRC |
Запрос |
0x01 |
0x77 |
0xDD |
0xC7 |
Ответ |
0x01 |
0xF7 |
0xEE |
0xE6 |
Таблица |
Стандартные коды ошибок
01
Принятый код функции не может быть
обработан на подчиненном.
02
Адрес данных указанный в запросе не
доступен данному подчиненному.
03
Величина содержащаяся в поле данных
запроса является не допустимой
величиной
для подчиненного.
04
Невосстанавливаемая ошибка имела место
пока подчиненный пытался выполнить
затребованное
действие.
05
Подчиненный принял запрос и обрабатывает
его, но это требует много времени.
Этот
ответ предохраняет главного от генерации
ошибки таймаута.
06
Подчиненный занят обработкой команды.
Главный
должен повторить сообщение позже, когда
подчиненный освободится.
07
Подчиненный не может выполнить программную
функцию, принятую в запросе.
Этот
код возвращается для неудачного
программного запроса, использующего
функции
с номерами 13 или 14.
Главный
должен запросить диагностическую
информацию или информацию об
ошибках
с подчиненного.
08
Подчиненный пытается читать расширенную
память, но обнаружил ошибку паритета.
Главный
может повторить запрос, но обычно в
таких случаях требуется ремонт.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
Содержание:
- Компоненты СИМП Лайт
- Редактор каналов
- Источники данных
- Modbus driver
- Коды ошибок Modbus
Расшифровка кодов ошибок Modbus:
01
|
Принятый код функции не может быть обработан. |
02 |
Адрес данных, указанный в запросе, недоступен. |
03 |
Значение, содержащееся в поле данных запроса, является недопустимой величиной. |
04 |
Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие. |
05 |
Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет ведущее устройство от генерации ошибки тайм-аута. |
06 |
Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится. |
07 |
Ведомое устройство не может выполнить программную функцию, заданную в запросе. Этот код возвращается для неуспешного программного запроса, использующего функции с номерами 13 или 14. Ведущее устройство должно запросить диагностическую информацию или информацию об ошибках от ведомого. |
08 |
Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Ведущее устройство может повторить запрос, но обычно в таких случаях требуется ремонт. |
10 (0A hex)
|
Шлюз неправильно настроен или перегружен запросами |
11 (0B hex)
|
Slave устройства нет в сети или от него нет ответа |
Содержание:
- Компоненты СИМП Лайт
- Редактор каналов
- Источники данных
- Modbus driver
- Коды ошибок Modbus
Расшифровка кодов ошибок Modbus:
01 |
Принятый код функции не может быть обработан. |
02 |
Адрес данных, указанный в запросе, недоступен. |
03 |
Значение, содержащееся в поле данных запроса, является недопустимой величиной. |
04 |
Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие. |
05 |
Ведомое устройство приняло запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет ведущее устройство от генерации ошибки тайм-аута. |
06 |
Ведомое устройство занято обработкой команды. Ведущее устройство должно повторить сообщение позже, когда ведомое освободится. |
07 |
Ведомое устройство не может выполнить программную функцию, заданную в запросе. Этот код возвращается для неуспешного программного запроса, использующего функции с номерами 13 или 14. Ведущее устройство должно запросить диагностическую информацию или информацию об ошибках от ведомого. |
08 |
Ведомое устройство при чтении расширенной памяти обнаружило ошибку паритета. Ведущее устройство может повторить запрос, но обычно в таких случаях требуется ремонт. |
10 (0A hex) |
Шлюз неправильно настроен или перегружен запросами |
11 (0B hex) |
Slave устройства нет в сети или от него нет ответа |
Статья посвящена промышленному протоколу ModBus — наиболее простому, а потому широко распространённому цифровому протоколу передачи данных.
Стандарт ModBus был изобретён ещё в 1979 году компанией Modicon (ныне Schneider Electric) и с того времени не утратил своей актуальности, а даже наоборот получил широкое распространение и большую популярность среди разработчиков АСУ ТП.
Преимущества:
- прост в реализации
- отсутствует необходимость установки специальных микросхем для реализации протокола при разработке контроллеров и устройств
- простота диагностики и отладки
- поддерживается большинством устройств, применяемых при построении АСУ ТП
- высокая надёжность и достоверность при передаче данных
Недостатки:
- 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
Номер функции определяет тип запрашиваемых данных и что с ними нужно сделать (прочитать/записать).
Функций ModBus достаточно много и они разделены на три категории:
- стандартные — функции, описанные в стандарте протокола. Среди них много устаревших и неиспользуемых.
- пользовательские — диапазон номеров функций (с 65 по 72 и с 100 по 110), которые может использовать любой производитель устройств для реализации своих специфичных функций. При этом вполне возможно, что у устройств различных производителей под одинаковыми номерами будут разные по смыслу функции.
- зарезервированные — функции, не описанные в базовом стандарте, но реализованные в устройствах различных производителей. При этом гарантируется, что данные производители зарезервировали эти номера для себя и другие производители не могут ими воспользоваться.
Однако, это всё лирика… На практике в большинстве случаев используются всего несколько функций, мы подробно поговорим о них в отдельной статье, а в этой будем рассматривать всё на примере функции Read Holding Registers (чтение регистров общего назначения).
Функция Read Holding Registers (0x03)
Функция под номером 3 — одна из самых употребимых функций, предназначена для чтения регистров общего назначения устройства.
В запросе указывается количество регистров, которые нужно прочитать и адрес первого из них.
Ответ содержит количество байт (количество регистров умноженное на 2) и значения запрошенных регистров.
Рис. Запрос от мастера
Рис. Ответ слейва
Количество байт в ответе помогает ведущему устройству по мере получения данных понять, когда все данные уже получены. То есть если мастер получил третий байт с числом 200 — это означает, что ему осталось получить еще 100 байт + 2 байта контроля целостности. Это позволит ему посчитать количество пришедших байт и закончить приём, не дожидаясь, когда закончится время таймаута, отведённое слейву на ответ.
Коды ошибок ModBus
Вместо нормального ответа, содержащего запрошенные данные, подчинённое устройство может ответить ошибкой. При этом к номеру функции в ответе добавляется код 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 — это протокол прикладного (седьмого) уровня модели 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) |
|
|
3 (Read Holding Registers) и 4 (Read Input Registers) |
|
|
5 (Write Single Coil) |
|
Ответ аналогичен запросу |
6 (WriteSingle Register) |
|
Ответ аналогичен запросу |
15 (WriteMultipleCoils) |
|
|
16 (Write Multiple register ) |
|
|
Коды исключений (ошибки) 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 |
Во время обмена
данными могут возникать ошибки двух
типов:
-
ошибки, связанные
с искажениями при передаче данных; -
логические ошибки.
Ошибки первого
типа обнаруживаются при помощи фреймов
символов, контроля чётности и циклической
контрольной суммы CRC-16-IBM
(используется число-полином
= 0xA001).
Rtu фрейм
В RTU режиме сообщение
должно начинаться и заканчиваться
интервалом тишины — временем передачи
не менее 3.5 символов при данной скорости
в сети. Первым полем затем передаётся
адрес устройства.
Вслед за последним
передаваемым символом также следует
интервал тишины продолжительностью не
менее 3.5 символов. Новое сообщение может
начинаться после этого интервала.
Фрейм сообщения
передаётся непрерывно. Если интервал
тишины продолжительностью 1.5 возник во
время передачи фрейма, принимающее
устройство должно игнорировать этот
фрейм как неполный.
Таким образом,
новое сообщение должно начинаться не
раньше 3.5 интервала, т.к. в этом случае
устанавливается ошибка.
Немного об интервалах
(речь идёт о Serial Modbus RTU): при скорости
9600 и 11 битах в кадре (стартовый бит + 8
бит данных + бит контроля чётности +
стоп-бит): 3.5 * 11 / 9600 = 0,00401041(6), т.е. более
4 мс; 1.5 * 11 / 9600 = 0,00171875, т.е. не более 1 мс.
Для скоростей более 19200 бод допускается
использовать интервалы 1,75 и 0,75 мс
соотвественно.
Логические ошибки
Для сообщений об
ошибках второго типа протокол Modbus RTU
предусматривает, что устройства могут
отсылать ответы, свидетельствующие об
ошибочной ситуации. Признаком того, что
ответ содержит сообщение об ошибке,
является установленный старший бит
кода команды. Пример кадра при выявлении
ошибки ведомым устройством, в ответ на
запрос приведён в (Таблица 2-1).
1. Если Slave принимает
корректный запрос и может его нормально
обработать, то возвращает нормальный
ответ.
2. Если Slave не
принимает какого либо значения, никакого
ответа не отправляется. Master диагностирует
ошибку по таймауту.
3. Если Slave принимает
запрос, но обнаруживает ошибку (parity,
LRC, or CRC), никакого ответа не отправляется.
Master диагностирует ошибку по таймауту.
4. Если Slave принимает
запрос, но не может его обработать
(обращение к несуществующему регистру
и т.д.), отправляется ответ содержащий
в себе данные об ошибке.
Направление |
адрес |
номер |
данные |
CRC |
Запрос |
0x01 |
0x77 |
0xDD |
0xC7 |
Ответ |
0x01 |
0xF7 |
0xEE |
0xE6 |
Таблица |
Стандартные коды ошибок
01
Принятый код функции не может быть
обработан на подчиненном.
02
Адрес данных указанный в запросе не
доступен данному подчиненному.
03
Величина содержащаяся в поле данных
запроса является не допустимой
величиной
для подчиненного.
04
Невосстанавливаемая ошибка имела место
пока подчиненный пытался выполнить
затребованное
действие.
05
Подчиненный принял запрос и обрабатывает
его, но это требует много времени.
Этот
ответ предохраняет главного от генерации
ошибки таймаута.
06
Подчиненный занят обработкой команды.
Главный
должен повторить сообщение позже, когда
подчиненный освободится.
07
Подчиненный не может выполнить программную
функцию, принятую в запросе.
Этот
код возвращается для неудачного
программного запроса, использующего
функции
с номерами 13 или 14.
Главный
должен запросить диагностическую
информацию или информацию об
ошибках
с подчиненного.
08
Подчиненный пытается читать расширенную
память, но обнаружил ошибку паритета.
Главный
может повторить запрос, но обычно в
таких случаях требуется ремонт.
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
- #
Modbus — коммуникационный протокол, основанный на клиент-серверной архитектуре. Разработан фирмой Modicon для использования в контроллерах с программируемой логикой (PLC). Стал стандартом де-факто в промышленности и широко применяется для организации связи промышленного электронного оборудования. Использует для передачи данных последовательные линии связи RS-485, RS-422, RS-232, а также сети TCP/IP. В настоящее время поддерживается некоммерческой организацией Modbus-IDA.
Общее описание протокола Modbus RTU[править | править код]
Протокол Modbus описывает единый простой формат передачи данных PDU, который в свою очередь входит в полный пакет ADU. Формат ADU меняется в зависимости от типа линии связи. Существуют три режима протокола: Modbus RTU, Modbus ASCII, Modbus TCP. Первые два используют последовательные линии связи (в основном RS-485, реже RS-422/RS-232), последний использует для передачи данных по сетям TCP/IP.
Протокол Modbus RTU предполагает одно ведущее (запрашивающее) устройство в линии (master), которое может передавать команды одному или нескольким ведомым устройствам (slave), обращаясь к ним по уникальному в линии адресу. Синтаксис команд протокола позволяет адресовать 247 устройств на одной линии связи стандарта RS-485 (реже RS-422 или RS-232).
Инициатива проведения обмена всегда исходит от ведущего устройства. Ведомые устройства прослушивают линию связи. Мастер подаёт запрос (посылка, последовательность байт) в линию и переходит в состояние прослушивания линии связи. Ведомое устройство отвечает на запрос, пришедший в его адрес.
Окончание ответной посылки мастер определяет, по временному интервалу между окончанием приёма предыдущего байта и началом приёма следующего. Если этот интервал превысил время, необходимое для приёма двух байт на заданной скорости передачи, приём кадра ответа считается завершённым.
Кадры запроса и ответа по протоколу modbus имеют фиксированный формат, приведённый в (Таблица 1-1).
Таблица 1-1. Кадр посылки Modbus RTU
адрес ведомого устройства | номер функции | данные | CRC |
---|---|---|---|
1 байт |
1 байт |
N < 253 (байт) | 2 байта |
где:
- адрес ведомого устройства — первое однобайтное поле кадра. Оно содержит адрес подчинённого устройства, к которому адресован запрос. Ведомые устройства отвечают только на запросы, поступившие в их адрес. Ответ также начинается с адреса отвечающего ведомого устройства, который может изменяться от 1 до 254. Адрес 0 используется для широковещательной передачи, его распознаёт каждое устройство;
- номер функции — это следующее однобайтное поле кадра. Оно говорит ведомому устройству, какие данные или выполнение какого действия требует от него ведущее устройство;
- данные — поле содержит информацию, необходимую ведомому устройству для выполнения заданной мастером функции или содержит данные, передаваемые ведомым устройством в ответ на запрос ведущего. Длина и формат поля зависит от номера функции;
- CRC — (контрольная сумма) заключительное двухбайтное поле кадра. Контрольная сумма завершает кадры запроса и ответа и применяется для проверки отсутствия ошибок в кадре посылки Modbus RTU.
Следует отметить, что поле CRC записывается младшим байтом вперёд. Алгоритм расчёта CRC может отличаться для разных устройств.
Адресация данных в протоколе Modbus RTU[править | править код]
Все операции с данными привязаны к нулю, каждый вид данных (регистр, выходное/входное значение) начинаются с адреса 0000.
Адресация к ячейке начинается с 1.
Например:
Флаг номер 1 программируемого контроллера имеет адрес 0000 (указывается в поле «Адрес»).
Флаг номер 127 (DEC) имеет адрес 0x007E hex (126 dec) (указывается в поле «Адрес»).
Запоминающий регистр 40001 будет иметь адрес 0000 в поле «Адрес» команды. Потому что код операции уже содержит в себе необходимую информацию об адресе. Операции с этими регистрами имеют смещение Адрес_регистра — 40000 = Значение Используемое В Поле «Адрес». Тип адресации команд в дальнейшем будем помечать т.о.
смещение | обозначение |
-40000 | 4x |
-10000 | 1x |
Запоминающий регистр 40108 будет иметь адрес 006B hex (107 dec)
Контроль ошибок в протоколе Modbus RTU[править | править код]
Во время обмена данными могут возникать ошибки двух типов:
- ошибки, связанные с искажениями при передаче данных;
- логические ошибки.
Ошибки первого типа обнаруживаются при помощи фреймов символов, контроля чётности и циклической контрольной суммы CRC-16-IBM (используется число-полином = 0xA001).
RTU фрейм[править | править код]
В RTU режиме сообщение начинается с интервала тишины равного времени передачи 3.5 символов при данной скорости передачи в сети. Первым полем затем передается адрес устройства.
Вслед за последним передаваемым символом также следует интервал тишины продолжительностью не менее 3.5 символов. Новое сообщение может начинаться после этого интервала.
Фрейм сообщения передается непрерывно. Если интервал тишины продолжительностью 1.5 возник во время передачи фрейма, принимающее устройство заканчивает прием сообщения и следующий байт будет воспринят как начало следующего сообщения.
Таким образом, если новое сообщение начнется раньше 3.5 интервала, принимающее устройство воспримет его как продолжение предыдущего сообщения. В этом случае устанавливается ошибка, так как будет несовпадение контрольных сумм.
Логические ошибки[править | править код]
Для сообщений об ошибках второго типа протокол Modbus RTU предусматривает, что устройства могут отсылать ответы, свидетельствующие об ошибочной ситуации. Признаком того, что ответ содержит сообщение об ошибке, является установленный старший бит кода команды. Пример кадра при выявлении ошибки ведомым устройством, в ответ на запрос приведён в (Таблица 2-1).
1. Если Slave принимает корректный запрос и может его нормально обработать, то возвращает нормальный ответ.
2. Если Slave не принимает какого либо значения, никакого ответа не отправляется. Master диагностирует ошибку по таймауту.
3. Если Slave принимает запрос, но обнаруживает ошибку (parity, LRC, or CRC), никакого ответа не отправляется. Master диагностирует ошибку по таймауту.
4. Если Slave принимает запрос, но не может его обработать (обращение к несуществующему регистру и т.д.), отправляется ответ содержащий в себе данные об ошибке.
Таблица 2-1. Кадр ответа (Slave→Master) при возникновении ошибки modbus RTU
Направление передачи | адрес подчинённого устройства | номер функции | данные (или код ошибки) | CRC |
---|---|---|---|---|
Запрос (Master→Slave) |
0x01 |
0x77 |
0xDD |
0xC7 0xA9 |
Ответ (Slave→Master) |
0x01 |
0xF7 |
0xEE |
0xE6 0x7C |
Стандартные коды ошибок[править | править код]
01 Принятый код функции не может быть обработан на подчиненном. 02 Адрес данных указанный в запросе не доступен данному подчиненному. 03 Величина содержащаяся в поле данных запроса является не допустимой величиной для подчиненного. 04 Невосстанавливаемая ошибка имела место пока подчиненный пытался выполнить затребованное действие. 05 Подчиненный принял запрос и обрабатывает его, но это требует много времени. Этот ответ предохраняет главного от генерации ошибки таймаута. 06 Подчиненный занят обработкой команды. Главный должен повторить сообщение позже, когда подчиненный освободится. 07 Подчиненный не может выполнить программную функцию, принятую в запросе. Этот код возвращается для неудачного программного запроса, использующего функции с номерами 13 или 14. Главный должен запросить диагностическую информацию или информацию об ошибках с подчиненного. 08 Подчиненный пытается читать расширенную память, но обнаружил ошибку паритета. Главный может повторить запрос, но обычно в таких случаях требуется ремонт.
Стандартные коды функций протокола Modbus[править | править код]
В протокол Modbus можно выделить несколько подмножеств команд ( Таблица 3-1).
Таблица 3-1
Подмножество команд | Диапазон кодов команд |
---|---|
Стандартные команды |
1-21 |
Резерв для расширенных функций |
22-64 |
Пользовательские |
65-119 |
Резерв для внутренних нужд |
120-255 |
0x10 Preset Multiple Registers (Установка значений в несколько регистров)[править | править код]
Тип адресации 4x
Значения регистров передаются в линию начиная с указанного адреса, следующие значения регистров передаются после него (см. поле «Данные»).
Ниже приведены примеры команда ведущего устройства (таблица 3-2) и ответ ведомого (таблица 3-3):
Таблица 3-2. Пример установки значения в один регистр
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Кол. регистров ст. байт | 05 Кол. регистров мл. байт | 06 Кол. байт | 07 Данные ст. байт | 08 Данные мл. байт | 09 CRC мл. байт | 10 CRC ст. байт |
---|---|---|---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x10 |
0x00 |
0x01 |
0x00 |
0x01 |
0x02 |
0xFF |
0xFF |
0xA6 |
0x31 |
Таблица 3-3.Ответ на команду установки значения в один регистр
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Кол. регистров ст. байт | 05 Кол. регистров мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x10 |
0x00 |
0x01 |
0x00 |
0x01 |
0x50 |
0x09 |
0x03 Read Holding Registers (Чтение значений из нескольких регистров)[править | править код]
Тип адресации 4x
Ниже приведены примеры команда ведущего устройства (таблица 3-4) и ответ ведомого (таблица 3-5):
Таблица 3-4. Пример чтения значения из одного регистра
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Кол. регистров ст. байт | 05 Кол. регистров мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x03 |
0x00 |
0x01 |
0x00 |
0x01 |
0xD5 |
0xCA |
Значения регистров передаются в линию начиная с указанного адреса, следующие значения регистров передаются после него (см. поле «Данные»).
Таблица 3-5. Ответ на команду чтения значения из одного регистра
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Кол. Байт | 03 Данные ст. байт | 04 Данные мл. байт | 05 CRC мл. байт | 06 CRC ст. байт |
---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x03 |
0x02 |
0xFF |
0xFF |
0xB9 |
0xF4 |
0x06 Preset Single Register (Установка значения в один регистр)[править | править код]
Тип адресации 4x
Ниже приведены примеры команда ведущего устройства (таблица 3-2) и ответ ведомого (таблица 3-3):
Таблица 3-6. Пример установки значения в один регистр
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Данные ст. байт | 05 Данные мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x06 |
0x00 |
0x01 |
0xFF |
0xFF |
0xD9 |
0xBA |
Таблица 3-7. Ответ на команду установки значения в один регистр
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Данные ст. байт | 05 Данные мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x06 |
0x00 |
0x01 |
0xFF |
0xFF |
0xD9 |
0xBA |
0x01 Read Coil Status (Чтение значений из нескольких регистров флагов)[править | править код]
Тип адресации 0x
Запрос:
Состоит из адреса флага и количества считываемых флагов. Адресация флагов начинается с 0, количество флагов с 1.
Ответ:
Значение флагов передается в одном бите в поле «Данные». Трактовка флагов: 1 = ON; 0 = OFF. 0-й бит первого байта данных содержит значение флага указанного в поле «Адрес». Если запросить состояние одного флага, то в младшем бите будет возвращено значение флага, а все остальные старшие биты заполнены нулями.
Ниже приведены примеры запроса ведущего устройства (таблица 3-6) и ответ ведомого (таблица 3-7). В примере запрашивается состояние 9 флагов с адреса 1. В ответе содержится 2 байта данных, для большей ясности будем считать что все запрашиваемые флаги находятся в состоянии ON, а все остальные в состоянии OFF.
Таблица 3-8. Пример чтения значения из одного регистра флагов
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Кол. флагов ст. байт | 05 Кол. флагов мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x01 |
0x00 |
0x01 |
0x00 |
0x09 |
0x |
0x |
Таблица 3-9. Пример ответа на запрос чтения значения из одного регистра флагов
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Количество байт | 03 Данные (флаги 0-7) | 04 Данные (флаги 8-15) | 05 CRC мл. байт | 06 CRC ст. байт |
---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x01 |
0x02 |
0xFF |
0x01 |
0x |
0x |
0x0F Force Multiple Coils (Запись значений в несколько регистров флагов)[править | править код]
Тип адресации 0x
Команда:
Состоит из адреса флага, количества изменяемых флагов, количества передаваемых байт устанавливаемых значений. Адресация флагов начинается с 0, количество флагов с 1. Устанавливаемые значения передаются начиная с байта, в котором находится младшим битом значение, устанавливаемое по адресу указываемому в поле «00 адрес подчиненного устройства».
Ответ:
Состоит из начального адреса флага и количества записанных флагов. Адресация флагов начинается с 0, количество флагов с 1.
Ниже приведены примеры команды ведущего устройства (таблица 3-6) и ответ ведомого (таблица 3-7).
Таблица 3-7. Пример команды записи значения в один из регистр флагов
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Количество флагов ст. байт | 05 Количество флагов мл. байт | 06 Количество байт данных | 07 Данные (значения для флагов биты 0-7) | 08 Данные (значения для флагов биты 8-15) | 09 CRC мл. байт | 0A CRC ст. байт |
---|---|---|---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x0F |
0x00 |
0x13 |
0x00 |
0x0A |
0x02 |
0xCD |
0x01 |
0x72 |
0xCB |
Таблица 3-7. Пример команды записи значения в один из регистр флагов
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Количество флагов ст. байт | 05 Количество флагов мл. байт | 05 CRC мл. байт | 06 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x0F |
0x00 |
0x13 |
0x00 |
0x0A |
0x24 |
0x09 |
0x05 Force Single Coil (Запись значения в один флаг регистра флагов)[править | править код]
Команда:
Состоит из адреса флага и устанавливаемого значения. Поле «Значение флага мл. байт» всегда равно нулю (0x00), поле «Значение флага ст. байт» принимает значения 0xFF если флаг устанавливается в «1»(ON) или 0x00 если флаг устанавливается в «0»(OFF), другие значения недопустимы и не влияют на значение флага. Адресация флагов начинается с 0.
Ответ:
Состоит из начального адреса флага и количества записанных флагов. Адресация флагов начинается с 0, количество флагов с 1.
Ниже приведены примеры команды ведущего устройства (таблица 3-6) и ответ ведомого (таблица 3-7).
Таблица 4-4. Пример: команда установки значения в один флаг
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Значение флага ст. байт | 05 Значение флага мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x05 |
0x00 |
0x13 |
0xFF |
0x00 |
0x7D |
0xFF |
Таблица 4-4. Пример: Ответ на команду установки значения в один флаг
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Адрес ст. байт | 03 Адрес мл. байт | 04 Значение флага ст. байт | 05 Значение флага мл. байт | 06 CRC мл. байт | 07 CRC ст. байт |
---|---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x05 |
0x00 |
0x13 |
0xFF |
0x00 |
0x7D |
0xFF |
0x50 Set date and time (Установка даты и времени)[править | править код]
Ниже приведены примеры команда ведущего устройства (таблица 5-4) и ответ ведомого (таблица 5-5):
Таблица 5-4. Пример установки даты и времени
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Час [0..23] | 03 Минута [0..59] | 04 Секунды [0..59] | 05 День [1..31] | 06 Месяц [1..12] | 07 Год [0..99] | 08 Столетие [19-20] | 09 CRC мл. байт | 10 CRC ст. байт |
---|---|---|---|---|---|---|---|---|---|---|---|
Master→Slave |
0x01 |
0x50 |
0x0A |
0x01 |
0x00 |
0x01 |
0x0A |
0x02 |
0x14 |
0x89 |
0x1C |
Таблица 5-5. Ответ на команду установки даты и времени
Направление передачи | 00 адрес подчиненного устройства | 01 номер функции | 02 Час [0..23] | 03 Минута [0..59] | 04 Секунды [0..59] | 05 День [1..31] | 06 Месяц [1..12] | 07 Год [0..99] | 08 Столетие [19-20] | 09 CRC мл. байт | 10 CRC ст. байт |
---|---|---|---|---|---|---|---|---|---|---|---|
Slave→Master |
0x01 |
0x50 |
0x0A |
0x01 |
0x00 |
0x01 |
0x0A |
0x02 |
0x14 |
0x89 |
0x1C |
Ссылки на используемые в статье источники[править | править код]
- Modbus-IDA некоммерческая организация, которая поддерживает данный протокол
- Оригинальные спецификации протокола на английском языке
- Введение в Modbus протокол
- Описание стандартного описания протокола ModBus на английском языке
- Реализация протокола Modicon Modbus RTU (Комплекс программ «ЗОНД»)
- Linux C Programming Examples
- Как Modbus работает
- Программа испытания Modbus Simply Modbus
- Site for software developers which develop, test modbus protocol in drivers, devices, PLC etc.
- FreeModbus ASCII/RTU и tcp для microcontrollers
- Бесплатное программа для теста устройств Modbus RTU
- форум по настройки Modbus