что такое протокол modbus
Протокол Modbus. Обзор, описание и примеры использования.
Продолжаем подробно разбирать стандарты передачи данных. И героем сегодняшней статьи станет протокол Modbus! Впервые спецификация протокола Modbus была опубликована ни много ни мало, а в 1979 году, но до сих пор не утратила своей актуальности! Итак, приступаем…
Modbus — самый широко распространенный промышленный протокол для организации обмена данными между различными устройствами (межмашинное взаимодействие, Machine-to-Machine, M2M). Популярность объясняется многими факторами, среди которых простота реализации, отсутствие необходимости использовать дополнительные микросхемы, и, конечно же, открытость протокола.
Основные плюсы Modbus:
В то же время протокол не избавлен от некоторых недостатков:
Обсуждая достоинства и недостатки протокола мы частично забежали вперед, так что теперь давайте разберем все поэтапно…
Как уже было упомянуто, протокол использует обмен данными по модели ведущий-подчиненный (Master — Slave). Ведущий отправляет запросы, на которые могут отвечать подчиненные. Slave-устройство не может само начать обмен данными, только по команде от Master’a.
В качестве физического уровня стандарт предусматривает использование интерфейсов RS-232, RS-422 и RS-485. Также существует реализация протокола Modbus для TCP/IP — Modbus TCP. Но этот вариант мы сегодня будем затрагивать в меньшей степени.
Сеть Modbus может состоять из нескольких slave-устройств (от 1-го до 247-ми), но master должен быть только один. Каждое из подчиненных устройств имеет свой собственный адрес, соответственно, ведущий может адресовать свое сообщение или запрос конкретному slave-устройству.
Кроме того, поддерживаются широковещательные сообщения, которые принимают все подчиненные. Но разница заключается в том, что опознав сообщение, адресованное именно ему, подчиненное устройство отправляет ведущему ответ. На широковещательные же запросы подчиненные отвечать не могут.
На адреса slave накладываются некоторые ограничения:
Вот как может выглядеть один из вариантов подключения устройств с использованием RS-485:
Здесь у нас присутствует один master и три slave-устройства с адресами от 0x03 до 0x05.
Переходим дальше… Различают несколько логических уровней протокола:
Modbus RTU | RS-232 RS-422 RS-485 |
Таблица | Тип элемента |
---|---|
Дискретные входы (Discrete Inputs) | 1 бит |
Дискретные выходы (регистры флагов, Coils) | 1 бит |
Регистры ввода (Input Registers) | 16-битное слово |
Регистры хранения (Holding Registers) | 16-битное слово |
Дискретные входы и регистры ввода доступны только для чтения данных, а, соответственно, дискретные выходы и регистры хранения — для чтения и записи.
Доступ к регистрам таблицы осуществляется при помощи 16-ти битного адреса. Первому элементу таблицы соответствует адрес 0. Таким образом, каждая из этих 4-х таблиц может включать в себя вплоть до 65536 регистров (адреса 0…65535 — 16 бит).
Вот теперь давайте рассмотрим конкретные команды из группы стандартных:
И, конечно же, мы не можем не разобрать конкретные примеры запросов и ответов при работе по Modbus.
Протокол Modbus. Примеры команд.
Первым делом займемся чтением данных — коды функций 0x01, 0x02, 0x03, 0x04. В общем виде запросы ведущего и ответы подчиненного выглядят следующим образом (здесь мы рассматриваем только часть пакета — PDU):
Обратите внимание, что в запросе передается количество элементов(!), то есть ячеек таблиц данных (регистров). А в ответе для указания размера данных используются уже байты. Значения адреса и количество элементов передаются в виде 16-битных слов, при этом старший байт передается первым.
Пойдем дальше обобщенного описания формата и проанализируем команды для конкретного устройства. В качестве этого устройства я использую сервопривод серии ASDA-A2, который для обмена данными использует как раз-таки протокол Modbus, причем поддерживает и Modbus RTU, и Modbus ASCII.
Пусть нам надо прочитать данные, расположенные по адресам 0x0200 и 0x0201, slave-устройства с адресом 0x01. Запрос master’а для Modbus RTU будет таким:
Здесь у нас в запросе, указано, что мы хотим прочитать значение двух элементов (регистров). И ответ slave:
А в ответе уже видим, что прочитано 4 байта, поскольку значение одного регистра — это 2 байта (16 бит), а регистров у нас тоже 2. Таким образом, полученные значения:
CRC Low и CRC High — это соответственно младший и старший байты 16-ти битной контрольной суммы.
В Modbus ASCII все несколько иначе, запрос выглядит так (в кавычках указаны ASCII символы):
И в первом и во втором случае запрашиваем значения одних и тех же регистров и, соответственно, получаем в ответ одинаковые данные.
При чтении битов регистров флагов или дискретных входов запрос выглядит точно также, а вот байты данных ответного сообщения иначе:
Здесь одно значение флага или дискретного входа занимает один бит. И все эти биты упакованы в байты, и если число запрошенных флагов/входов не распределяется по байтам (не кратно 8), то «лишние» биты заполняются нулями. Как в последнем байте на этой схеме.
Переходим к записи! Для записи одного значения используются команды с кодами 0x05 и 0x06. Запрос в целом похож на уже рассмотренный (при чтении данных), только вместо количества элементов для чтения передаются данные, которые будут записаны:
При записи значений флагов или дискретных входов число 0xFF00 соответствует включенному состоянию, 0x0000 — выключенному. В случае успешного выполнения запроса подчиненное устройство отправляет ведущему точную копию этого запроса.
С этим разобрались! Но необходимо рассмотреть еще и случай записи нескольких значений (коды команд 0x10 и 0x0F). В общем виде формат запроса такой:
И, в обязательном порядке, рассмотрим практический пример 🙂 Пусть нам требуется записать значения 0x0BB8 и 0x0000 по адресам, начинающимся с 0x0112. Запрос и ответ Modbus RTU:
И для Modbus ASCII:
Довольно большая получилась статья, но очень уж хотелось затронуть все по максимуму… И, на самом деле, некоторые моменты остались раскрытыми до конца 🙂 Например, расчет контрольной суммы для Modbus RTU и Modbus ASCII, алгоритмы там абсолютно разные. Так что в ближайшее время будет еще как минимум одна статья с примером программы для расчета LRC и CRC, оставайтесь на связи!
Что такое протокол modbus
Modbus — коммуникационный протокол, основанный на архитектуре «клиент-сервер». Широко применяется в промышленности для организации связи между электронными устройствами. Может использовать для передачи данных последовательные линии связи RS-485, RS-422, RS-232, а также сети TCP/IP (Modbus TCP).
История
Modbus был разработан фирмой Modicon (в настоящее время принадлежит Schneider Electric) для использования в её контроллерах с программируемой логикой. Впервые спецификация протокола была опубликована в 1979 году. [1] Это был открытый стандарт, описывающий формат сообщений и способы их передачи в сети состоящей из различных электронных устройств.
Первоначально контроллеры MODICON использовали последовательный интерфейс RS-232. [1] Позднее стал применяться интерфейс RS-485, так как он обеспечивает более высокую надёжность, позволяет использовать более длинные линии связи и подключать к одной линии несколько устройств.
Введение
Modbus относится к протоколам прикладного уровня сетевой модели OSI. [3] Контроллеры на шине Modbus взаимодействуют, используя клиент-серверную модель, основанную на транзакциях, состоящих из запроса и ответа.
Обычно в сети есть только один клиент, так называемое, «главное» (англ. master) устройство, и несколько серверов — «подчиненных» (slaves) устройств. Главное устройство инициирует транзакции (передаёт запросы). Подчиненные устройства передают запрашиваемые главным устройством данные, или производят запрашиваемые действия. Главный может адресоваться индивидуально к подчиненному или инициировать передачу широковещательного сообщения для всех подчиненных устройств. Подчиненное устройство формирует сообщение и возвращает его в ответ на запрос, адресованный именно ему. При получении широковещательного запроса ответное сообщение не формируется.
Спецификация Modbus описывает структуру запросов и ответов. Их основа — элементарный пакет протокола, так называемый PDU (Protocol Data Unit). Структура PDU не зависит от типа линии связи и включает в себя код функции и поле данных. Код функции кодируется однобайтовым полем и может принимать значения в диапазоне 1. 127. Диапазон значений 128. 255 зарезервирован для кодов ошибок. Поле данных может быть переменной длины. Размер пакета PDU ограничен 253 байтами.
номер функции | данные | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 байт | N Категории кодов функций В действующей в настоящее время спецификации протокола определяются три категории кодов функций: Стандартные команды Их описание должно быть опубликовано и утверждено 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Чтение данныхДля чтения значений из перечисленных выше таблиц данных используются функции с кодами 1—4 (шестнадцатеричные значения 0x01—0x04): Запрос состоит из адреса первого элемента таблицы, значение которого требуется прочитать, и количества считываемых элементов. Адрес и количество данных задаются 16-битными числами, старший байт каждого из них передается первым. В ответе передаются запрошенные данные. Количество байт данных зависит от количества запрошенных элементов. Перед данными передается один байт, значение которого равно количеству байт данных. Значения регистров хранения и регистров ввода передаются начиная с указанного адреса, по два байта на регистр, старший байт каждого регистра передаётся первым:
Значения флагов и дискретных входов передаются в упакованном виде: по одному биту на флаг. Единица означает включённое состояние, ноль — выключенное. Значения запрошенных флагов заполняют сначала первый байт, начиная с младшего бита, затем следующие байты, также от младшего бита к старшим. Младший бит первого байта данных содержит значение флага, указанного в поле «адрес». Если запрошено количество флагов, не кратное восьми, то значения лишних битов заполняются нулями:
Запись одного значенияКоманда состоит из адреса элемента (2 байта) и устанавливаемого значения (2 байта). Для регистра хранения значение является просто 16-битным словом. Для флагов значение 0xFF00 означает включённое состояние, 0x0000 — выключенное, другие значения недопустимы. Если команда выполнена успешно, ведомое устройство возвращает копию запроса. Запись нескольких значенийКоманда состоит из адреса элемента, количества изменяемых элементов, количества передаваемых байт устанавливаемых значений и самих устанавливаемых значений. Данные упаковываются так же, как в командах чтения данных. Ответ состоит из начального адреса и количества изменённых элементов. Ниже приведён пример команды ведущего устройства и ответа ведомого (для Modbus RTU). Протокол ModbusСодержаниеОсновные понятияВ устройствах Wirenboard данные 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 выглядит, как это показано на рисунке. 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, содержащий запрошенные данные. При возникновении ошибки устройством возвращается код ошибки. В случае обычной транзакции код функции в ответе возвращается без изменений; в случае ошибки старший бит кода функции устанавливается в единицу (то есть код функции + 0x80) Стоит определить таймаут ожидания ответа от ведомого устройства — бессмысленно долго ждать ответ, который, возможно, из-за какой-то ошибки никогда и не придет. Структуры данных ModbusВ Modbus принято кодировать адреса и данные в формате big-endian, то есть в формате, когда байты следуют, начиная со старшего: например, при передаче шестнадцатеричного числа 0x1234 сначала устройством будет принят байт 0x12, а затем — 0x34. Для передачи данных другого типа, например, чисел с плавающей запятой (float), текстовых строк, даты и времени суток и т.п. производитель может выбрать свой собственный способ кодирования — для расшифровки получаемых данных важно ознакомится со спецификацией производителя устройства. Модель данных ModbusОбмен данными с Modbus-устройствами происходит через регистры. В протоколе Modbus определяется четыре типа регистров, показанных в таблице:
Дискретные входы (Discrete Inputs) также являются однобитными регистрами, описывающими состояние входа устройства (например подано напряжение — 1). Эти регистры поддерживают только чтение. Регистры хранения (Holding Registers) и регистры ввода (Input Registers) представлены двухбайтовым словом и могут хранить значения от 0 до 65535 (0x0000 — 0xFFFF). Регистры ввода допускают только чтение (например, текущее значение температуры). Регистры хранения поддерживают как чтение, так и запись (для хранения настроек). В настоящее время во многих устройствах, в частности в устройствах Wiren Board, эти регистры не разделяются. Команды на чтение регистра хранения N и регистра ввода N обратятся к одному и тому же значению в адресном пространстве устройства. Адреса и номера регистровВ стандарте Modbus для каждого из четырех типов регистров используются разные таблицы с номерами 0,1,3,4. Таким образом, регистр определенного типа с определенным номером (иначе его называют физическим адресом) имеет свой адрес в соответствующей таблице.
Иногда в описаниях устройства указываются только логические адреса. Например, coil-регистр 0 имеет адрес 000001, регистр ввода 4 — 400005 и т.д. В готовых шаблонах устройств контроллера Wiren Board 5 есть шаблон для однофазного счетчика электроэнергии SDM220 (/usr/share/wb-mqtt-serial/templates/config-sdm220.json). В документации от производителя «Eastron SDM 220 Modbus Smart Meter Modbus Protocol Implementation V1.0» перечислены регистры и соответствующие им измеряемые параметры, например: Производитель в таблице приводит и логические, и физические адреса регистров, что позволяет нам с легкостью создать шаблон устройства и проиллюстрировать связь между логическими и физическими адресами Modbus-регистров. Коды функций чтения и записи регистровВ следующей таблице приведены наиболее распространенные коды функций Modbus:
Команды условно можно разделить по типам: чтение значений — запись значений; операция с одним значением — операция с несколькими значениями. Формат данных запросов и ответов ModbusРассмотрим подробнее, как происходит обмен данными между устройством-клиентом, отправляющим запрос, и устройством-сервером, отвечающим ему. На следующем рисунке показан обмен данными контроллера с устройством с адресом 0x01. Мы хотим прочесть 8 coil-регистров, начиная с первого. В качестве данных мы получили шестнадцатеричное число 0x2D, то есть состояние восьми coil-регистров в двоичном виде такое: 0b10110100. В следующей таблице приведены структуры данных запросов и ответов для основных функций Modbus. Коды исключений (ошибки) ModbusВ случае, если запрос не может по той или иной причине быть обработан устройством-сервером, то в ответ он отправляет сообщение об ошибке. Соообщение об ошибке содержит адрес Modbus-устройства, код функции, при выполнении которой произошла ошибка, увеличенный на 0x80, код ошибки и контрольную сумму: В этом случае мы попытались обратиться к несуществующему адресу регистра 0xFFFF и попытались прочесть 8 регистров флагов. В результате мы получили код ошибки 0x03 — «В поле данных передано неверное значение». Наиболее распространенные коды ошибок Modbus приведены в следующей таблице:
Вычисление контрольной суммы ModbusДля протокола Modbus RTU 16-битная контрольная сумма (CRC) вычисляется по алгоритму, описанному в спецификации Modbus, в документе «Modbus Serial Line Protocol and Implementation Guide», раздел «CRC-generation». Передающее устройство формирует два байта контрольной суммы на основе данных сообщения, а принимающее устройство заново вычисляет контрольную сумму и сравнивает с полученной. Совпадение принятой и вычисленной контрольной суммы Modbud RTU считается индикатором успешного обмена данными. В случае ограниченных вычислительных ресурсов для вычисления контрольной суммы существует функция, использующая табличные значения (так же приведена в спецификации).
|