Промышленный протокол ModBus. Структура Modbus RTU сообщения

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Первоначально контроллеры MODICON использовали последовательный интерфейс RS-232. Позднее стал применяться интерфейс RS-485, так как он обеспечивает более высокую надёжность, позволяет использовать более длинные линии связи и подключать к одной линии несколько устройств.

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

Введение

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

Обычно в сети есть только один клиент, так называемое, «главное» (англ. master ) устройство, и несколько серверов - «подчиненных» (slaves ) устройств. Главное устройство инициирует транзакции (передаёт запросы). Подчиненные устройства передают запрашиваемые главным устройством данные, или производят запрашиваемые действия. Главный может адресоваться индивидуально к подчиненному или инициировать передачу широковещательного сообщения для всех подчиненных устройств. Подчиненное устройство формирует сообщение и возвращает его в ответ на запрос, адресованный именно ему. При получении широковещательного запроса ответное сообщение не формируется.

Спецификация Modbus описывает структуру запросов и ответов. Их основа - элементарный пакет протокола, так называемый PDU (Protocol Data Unit). Структура PDU не зависит от типа линии связи и включает в себя код функции и поле данных. Код функции кодируется однобайтовым полем и может принимать значения в диапазоне 1...127. Диапазон значений 128...255 зарезервирован для кодов ошибок. Поле данных может быть переменной длины. Размер пакета PDU ограничен 253 байтами.

Modbus PDU
номер функции данные
1 байт N < 253 (байт)

Для передачи пакета по физическим линиям связи PDU помещается в другой пакет, содержащий дополнительные поля. Этот пакет носит название ADU (Application Data Unit). Формат ADU зависит от типа линии связи.

Существуют три основных реализации протокола Modbus, две для передачи данных по последовательным линиям связи, как медным EIA/TIA-232-E (RS-232), EIA-422, EIA/TIA-485-A (RS-485), так и оптическим и радио:

  • Modbus ASCII,

и для передачи данных по сетям Ethernet поверх TCP/IP :

  • Modbus TCP.

Общая структура ADU следующая (в зависимости от реализации, некоторые из полей могут отсутствовать):

  • адрес ведомого устройства - адрес подчинённого устройства, к которому адресован запрос. Ведомые устройства отвечают только на запросы, поступившие в их адрес. Ответ также начинается с адреса отвечающего ведомого устройства, который может изменяться от 1 до 247. Адрес 0 используется для широковещательной передачи, его распознаёт каждое устройство, адреса в диапазоне 248...255 - зарезервированы;
  • номер функции - это следующее однобайтное поле кадра. Оно говорит ведомому устройству, какие данные или выполнение какого действия требует от него ведущее устройство;
  • данные - поле содержит информацию, необходимую ведомому устройству для выполнения заданной мастером функции или содержит данные, передаваемые ведомым устройством в ответ на запрос ведущего. Длина и формат поля зависит от номера функции;
  • блок обнаружения ошибок - контрольная сумма для проверки отсутствия ошибок в кадре.

Максимальный размер ADU для последовательных сетей RS232/RS485 - 256 байт, для сетей TCP - 260 байт.

Для Modbus TCP ADU выглядит следующим образом:

  • ид транзакции - два байта, обычно нули
  • ид протокола - два байта, нули
  • длина пакета - два байта, старший затем младший, длина следующей за этим полем части пакета
  • адрес ведомого устройства - адрес подчинённого устройства, к которому адресован запрос. Обычно игнорируется, если соединение установлено с конкретным устройством. Может использоваться, если соединение установлено с бриджом, который выводит нас, например, в сеть RS485.

Поле контрольной суммы в Modbus TCP отсутствует.

Категории кодов функций

В действующей в настоящее время спецификации протокола определяются три категории кодов функций:

Стандартные команды Их описание должно быть опубликовано и утверждено Modbus-IDA. Эта категория включает в себя как уже определенные, так и свободные в настоящее время коды. Пользовательские команды Два диапазона кодов (от 65 до 72 и от 100 до 110), для которых пользователь может реализовать произвольную функцию. При этом не гарантируется, что какое-то другое устройство не будет использовать тот же самый код для выполнения другой функции. Зарезервированные В эту категорию входят коды функций, не являющиеся стандартными, но уже используемые в устройствах, производимых различными компаниями. Это коды 9, 10, 13, 14, 41, 42, 90, 91, 125, 126 и 127.

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

Одно из типичных применений протокола - чтение и запись данных в регистры контроллеров. Спецификация протокола определяет четыре таблицы данных:

Доступ к элементам в каждой таблице осуществляется с помощью 16-битного адреса, первой ячейке соответствует адрес 0. Таким образом, каждая таблица может содержать до 65536 элементов. Спецификация не определяет, что физически должны представлять собой элементы таблиц и по каким внутренним адресам устройства они должны быть доступны. Например, допустимо организовать перекрывающиеся таблицы, В этом случае команды работающие с дискретными данными и с 16-битными регистрами будут фактически обращаться к одним и тем же данным.

Следует отметить, что со способом адресации данных связана определённая путаница. Modbus был первоначально разработан для контроллеров Modicon. В этих контроллерах для каждой из таблиц использовалась специальная нумерация. Например, первому регистру ввода соответствовал номер ячейки 30001, а первому регистру хранения - 40001. Таким образом, регистру хранения с адресом 107 в команде Modbus соответствовал регистр № 40108 контроллера. Хотя такое соответствие адресов больше не является частью стандарта, некоторые программные пакеты могут автоматически «корректировать» вводимые пользователем адреса, например, вычитая 40001 из адреса регистра хранения.

Стандартные функции протокола Modbus

PDU запроса и ответа для стандартных функций
номер
функции
запрос/ответ
1 (0x01) A 1 A 0 Q 1 Q 0
N D (N байт)
2 (0x02) A 1 A 0 Q 1 Q 0
N D (N байт)
3 (0x03) A 1 A 0 Q 1 Q 0
N D (N байт)
4 (0x04) A 1 A 0 Q 1 Q 0
N D (N байт)
5 (0x05) A 1 A 0 D 1 D 0
A 1 A 0 D 1 D 0
6 (0x06) A 1 A 0 D 1 D 0
A 1 A 0 D 1 D 0
15 (0x0F) A 1 A 0 Q 1 Q 0 N D (N байт)
A 1 A 0 Q 1 Q 0
16 (0x10) A 1 A 0 Q 1 Q 0 N D (N байт)
A 1 A 0 Q 1 Q 0
  • A 1 и A 0 - адрес элемента,
  • Q 1 и Q 0 - количество элементов,
  • N - количество байт данных
  • D - данные

Чтение данных

Для чтения значений из перечисленных выше таблиц данных используются функции с кодами 1-4 (шестнадцатеричные значения 0x01-0x04):

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

Запрос состоит из адреса первого элемента таблицы, значение которого требуется прочитать, и количества считываемых элементов. Адрес и количество данных задаются 16-битными числами, старший байт каждого из них передается первым.

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

Значения регистров хранения и регистров ввода передаются начиная с указанного адреса, по два байта на регистр, старший байт каждого регистра передаётся первым:

байт 1 байт 2 байт 3 байт 4 ... байт N-1 байт N
R A,1 R A,0 R A+1,1 R A+1,0 ... R A+Q-1,1 R A+Q-1,0

Значения флагов и дискретных входов передаются в упакованном виде: по одному биту на флаг. Единица означает включённое состояние, ноль - выключенное. Значения запрошенных флагов заполняют сначала первый байт, начиная с младшего бита, затем следующие байты, также от младшего бита к старшим. Младший бит первого байта данных содержит значение флага, указанного в поле «адрес». Если запрошено количество флагов, не кратное восьми, то значения лишних битов заполняются нулями:

байт 1 ... байт N
F A+7 F A+6 F A+5 F A+4 F A+3 F A+2 F A+1 F A ... 0 ... 0 F A+Q-1 F A+Q-2 ...

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

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

Команда состоит из адреса элемента (2 байта) и устанавливаемого значения (2 байта).

Для регистра хранения значение является просто 16-битным словом.

Для флагов значение 0xFF00 означает включённое состояние, 0x0000 - выключенное, другие значения недопустимы.

Если команда выполнена успешно, ведомое устройство возвращает копию запроса.

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

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

Команда состоит из адреса элемента, количества изменяемых элементов, количества передаваемых байт устанавливаемых значений и самих устанавливаемых значений. Данные упаковываются так же, как в командах чтения данных.

Ответ состоит из начального адреса и количества изменённых элементов.

Ниже приведён пример команды ведущего устройства и ответа ведомого (для Modbus RTU).

Контроль ошибок в протоколе Modbus RTU

Во время обмена данными могут возникать ошибки двух типов:

  • ошибки, связанные с искажениями при передаче данных;
  • логические ошибки.

Ошибки первого типа обнаруживаются при помощи фреймов символов, контроля чётности и циклической контрольной суммы 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 принимает запрос, но не может его обработать (обращение к несуществующему регистру и т.д.), отправляется ответ содержащий в себе данные об ошибке.

Таблица 2-1. Кадр ответа (Slave→Master) при возникновении ошибки modbus RTU
Направление передачи адрес подчинённого устройства номер функции данные (или код ошибки) CRC

Пришло время рассмотреть еще одну вариацию протокола Modbus Modbus ASCII . Эта версия протокола использует для передачи данных только символы ASCII, которыми кодирует шестнадцатеричное представление бинарных данных. Немного не понятно и запутано? Это ничего, welcome под кат и давайте рассмотрим, с чем же мы имеем дело.

Разделитель пакетов

Первое отличие протокола Modbus ASCII от Modbus RTU – у него есть разделитель между пакетами. Если в Modbus RTU все пакеты шли один за одним (практически, там должна быть небольшая задержка на линии между пакетами, порядка 2-5мс), то в Modbus ASCII каждый новый пакет должен начинаться со специального символа разделителя.

По стандарту Modbus RTU между пакетами нужна задержка в 3.5 символа (это время, которое нужно для передачи 3.5 символов по линии связи, зависит от скорости передачи). Эта задержка используется, что бы детектировать новый запрос от мастера. Т.е. эта задержка указывает начало нового запроса. Но когда стали использовать модемы, это перестало работать. На модеме невозможно выдержать нужное время. Поэтому решили использовать новый вариант протокола — Modbus ASCII . Этот вариант устраняет многие неудобства при работе с модемом: есть специальный символ разделитель пакетов и используются только видимые символы ASCII.

Так вот, таким символом начала пакета служит символ двоеточие с шестнадцатеричным кодом 0x3A . А конец каждого пакета помечается символами новой строки и перевода каретки – 0x0D 0x0A . Таким образом, из протокола полностью убирается зависимость от задержек между байтами. Т.е. если модем задержит байт, это не вызовет недопонимания на стороне клиента. И он будет ждать окончания пакета байтами 0x0D 0x0A . А если встретит символ разделителя 0х3А – сбросит буфер и начнем формировать пакет заново. Кроме того нет необходимости в экранировании спец символов модема, так как данные не используют символы из начальной секции ASCII таблицы.

Представление байтов данных

В Modbus ASCII протоколе каждый байт данных представлен в виде 2 байтов. Каждый байт представляет собой ASCII символ в шестнадцатеричном представлении. Что бы легче было понять, приведем пример:

Немного объяснений для таблицы.

Например, нам нужно передать байт данных, который хранит символ # . Этот символ имеет в таблице ASCII шестнадцатеричный код 0x23 . В протоколе Modbus RTU мы просто передаем байт со значением 0x23 .

Если мы хоти передать тот же символ через протокол Modbus ASCII , нам нужно уже передавать 2 байта. На первом этапе мы получаем шестнадцатеричный код символа, 0x23 . На втором этапе мы кодируем это значение при помощи двух символов ASCII – 2 и 3 . И на третьем этапе мы передаем два байта данных, первый — это шестнадцатеричное значение символа 2 , второй байт — это шестнадцатеричное значение символа 3 .

Таким образом, диапазон значений для байта данных в протоколе Modbus RTU 0 .. 0xFF

Диапазон значений для байта данных в протоколе Modbus ASCII – только символы, необходимые для отображения шестнадцатеричных цифр, т.е. 0 – 9, A, B, C, D, E, F (все заглавные).

Контрольная сумма для Modbus ASCII

В протоколе Modbus RTU используется 2 байтная контрольная сумма, которая помогает детектировать поврежденные запросы. В протоколе Modbus ASCII так же есть контрольная сумма – LRC (Longitudinal Redundancy Check) .

Вычисление LRC намного проще, чем вычисление CRC . Что бы высчитать LRC вам нужно сделать следующие:

  • Сложить вместе все байты в сообщении Modbus ASCII , до того, как они сконвертированы в в символы ASCII. Не включаются в вычисления стартовый символ двоеточия и завершающие символы CR/LF .
  • Обнулить все биты больше 8 (т.е. оставить младший байт)
  • Сделать результирующий байт отрицательным чтобы получить LRC байт

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

Ниже приведен пример вычисления LRC для конкретного запроса Modbus ASCII .

Для примера возьмем запрос на чтение регистров #40108 — #40110 с устройства с адресом 17

Запрос: 11 03 00 6B 00 03
Данные (Десятичные) Данные (HEX) Данные (Двоичные)
17 11 0001 0001
3 03 0000 0011
0 00 0000 0000
107 6B 0110 1011
0 00 0000 0000
3 03 0000 0011

Теперь посчитаем сумму всех байт

Вот это отрицательное число (-130 или 0x7E ) и есть LRC запроса.

Эта контрольная сумма добавляется к запросу в виде 2 ASCII символов – 7 и E .

Т.е. в конце запроса нужно добавить 2 байта со значением 37 и 45 .

Примеры Modbus RTU и Modbus ASCII запросов

Что бы лучше понять, как все это работает, посмотрите пару простых примеров.

Возьмем наш запрос на чтение регистров #40108 — #40110 с устройства с адресом 17

Запрос: 11 03 00 6B 00 03

Это Modbus RTU запрос без последних двух байтов CRC . Теперь преобразуем этот запрос из Modbus RTU в Modbus ASCII . Для этого добавляем в начало запроса символ двоеточия, в конец запроса символ перевода строки и возврата каретки, а каждый байт представим в виде ASCII символов, соответствующих шестнадцатеричному представлению каждого байта запроса. В итоге у нас получиться такой запрос (в виде ASCII символов, или попросту в виде текстовой строки). Так же в конец запроса добавляем LRC .

: 1 1 0 3 0 0 6 B 0 0 0 3 7 E CR LF

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

3A 3131 3033 3030 3642 3030 3033 3745 0D 0A
Индекс байта Значение HEX ASCII Описание
0 3A : Символ начала
1-2 31 31 11 Адрес устройства
3-4 30 33 03 Код команды
5-8 30 30 36 42 00 6B Адрес HOLDING регистра, с которого нужно начинать чтение. В данном случае 0х006B = 107. Но это не адрес, а смещение от адреса 40001. Т.е. реальный адрес = 107+ 40001 = 40108.
9-12 30 30 30 33 00 03 Количество регистров, которые нужно прочитать. 0х0003 = 3. Т.е. читать нужно регистры 40108– 40110.
13 – 14 37 45 7E LRC запроса
15 CR 0D Символ перевода каретки
16 LF 0A Символ новой строки

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Протокол Master/Slave

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

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

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

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

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

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

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

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

Коды функций

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

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

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

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

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

Ограничения

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

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

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

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

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

Адресация данных в Modbus протоколе

Для хранения информации в ведомых устройствах (slave device ) используются 4 таблицы (или массива). Каждая таблица хранит информацию для схожих переменных в регистрах. Каждый регистр имеет свой размер и адрес. Так же регистры могут быть только для чтения, или для чтения – записи. Давайте рассмотрим эти 4 типа данных, которые можно хранить в регистрах:

COILS

Это цифровые выходы (Digital Outputs ). Каждый coil можно записать или считать. Его размер – 1 бит (т.е. 0 или 1). Исторически эти регистры связаны с реальными цифровыми выходами на сенсорах или терминальных устройствах. Цифровые выходы используются для управления, например светодиодами, реле или моторами. Т.е. записывая в такой регистр 1 мы можем включить светодиод, а записав 0 – выключить его (это условно, на самом деле 0 может включать, а 1 – выключать).

При чтении данного регистра мы можем узнать состояние выхода (т.е. включен он или выключен). Результат чтения так же 1 бит, т.е. 1 или 0.

CONTACTS

Это цифровые входы (Digital Inputs ). Цифровой вход можно только читать, т.е считывая данный регистр мы узнаем состояние реального цифрового входа на сенсоре или устройстве. Цифровые входы используются для контроля состояние – например, включен свет или выключен, достигла жидкость нужного уровня или нет, включено реле или нет, и т.д.

ANALOG INPUT REGISTERS

Под этим обычно имеются в виду аналоговые входы (Analog Inputs ). Аналоговые входы можно только читать, т.е их нельзя записывать, а можно только считать текущее состояние налогового входа. Обычно аналоговые входы применяются на сенсорах для измерение некоторых значений: входного тока или входного напряжения. Затем, полученное значение можно конвертировать в некоторую реальную величину, например в температуру, влажность воздуха, давление или еще что то. Для этого используются специальные формулы, которые идут вместе с сенсором. Но чаще сенсор сразу возвращает реальное значение. Например, сенсор измеряющий температуру, может возвращать измеренное значение как градусы по Цельсию умноженные на 10. Т.е. 253 означает 25.3°С. Этот прием часто используется, если нужно вернуть дробные значения через целочисленный регистр.

ANALOG OUTPUT HOLDING REGISTERS

Под этим обычно имеются в виду аналоговые выходы (Analog Outputs ) но так же часто просто регистры, которые хранят некоторые значения, которые можно как записывать, так и считывать. Т.е. эти регистры можно как читать, так и писать. Наиболее часто используются для записи DAC устройств (Digital to Analog Converter) или просто как регистры, хранящие некоторые значения. DAC часто используются для управления чем либо, например: яркостью свечения светодиода, или громкостью сирены, или скоростью вращения двигателя.

Эти регистры 16 битные, т.е. каждый регистр может хранить всего 2 байта.

Вот эти четыре типа регистров поддерживаются в стандартном Modbus . И используя только их, нужно строить систему. Если взглянуть с точки зрения конечного устройства (slave device), то регистры логичнее всего использовать для следующих нужд:

Coils – для управления устройствами через цифровые порты вывода или булевыми флагами типа включен/выключен, открыт / закрыт и т.д.

Contacts – для хранения значений булевых флагов или для отображения информации с цифровых входов.

Inputs –для значений, которые нужно только читать на стороне мастера, и которые могут быть представлены как 16 битные целые числа. Например, входы ADC, или какие о значения, генерируемые системой которые нужно читать (например количество запущенных процессов или внутренняя температура устройства может быть считана через некий Input регистр)

Holding – эти регистры можно использовать для хранения конфигурации устройства, для управления DAC устройствами, для хранения некоторой служебной информации. В принципе, эти регистры можно использовать для чего угодно, на что хватит фантазии разработчика системы.

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

Имя Тип Доступа Адреса Доступно Регистров
Coils Чтение / Запись 1 – 9999 9999
Contacts Чтение 10001 – 19999 9999
Inputs Чтение 30001 – 39999 9999
Holdings Чтение / Запись 40001 – 49999 9999

Как видно из таблицы, каждый тип регистров может вмещать максимум 9999 регистров. Но все они начинаются с некоторого смещения: 0, 10000, 30000, 40000.

На самом деле, внутри команд протокола Modbus , используется не полный адрес, а только его смещение относительно базового адреса. Т.е. для всех типов регистров реальный адрес внутри команды будет 0 -9998. А команда определяет какой именно базовый адрес может быть использован.

Проще всего представить себе, что устройство хранит 4 массива элементов по 9999 элементов в каждом. Индекс внутри массива – это и есть адрес, который задается внутри команды. А команда определяет, какой массив нужно использовать.

Если внимательно посмотреть на таблицу, то видно, что при желании можно использовать больше адресов для Holding регистров: 40001 – 105537, т.е. всего 65535 регистров. То же самое для Contacts : 10001 – 29999, т.е. всего 19999. Это так называемые расширенные регистры. Они не поддерживаются стандартными Modbus устройствами. Поэтому, если вы хотите, что бы ваше устройство могло работать со стандартными клиентами, то не нужно использовать расширенные регистры.

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

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

Адресация Modbus устройств

Для адресации устройств используется специальный идентификатор, который называется Slave Id . Это однобайтное значение, которое определяет уникальный адрес устройства на всей сети Modbus . По стандарту Modbus это может быть число от 1 до 247. Т.е. всего в сети может находиться 247 конечных устройств (slave device) с уникальными адресами.

Когда мастер посылает команду в сеть, первый байт – это Slave Id . Это позволяет устройствам уже после первого байта определить, должны они обрабатывать команду, или могут ее проигнорировать. Это справедливо для Modbus RTU . Для Modbus TCP протокола используется Unit Id значение. Хотя если разобраться, это просто другое название Slave Id . Unit Id – это так же однобайтный адрес устройства, от 1 до 247.

Это очень сильно ограничивает количество устройств, которые одновременно могут находиться в сети. Поэтому есть вариант, когда используется 2 байта для адресации устройств. В таком случае количество устройств увеличивается до 65535. Этого более чем достаточно. Но есть одно условие. Мастер и Конечное устройство должны использовать 2 байте для адресации. Т.е. они должны быть настроены, что бы использовать одинаковую схему адресации устройств: 1 или 2 байта. Так же, все устройства в сети должны использовать ту же самую схему адресации – 1 или 2 байта. Не может быть в сети устройств с разной схемой адресации.

Функции Modbus

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

Код Функции Тип Действия Описание
01 (01 hex) Чтение Читает значение Coil регистра
02 (02 hex) Чтение Читает значение Contact регистра
03 (03 hex) Чтение Читает значение Holding регистра
04 (04 hex) Чтение Читает значение Input регистра
05 (05 hex) Запись одного регистра Записывает значение в Coil регистр
06 (06 hex) Запись одного регистра Записывает значение в Holding регистр
15 (0F hex) Запись нескольких регистров Записывает значение в несколько Coil регистров
16 (10 hex) Запись нескольких регистров Записывает значение в несколько Holding регистров

Каждая функция будет рассмотрена позже, подробно и с примерами.

CRC 16 как способ избежать ошибок

Каждая команда в Modbus RTU протоколе заканчивается двумя байтами, которые содержать CRC16 значение всех байт команды. Добавление CRC16 позволяет найти поврежденные запросы и игнорировать их. Так как для вычисления контрольной суммы используется каждый байт в команде, то даже изменение одного бита в любом байте вызовет расхождение в переданной контрольной сумме и вычисленной на основе полученных байт. Это достаточно надежный способ обезопасить передаваемые данные от повреждений (имеется в виду, найти поврежденные данные). Клиент, как и мастер, должны проверять CRC16 из полученной команды с CRC16 сгенерированным на основе полученных байт. Если контрольные суммы не совпадают, значит полученный запрос содержит поврежденные байты, что искажает смысл посланной команды. Такая команда должна быть проигнорирована.

Нужно заметить, CRC16 не используется в Modbus TCP протоколе. Так как TCP пакеты уже имеют свою встроенную контрольную сумму и проверяются на целостность данных, нет никакой необходимости для вычисления CRC16.

Еще в одной разновидности Modbus протокола, Modbus ASCII , используется LRC (Longitudinal Redundancy Check) вместо CRC16. LRC намного проще чем CRC16 и результатом является 1 байт. LRC менее надежно для детектирования ошибок повреждения данных, но исторически так сложилось что Modbus ASCII использует именно этот метод.

О том, как вычислять CRC16 для Modbus RTU протокола и LRC для Modbus ASCII протокола, я напишу отдельно.

Типы данных, которые хранятся в регистрах.

Поговорим о том, какие данные могут храниться в регистрах. Самый простой случай – это Coil и Contac регистры. В этих регистрах может храниться 1 бит информации – 0 или 1. Когда мастер читает эти регистры, он получает в результате 0 или 1. Для записи регистров используются специальные константы:

0xFF00 – означает логическую 1

0x0000 – означает логический 0

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

Все остальные регистры – это 16 битные данные (2 байта)

И вот тут самое интересное.

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

Начнём с простых случаев.

Если мы считываем 1 Input или Holding регистр, то мы получаем 16 бит данных. Например, это может быть значение 0x8D05 – два байта 0x8D и 0x05 .

В самом простом случае это может быть без знаковое целое значение: 36101

Но это может быть целое число со знаком: -29435

Другой пример. Мы прочитали значение 0x4D4F

Это может быть как целое без знака, целое со знаком, так и 2 символа в кодировке ASCII:

0x4D = M

0x4F = O

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

К примеру, мы прочитали 2 регистра, и получили следующие данные: 0xAE53 0x544D

Это может быть:

32 битное целое без знака

0xAE53 0x544D = 2924696653

32 битное целое со знаком

0xAE53 0x544D = -1370270643

32 битный float – число с плавающей точкой

0xAE53 0x544D = -4.80507e-11

Или хранить 4 символа в кодировке ASCII

0xAE53 0x544D = 0xAE 0x53 0x54 0x4D = ®STM

Если продолжать, то комбинируя больше регистров, можно хранить 64 битные значения, 128 битные значения, строки и в принципе любые типы данных.

Но, комбинируя регистры, у нас встает следующий вопрос:

Порядок байт и слов

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

Например, читая регистр, мы получили значение 0xA543

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

Если использовался Big Endian формат (старший байт первый), то у нас будет значение 42307

Но если использовался Little Endian формат (младший байт первым), то у нас будет значение 17317

Еще интереснее, когда мы формируем 32 битное значение из двух регистров.

Вариантов комбинации байтов становится 4. К примеру 32 битное число 4014323619 (0xEF45B7A3 ) может быть передано 4 следующими последовательностями байтов:

0xEF45 0xB7A3

0x45EF 0x A3B7

0xB7A3 0xEF45

0x A3B7 0x45EF

На самом деле это не важно, какой порядок байт / слов реализован на конечном устройстве. Главное, мастер должен знать этот порядок, и уметь формировать правильные значения из полученных байтов. Зная точный формат данных на конечном устройстве, мастер всегда будет правильно формировать значения регистров. И именно для этого существует такое понятие как Modbus Map (Карта Modbus ).

Modbus Map

Modbus Map – это документация, которая полностью описывает все возможные Modbus регистры на устройстве, их адреса, назначение, доступные значения, значения по умолчанию, способ доступа.

Некоторые устройства поставляются с фиксированным описанием регистров. Т.е. список регистров, их адресов, хранимых данных и т.д. жестко задан производителем и описан в документации.

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

Пример фиксированного Modbus Map , который имеет смысл применять для своих устройств, может выглядеть так, как в таблице ниже.

Адрес Описание Доступ Значение по умолчанию Доступные значения
40001 Код продукта Чтение 1 1
40002 Командный регистр, для записи команд Запись 0 – сброс устройства
1 – Разблокировать uSD карту для записи
2 – Заблокировать uSD карту для записи
3 – Созранить конфигурацию на uSD карту
40003 Время работы, в секундах
Младшее слово
Чтение 0 0 .. 0xFFFF
40004 Время работы, в секундах
Старшее слово
Чтение 0 0 .. 0xFFFF
40005 Системная ошибка Чтение / Запись 0 Смотри приложение с кодами ошибок.
Запись 0 для сброса ошибки и выключения ERROR LED

Чего не может Modbus

Modbus очень простой протокол, поэтому он поддерживает далеко не все, что может потребоваться.

Modbus не поддерживает сообщения (events). Т.е. конечное устройство не может послать сообщение мастеру. Только мастер может опросить конечное устройство.

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

Стандартный Modbus не может хранить сложные структурированные данные (по крайней мере это не так просто реализовать).

Кроме того, Modbus не поддерживает идентификации и шифрования. Т.е вся коммуникация идет в незащищённом режиме. Хотя, при некотором желании можно реализовать некоторое подобие идентификации в Modbus TCP в большинстве случаев это сделать невозможно. Есть некоторые варианты как защитить данные от несанкционированного доступа и изменения, но они все не очень надежные (хотя и могут применятся). Я опишу их в следующих статьях.

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

В следующей статье мы рассмотрим все основные функции, которые поддерживаются протоколом Modbus .