|
|
(не показано 148 промежуточных версий 11 участников) |
Строка 1: |
Строка 1: |
| <languages/>
| | Для управления WB-MR14 используется протокол Modbus с открытой спецификацией. Это протокол прикладного (седьмого) уровня модели [https://ru.wikipedia.org/wiki/%D0%A1%D0%B5%D1%82%D0%B5%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_OSI OSI], он служит для обмена данными, чаще всего между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)". |
| <translate>
| |
| {{DISPLAYTITLE: Протокол Modbus}}
| |
|
| |
|
| ==Основные понятия== <!--T:1-->
| | В устройствах Wirenboard данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется. |
| {{YouTube
| |
| |link= https://youtu.be/d_olK15Xhkw
| |
| |text= Всё о Modbus и модулях Wiren Board
| |
| }}
| |
|
| |
|
| <!--T:2-->
| |
| Modbus - это протокол, который служит для обмена данными между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)".
| |
|
| |
| <!--T:3-->
| |
| В устройствах Wiren Board данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети (кроме ведущего см. далее) имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется.
| |
|
| |
| <!--T:4-->
| |
| Существует две спецификации протокола: Modbus RTU и Modbus ASCII. В Modbus RTU передается 11-битный символ, состоящий из 1 стартового бита, 8 бит данных (начиная с младшего бита), бит четности (необязателен) и 2 стоповых бита - если бит четности не передается, или 1 стоповый бит - если бит четности передается. Такой символ передает 1 байт данных. В устройствах Wiren Board по умолчанию бит контроля четности не передается и используется 2 стоповых бита. В Modbus ASCII каждый байт передается двумя символами, представляющими ASCII-коды младшей и старшей четырехбитной группы байта ([http://www.simplymodbus.ca/ASCII.htm пример]). Modbus RTU передает больше информации при той же скорости последовательной линии, и в устройствах Wiren Board используется именно он. Все дальнейшее описание относится к Modbus RTU.
| |
|
| |
| <!--T:5-->
| |
| Ведущее устройство ("мастер", или "клиент") периодически опрашивает "ведомое", или "сервер". Ведущее устройство не имеет адреса, передача сообщений от устройства-сервера ведущему без запроса ведущего в протоколе не предусмотрена. | | Ведущее устройство ("мастер", или "клиент") периодически опрашивает "ведомое", или "сервер". Ведущее устройство не имеет адреса, передача сообщений от устройства-сервера ведущему без запроса ведущего в протоколе не предусмотрена. |
|
| |
|
| <!--T:6-->
| | [[Файл:Modbus_Datagram.png|900px|thumb|left|Датаграмма Modbus в общем виде]] |
| [[File:Modbus_Datagram.png|700px|thumb|right|Датаграмма Modbus в общем виде]] | |
|
| |
|
| <!--T:7-->
| | Пакет данных Modbus выглядит, как это показано на рисунке. '''PDU''' (Protocol Data Unit) — общая часть пакета MODBUS, включающая код функции и данные пакета. '''ADU''' (Application Data Unit) — полный пакет MODBUS. Включает в себя специфичную для физического уровня часть пакета и PDU. Для последовательных линий в заголовке ADU передается адрес устройства, а в конце — контрольная сумма CRC16. Максимальный размер ADU в последовательных коммуникационных линиях составляет '''253 байта''' (из максимальных, разрешенных спецификацией 256 байт вычитается 1 байт адреса и два байта контрольной суммы). Для справки — в Modbus TCP максимальная длина пакета составляет 260 байт. |
| Пакет данных Modbus выглядит, как это показано на рисунке. '''PDU''' (Protocol Data Unit) — общая часть пакета MODBUS, включающая код функции и данные пакета. '''ADU''' (Application Data Unit) — полный пакет MODBUS. Включает в себя специфичную для физического уровня часть пакета и PDU. Для последовательных линий в заголовке ADU передается адрес устройства, а в конце — контрольная сумма CRC16. Максимальный размер PDU в последовательных коммуникационных линиях составляет '''253 байта''' (из максимальных, разрешенных спецификацией 256 байт вычитается 1 байт адреса и два байта контрольной суммы). Для справки — в Modbus TCP максимальная длина пакета составляет 260 байт. | |
|
| |
|
|
| |
|
| <!--T:8-->
| |
| Функция кодируется одним байтом и определяет, какое действие должно выполнить устройство-сервер. Значение кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках со стороны устройства-сервера. Код 0 не используется. Размер блока данных может варьироваться от нуля до максимально допустимого. Если обработка запроса прошла без ошибок, то устройство-сервер возвращает пакет ADU, содержащий запрошенные данные. | | Функция кодируется одним байтом и определяет, какое действие должно выполнить устройство-сервер. Значение кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках со стороны устройства-сервера. Код 0 не используется. Размер блока данных может варьироваться от нуля до максимально допустимого. Если обработка запроса прошла без ошибок, то устройство-сервер возвращает пакет ADU, содержащий запрошенные данные. |
|
| |
|
| <gallery mode="packed" heights="300px">
| | [[Файл:Modbus_transaction_OK.png|700px|thumb|center|Modbus-транзакция, прошедшая без ошибок]] |
| File:Modbus_transaction_OK.png|700px|thumb|center|Modbus-транзакция, прошедшая без ошибок
| |
| File:Modbus_transaction_ERR.png|700px|thumb|center|Modbus-транзакция с ошибками
| |
| </gallery>
| |
| <!--T:10-->
| |
|
| |
|
| При возникновении ошибки устройством возвращается код ошибки. При обычной транзакции код функции в ответе возвращается без изменений; при ошибке старший бит кода функции устанавливается в единицу (то есть ''код функции'' + 0x80). Так же есть таймаут ожидания ответа от ведомого устройства — бессмысленно долго ждать ответ, который, возможно, никогда и не придет.
| | ---- |
|
| |
|
| ==Структуры данных Modbus== <!--T:14-->
| | При возникновении ошибки устройством возвращается код ошибки. В случае обычной транзакции код функции в ответе возвращается без изменений; в случае ошибки старший бит кода функции устанавливается в единицу (то есть ''код функции'' + 0x80) |
|
| |
|
| <!--T:15-->
| | [[Файл:Modbus_transaction_ERR.png|700px|thumb|center|Modbus-транзакция с ошибками]] |
| В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой (float), текстовых строк, даты и времени суток и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства.
| |
|
| |
|
| ==Модель данных Modbus== <!--T:16-->
| | ---- |
| | Ответ от ведомого устройства должен прийти в течение заданного таймаута — бессмысленно ждать ответ, который, возможно, никогда и не придет. |
|
| |
|
| <!--T:17-->
| | ===Структуры данных Modbus=== |
| | В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой, строк и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства. |
| | |
| | ===Модель данных Modbus=== |
| Обмен данными с Modbus-устройствами происходит через регистры. В протоколе Modbus определяется четыре типа регистров, показанных в таблице: | | Обмен данными с Modbus-устройствами происходит через регистры. В протоколе Modbus определяется четыре типа регистров, показанных в таблице: |
| {|class="wikitable" align="center" | | {|class="wikitable" align="center" |
| ! Таблица || Размер || Доступ | | ! Таблица || Размер || Тип доступа |
| |- | | |- |
| ! Регистры флагов (Coils) | | ! Регистры флагов (Coils) |
Строка 64: |
Строка 44: |
| |} | | |} |
|
| |
|
| <!--T:18-->
| | '''Регистры флагов'''(Coils) хранят однобитные значения - то есть могут находится в состоянии 0 или 1. Такие регистры могут обозначать текущее состояние выхода (включено реле). Название "coil" буквально и означает обмотку-актюатор электромеханического реле. Регистры флагов допускают как чтение, так и запись. |
| '''Регистры флагов''' (Coils) хранят однобитные значения - то есть могут находится в состоянии 0 или 1. Такие регистры могут обозначать текущее состояние выхода (включено реле). Название "coil" буквально и означает обмотку-актюатор электромеханического реле. Регистры флагов допускают как чтение, так и запись. | |
|
| |
|
| <!--T:19-->
| | '''Дискретные входы''' (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например подано напряжение -- 1). Эти регистры поддерживают только чтение. |
| '''Дискретные входы''' (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например, подано напряжение — 1). Эти регистры поддерживают только чтение. | |
|
| |
|
| <!--T:20-->
| | '''Регистры хранения''' (Holding Registers) и '''регистры ввода''' (Input Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 -- 0xFFFFF). |
| '''Регистры хранения''' (Holding Registers) и '''регистры ввода''' (Input Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 — 0xFFFF). | |
| Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства. | | Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства. |
|
| |
|
| == Адреса регистров == | | ===Адреса и номера регистров=== |
| Регистры в стандарте Modbus адресуются с помощью 16-битных адресов. Адресация начинается с нуля. Адрес регистра, таким образом, может принимать значения от 0 до 65535.
| |
| | |
| Адресные пространства регистров, также называемые таблицами или блоками, могут быть различны для всех четырёх типов регистров. Это значит, что значения регистров с одинаковым адресом, но разным типом, в общем случае разные.
| |
| | |
| Например, при чтении регистра флагов (coil) номер 42, регистра дискретного входа (Discrete), регистров ввода и хранения (Input и Holding) с теми же адресами, можно получить четыре разных значения.
| |
| | |
| === Нестандартная адресация ===
| |
| В документации на некоторые, особенно старые, устройства адреса элементов (регистров) указываются в формате, не соответствующем стандарту. В этом формате тип элемента кодируется первой цифрой адреса, а адресация начинается не с нуля.
| |
| | |
| Например, регистр хранения с адресом 0 может записываться как 40001 или 400001, а Coil с адресом 0 как 000001.
| |
| | |
| В таблице перевода адресов в стандартный формат показаны диапазоны для двух разных нестандартных типов указания адресов и соответствующие им типы данных и диапазоны стандартных адресов.
| |
| | |
| {|class="wikitable" align="center"
| |
| ! Тип данных || Стандартные адреса || Стандартные адреса (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
| |
| | |
| Часто рядом с нестандартными адресами указываются и адреса соответствующие стандарту, обычно в шестнадцатеричном формате.
| |
| Стоит отметить, что физически в пакете данных передаются адреса в стандартном формате, независимо от способа представления их в документации.
| |
| | |
| === Пример описания регистров в документации ===
| |
| <!--T:26-->
| |
| В готовых шаблонах устройств для контроллера Wiren Board есть шаблон для однофазного счетчика электроэнергии SDM220 (/usr/share/wb-mqtt-serial/templates/config-sdm220.json). В документации от производителя "Eastron SDM
| |
| 220 Modbus Smart Meter Modbus Protocol Implementation V1.0" перечислены регистры и соответствующие им измеряемые параметры, например:
| |
| | |
| <!--T:27-->
| |
| {|class="wikitable" align="center"
| |
| ! 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
| |
| |-
| |
| ! ...
| |
| | ... || ... || ... ...
| |
| | |
| <!--T:28-->
| |
| |}
| |
| | |
| <!--T:29-->
| |
| Производитель в таблице приводит и логические, и физические адреса регистров, что позволяет нам с легкостью создать шаблон устройства и проиллюстрировать связь между логическими и физическими адресами Modbus-регистров.
| |
| | |
| <!--T:30-->
| |
| [[File:SDM220_Template.png|700px|thumb|center|Фрагмент шаблона счетчика SDM220]]
| |
| | |
| === Коды функций чтения и записи регистров === <!--T:31-->
| |
| | |
| <!--T:32-->
| |
| В следующей таблице приведены наиболее распространенные коды функций Modbus:
| |
| | |
| <!--T:33-->
| |
| {|class="wikitable" align="center"
| |
| !Код функции || 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 || Запись нескольких регистров хранения
| |
| |-
| |
| |}
| |
| | |
| <!--T:34-->
| |
| Команды условно можно разделить по типам: чтение значений — запись значений; операция с одним значением — операция с несколькими значениями.
| |
| | |
| === Формат данных запросов и ответов Modbus === <!--T:35-->
| |
| | |
| <!--T:36-->
| |
| Рассмотрим подробнее, как происходит обмен данными между устройством-клиентом, отправляющим запрос, и устройством-сервером, отвечающим ему.
| |
| На следующем рисунке показан обмен данными контроллера с устройством с адресом 0x01. Мы хотим прочесть 8 coil-регистров, начиная с первого.
| |
| [[File:Read_8_Coils_2.png|600px|thumb|center|Обмен данными в Modbus]]
| |
| | |
| <!--T:37-->
| |
| В качестве данных мы получили шестнадцатеричное число 0x2D, то есть состояние восьми coil-регистров в двоичном виде такое: 0b10110100.
| |
| | |
| <!--T:38-->
| |
| ----
| |
| | |
| <!--T:39-->
| |
| В следующей таблице приведены структуры данных запросов и ответов для основных функций Modbus.
| |
| | |
| <!--T:40-->
| |
| {|class="wikitable" align="center"
| |
| !Код функции || Запрос || Ответ
| |
| |-
| |
| ! 1 (Read Coils) и 2 (Read Discrete Inputs)
| |
| |<ul><li>Адрес первого регистра флагов или входного регистра (16 бит)</li><li>Количество данных (8 значений на байт) (16 бит)</li><ul>|| <ul><li>Число передаваемых байт (8 бит)</li><li>Значения регистров флагов или входных регистров (8 значений на байт)</li></ul>
| |
| |-
| |
| ! 3 (Read Holding Registers) и 4 (Read Input Registers)
| |
| |<ul><li>Адрес первого регистра (16 бит)</li><li>Количество регистров, которые нужно прочесть</li><ul>|| <ul><li>Число передаваемых байт (8 бит)</li><li>Значения регистров (16 бит на 1 регистр)</li></ul>
| |
| |-
| |
| ! 5 (Write Single Coil)
| |
| |<ul><li>Адрес регистра (16 бит)</li><li>Значение, которое нужно записать (0 — выключить, 0xFF00 — включить)</li><ul>|| Ответ аналогичен запросу
| |
| |-
| |
| ! 6 (WriteSingle Register)
| |
| |<ul><li>Адрес регистра(16 бит)</li><li>Новое значение регистра (16 бит)</li></ul>|| Ответ аналогичен запросу
| |
| |-
| |
| ! 15 (WriteMultipleCoils)
| |
| | <ul><li>Адрес первого регистра флагов для записи (16 бит)</li><li>Количество регистров флагов для записи (16 бит)</li><li>Количество передаваемых байт данных для регистров флагов (8 бит)</li><li>Данные (8 регистров флагов на байт)</li></ul> || <ul><li>Адрес первого coil-регистра (16 бит)</li><li>Количество записанных coil-регистров(16 бит)</li></ul>
| |
| |-
| |
| ! 16 (Write Multiple register )
| |
| | <ul><li>Адрес первого регистра хранения для записи (16 бит)</li><li>Количество регистров хранения для записи (16 бит)</li><li>Количество передаваемых байт данных для регистров (8 бит)</li><li>Данные (16 байт на регистр)</li></ul> || <ul><li>Адрес первого регистра хранения (16 бит)</li><li>Количество записанных регистров хранения(16 бит)</li></ul>
| |
| |-
| |
| |}
| |
| | |
| | |
| === Коды исключений (ошибки) Modbus === <!--T:41-->
| |
| | |
| <!--T:42-->
| |
| Если запрос не может по той или иной причине быть обработан устройством-сервером, то в ответ он отправляет сообщение об ошибке. Соообщение об ошибке содержит адрес Modbus-устройства, код функции, при выполнении которой произошла ошибка, увеличенный на 0x80, код ошибки и контрольную сумму:
| |
| | |
| <!--T:43-->
| |
| [[File:Read_8_Coils_ERR.png|600px|thumb|center|Транзакция завершилась с ошибкой]]
| |
| В этом случае мы попытались обратиться к несуществующему адресу регистра 0xFFFF и попытались прочесть 8 регистров флагов. В результате мы получили код ошибки 0x03 — "В поле данных передано неверное значение".
| |
| | |
| <!--T:44-->
| |
| Наиболее распространенные коды ошибок Modbus приведены в следующей таблице:
| |
| | |
| <!--T:45-->
| |
| {|class="wikitable" align="center"
| |
| !Код ошибки || Название ошибки|| Что означает
| |
| |-
| |
| ! 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 === <!--T:46-->
| |
| | |
| <!--T:47-->
| |
| Для протокола Modbus RTU 16-битная контрольная сумма (CRC) вычисляется по алгоритму, описанному в [http://www.modbus.org/specs.php спецификации Modbus], в документе "Modbus Serial Line Protocol and Implementation Guide", раздел "CRC-generation". Передающее устройство формирует два байта контрольной суммы на основе данных сообщения, а принимающее устройство заново вычисляет контрольную сумму и сравнивает с полученной. Совпадение принятой и вычисленной контрольной суммы Modbus RTU считается индикатором успешного обмена данными.
| |
| | |
| <!--T:48-->
| |
| В случае ограниченных вычислительных ресурсов для вычисления контрольной суммы существует функция, использующая табличные значения (также приведена в спецификации).
| |
| | |
| == Расширение протокола Modbus от Wiren Board ==
| |
| {{Anchor|modbus-ext}}
| |
| Мы производим устройства, которые работают по стандартному протоколу Modbus RTU. Но протокол очень старый и имеет ряд недостатков, которые мы решили устранить.
| |
| | |
| Мы добавили к стандартному протоколу новые функции: настраиваемое время задержки, игнорирование стопбитов и режим сплошного чтения регистров.
| |
| | |
| Также выпустили расширение протокола под названием «Быстрый Modbus». В нем появились события и быстрое сканирование устройств на шине RS-485.
| |
| | |
| Ниже описаны новые функции, а про расширение «Быстрый Modbus» читайте на [[Fast_Modbus |странице с описанием]].
| |
| | |
| Всё описываемое справедливо только для Modbus-устройств Wiren Board.
| |
| | |
| === Настраиваемое время задержки ответа устройством ===
| |
| Устройства работают по стандарту, поэтому отвечают master-устройству через 3.5 символа после конца кадра запроса.
| |
| | |
| Но некоторые сторонние master-устройства могут не соблюдать стандарт и после отправки запроса продолжают удерживать приемопередатчик в режиме отправки некоторое время.
| |
| | |
| В устройствах есть специальный регистр 113, в котором можно настроить время ответа slave-устройства в миллисекундах. Нужное значение подбирается опытным путём.
| |
| | |
| === Игнорирование стопбитов ===
| |
| Устройства всегда ожидают от мастера 1 стопбит, а отправляют ответ с 2.
| |
| | |
| Благодаря этому невозможно неправильно настроить стопбиты в master- и в slave-устройстве. Передача ответов более надежная даже, если мастер ожидает 1 стопбит. В последних прошивках настройка стопбита в регистре 112 игнорируется.
| |
| | |
| === Режим сплошного чтения регистров ===
| |
| | |
| Часто на устройствах регистры расположены с зазором, который не позволяет читать все необходимые регистры подряд одной командой.
| |
| | |
| Мы добавили режим сплошного чтения, который активируется записью 1 в регистр 114. При активации можно запрашивать любой регион, который укладывается по длине в ограничения команды чтения.
| |
| | |
| При таком запросе устройство вернёт пакет со значением регистров. Если регистры отсутствуют в устройстве, то для них будет возвращено значение 0xFFFE.
| |
| | |
| </translate>
| |
Для управления WB-MR14 используется протокол Modbus с открытой спецификацией. Это протокол прикладного (седьмого) уровня модели OSI, он служит для обмена данными, чаще всего между устройствами автоматизации и реализован в виде "протокола ответов на запросы (request-reply protocol)".
В устройствах Wirenboard данные Modbus передаются по последовательным линиям связи RS-485. В последовательных линиях связи протокол RS-485 полудуплексный и работает по принципу «клиент-сервер». Каждое устройство в сети имеет адрес от 1 до 247, адрес 0 используется для широковещательной передачи данных всем устройствам, а адреса 248–255 считаются зарезервированными согласно спецификации Modbus, их использование не рекомендуется.
Ведущее устройство ("мастер", или "клиент") периодически опрашивает "ведомое", или "сервер". Ведущее устройство не имеет адреса, передача сообщений от устройства-сервера ведущему без запроса ведущего в протоколе не предусмотрена.
Датаграмма Modbus в общем виде
Пакет данных Modbus выглядит, как это показано на рисунке. PDU (Protocol Data Unit) — общая часть пакета MODBUS, включающая код функции и данные пакета. ADU (Application Data Unit) — полный пакет MODBUS. Включает в себя специфичную для физического уровня часть пакета и PDU. Для последовательных линий в заголовке ADU передается адрес устройства, а в конце — контрольная сумма CRC16. Максимальный размер ADU в последовательных коммуникационных линиях составляет 253 байта (из максимальных, разрешенных спецификацией 256 байт вычитается 1 байт адреса и два байта контрольной суммы). Для справки — в Modbus TCP максимальная длина пакета составляет 260 байт.
Функция кодируется одним байтом и определяет, какое действие должно выполнить устройство-сервер. Значение кодов функций лежат в диапазоне от 1 до 255, причем коды от 128 до 255 зарезервированы для сообщений об ошибках со стороны устройства-сервера. Код 0 не используется. Размер блока данных может варьироваться от нуля до максимально допустимого. Если обработка запроса прошла без ошибок, то устройство-сервер возвращает пакет ADU, содержащий запрошенные данные.
Modbus-транзакция, прошедшая без ошибок
При возникновении ошибки устройством возвращается код ошибки. В случае обычной транзакции код функции в ответе возвращается без изменений; в случае ошибки старший бит кода функции устанавливается в единицу (то есть код функции + 0x80)
Modbus-транзакция с ошибками
Ответ от ведомого устройства должен прийти в течение заданного таймаута — бессмысленно ждать ответ, который, возможно, никогда и не придет.
Структуры данных Modbus
В Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой, строк и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства.
Модель данных 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 -- 0xFFFFF).
Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства.
Адреса и номера регистров