Урок 56. Протокол последовательной передачи данных ModBus RTU.

Протокол ModBus RTU

Продолжение серии уроков об обмене данными между платами Ардуино. В этом уроке подробно расскажу о коммуникационном протоколе ModBus RTU.

Предыдущий урок     Список уроков     Следующий урок

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

 

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

 

Общее описание протокола.

ModBus – открытый протокол обмена данными в малых локальных сетях. Как правило, используется для передачи данных через интерфейсы RS-232, RS-485, RS-422, в сетях TCP/IP, UDP. Благодаря своей простоте и универсальности ModBus получил широкое распространение и стал де факто стандартом в малых распределенных вычислительных системах. Практически все современные контроллеры поддерживают работу в сетях ModBus.

В сети ModBus контроллеры, как правило, соединены по топологии ”Общая шина”. Взаимодействие контроллеров происходит в соответствии с моделью master-slave (ведущий-ведомый).

В сети есть главное устройство - ведущее. А также несколько подчиненных устройств – ведомые. Обмен может быть инициирован только ведущим устройством.

Транзакция (последовательность операций при обмене данными) состоит из запроса и ответа.

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

Ведомое устройство, определив свой адрес в запросе, формирует ответ.

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

Существуют 3 варианта протокола ModBus.

  • ModBus ASCII – текстовый протокол. В нем используются только ASCII символы. Каждый байт передается как два шестнадцатеричных символа.
  • ModBus RTU – числовой протокол. Данные передаются в двоичном виде. Байт, передаваемый по сети это число протокола.
  • ModBus TCP – протокол для передачи данных в TCP/IP сетях.

Числовые и текстовые протоколы я сравнивал еще в уроке 31. По производительности и скорости обмена, безусловно, преимущество имеют числовые протоколы. Ближайшие уроки будем использовать  ModBus RTU. Именно этому варианту посвящена последующая информация урока.

 

Протокол ModBus RTU.

В сети по топологии ”Общая шина” подключены устройства (контроллеры). Стандарт ModBus допускает совместную работу до 247 контроллеров.

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

Стандарт ModBus определяет 4 типа данных.

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

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

На практике используются только данные Регистры хранения (Holding Registers). Доступ к данным осуществляется через 16 битный адрес. В итоге:

  • данные в каждом контроллере представляют собой таблицу 16 битных регистров;
  • в таблице данных может быть до 65536 элементов;
  • нумерация элементов начинается с 0.

Ведущее устройство инициирует транзакцию – обмен данными. Транзакция может быть индивидуальной (запрос-ответ) или широковещательной (адресуются одновременно все ведомые устройства). Транзакция состоит из одного кадра запроса и одного кадра ответа. При широковещательной транзакции используется только кадр запроса.

Данные кадра передаются сплошным потоком. Пауза между передачей данных не должна превышать время передачи 1,5 символа. Признаком нового кадра является отсутствие обмена в сети (молчание) в течение времени необходимого на передачу 3,5 символов. Если в течение этого времени линия сети находилась в неактивном состоянии, то ведомые устройства воспринимают первое принятое данное как начало кадра.

В общем случае кадр запроса имеет следующий формат.

Пауза
3,5 T
Адрес
8 бит
Функция
8 бит
Данные
N * 8 бит
Контрольная сумма
16 бит
Пауза
3,5 T


Адрес (8 бит).

Кадр начинается с поля адреса, которое состоит из 8 разрядов. Содержит адрес ведомого устройства, которому предназначено сообщение от ведущего. Каждое ведомое устройство должно иметь уникальный адрес от 1 до 247. И только адресуемое ведомое устройство должно ответить на запрос ведущего. В ответе сообщается ведущему устройству, с каким из ведомых установлена связь.

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

Функция (8 бит).

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

Старший бит байта функция устанавливается в 1 в ответе ведомого устройства, чтобы сообщить ведущему, что операция была выполнена с ошибкой. При успешной операции старший бит равен 0.

Выделяются 3 категории кодов функций.

  • Стандартные команды. Коды, определенные стандартом на протокол ModBus.
  • Пользовательские команды. Для кодов 65…72 и 100…110 пользователь может сам назначить произвольную функцию.
  • Зарезервированные команды. Это коды, которые не были изначально определены стандартом, но уже используются в устройствах разных производителей.

Подавляющее большинство ModBus контроллеров используют только 3 функции.

Код функции Название Описание
03 READ HOLDING REGISTERS Чтение значений одного или нескольких регистров хранения
06 FORCE SINGLE REGISTER Запись в один регистр хранения
16 FORCE MULTIPLE REGISTERS Последовательная запись нескольких регистров хранения

Формат ответа зависит от функции. Во многих случаях нормальный ответ полностью или частично повторяет запрос.

Данные (N * 8 бит).

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

Каждое данное имеет 16 разрядов (2 байта). Данные передаются старшим байтом вперед.  Например, последовательная передача регистров с адресами 0 и 1 должна происходить следующим образом:

  • старший байт регистра 0 ->
  • младший байт регистра 0 ->
  • старший байт регистра 1 ->
  • младший байт регистра 1 ->.

При передаче 4х байтового числа, например, с плавающей запятой последовательность та же. Число разбивается на два 16 разрядных регистра и в каждом из них первым передается старший байт (1-> 0-> 3-> 2->).

Контрольная сумма (16 бит).

Поле контроля целостности данных сообщений. Позволяет проверять кадры на наличие ошибок. Речь идет об ошибках, появляющихся при передаче данных.

Я постараюсь в общих чертах рассказать о контрольном коде. Лучше пропустить этот параграф. Может голова треснуть. У меня, когда я затрагиваю эту тему – всегда трещит. В следующем уроке я представлю практическую реализацию вычисления контрольного кода ModBus.

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

Используется полиноминальная арифметика по модулю 2. Это означает, что все действия при вычислении CRC это арифметические операции без переноса. Вычитание и сложение происходят побитно, без учета переноса из-за чего эти операции дают одинаковый результат и могут быть заменены операцией ”исключающее или”. При делении вместо вычитания делителя из делимого также используется операция ”исключающее или”. Это общий принцип вычисления CRC. Практически вычисления производятся с помощью более эффективных алгоритмов.

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

Стандарт ModBus RTU использует стандартный циклический код CRC-16 с порождающим полиномом X16+X15+X2+1. Это 16ти разрядный код, двоичные коэффициенты 1 1000 0000 0000 0101 ( 8005h в шестнадцатеричном представлении).

Сообщение рассматривается как одно последовательное двоичное число, в котором старший бит передается первым. Это число умножается на X16 (сдвиг влево на 16 разрядов), и делится на X16+X15+X2+1 (1 1000 0000 0000 0101). 16ти битный остаток (предварительно инициализированный всеми единицами) и есть контрольный код сообщения.

 

Обработка логических ошибок.

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

Код ошибки Название Описание
01 ILLEGAL FUNCTION Код функции не поддерживается в контроллере
02 ILLEGAL DATA ADRESS Недопустимый адрес данных
03 ILLEGAL DATA VALUE Недопустимые значения данных
04 SLAVE DEVICE FAILURE Произошла ошибка при выполнении операции

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

 

Детальное рассмотрение функций.

Функция 03 – чтение регистров хранения.

Используется для чтения значений нескольких регистров хранения. В запросе передается адрес первого элемента таблицы регистров, значение которого необходимо прочитать и количество считываемых регистров. Для адреса и количества используются 16ти разрядные числа. Старший байт передается первым.

Запрошенные данные содержатся в ответе. Перед блоком данных передается байт, который содержит число прочитанных данных в байтах.

Формат запроса функции чтения регистров хранения.

Номер байта Номер байта в параметре Параметр Пример чтения регистров с адресами 8 и 9
0 0 Адрес контроллера 01 01
1 0 Функция 03 03
2 1 Начальный адрес регистров 0008 00
3 0 08
4 1 Количество регистров 0002 00
5 0 02
6 1 Контрольная сумма 45C9 45
7 0 C9

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

Номер байта Номер байта в параметре Параметр Пример чтения регистров с адресами 8 и 9
0 0 Адрес контроллера 01 01
1 0 Функция 03 03
2 0 Количество прочитанных байтов 04 04
3 1 Значение регистра 8 12A5 12
4 0 A5
5 1 Значение регистра 9 E020 E0
6 0 20
7 1 Контрольная сумма A770 A7
8 0 70

 

Функция 06 – запись в один регистр хранения.

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

Формат запроса функции записи одного регистра хранения.

Номер байта Номер байта в параметре Параметр Пример записи в регистр 9 значения 12A5
0 0 Адрес контроллера 01 01
1 0 Функция 06 06
2 1 Адрес регистра 0009 00
3 0 09
4 1 Значение регистра 12A5 12
5 0 A5
6 1 Контрольная сумма 9513 95
7 0 13

Ответ (повторяет запрос).

Номер байта Номер байта в параметре Параметр Пример записи в регистр 9 значения 12A5
0 0 Адрес контроллера 01 01
1 0 Функция 06 06
2 1 Адрес регистра 0009 00
3 0 09
4 1 Значение регистра 12A5 12
5 0 A5
6 1 Контрольная сумма 9513 95
7 0 13

 

Функция 16 – запись значений в регистры хранения.

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

В запросе передается адрес первого регистра, количество регистров и значения для них.

В ответе возвращается начальный адрес и количество измененных регистров.

Формат запроса функции записи регистров хранения.

Номер байта Номер байта в параметре Параметр Пример записи регистров с адресами 8 и 9
0 0 Адрес контроллера 01 01
1 0 Функция 10 10
2 1 Начальный адрес регистров 0008 00
3 0 08
4 1 Количество регистров 0002 00
5 0 02
6 0 Счетчик байтов 04 04
7 1 Значение регистра 8 12A5 12
8 0 A5
9 1 Значение регистра 9 E020 E0
10 0 20
11 1 Контрольная сумма AF4A AF
12 0 4A

Ответ (адрес ведомого, код функции, начальный адрес и количество регистров).

Номер байта Номер байта в параметре Параметр Пример записи регистров с адресами 8 и 9
0 0 Адрес контроллера 01 01
1 0 Функция 10 10
2 1 Начальный адрес регистров 0008 00
3 0 08
4 1 Количество регистров 0002 00
5 0 02
6 1 Контрольная сумма С00A C0
7 0 0A

 

ModBus и специализированные протоколы.

Теперь можете сравнить протокол ModBus со специализированном протоколом из урока 48.

Запрос.

Номер байта Формат числа Назначение
0 byte Код операции + адрес контроллера (0x10)
1 byte Состояние светодиода
2 byte Контрольный код ( байт 0 ^ байт 1 ^ 0xe5)

Ответ.

Номер байта Формат числа Назначение
0 … 3 float Температура
4 … 7 float Напряжение
8 byte Состояние кнопки
9 byte Резерв
10, 11 int Контрольная сумма (сумма байтов 0 … 9  ^ 0xa1e3)

По сравнению со специализированным протоколом:

  • ModBus медленнее, его производительность ниже. Для получения такого же количества информации по сети передается намного больше данных.
  • Реализация его сложнее. Требуется больше ресурсов микроконтроллера и сети.

Но достоинства во многих случаях весомее.

  • За счет более сложной контрольной суммы и избыточности информации ошибки сети определяются в нем надежнее, выше достоверность данных.
  • Сеть легко расширяется. Очень просто добавлять новые устройства.
  • ModBus – стандартный протокол. Множество контроллеров различных производителей поддерживают его.

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

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

 

В следующем уроке будем реализовывать связь платы Ардуино и компьютера по протоколу ModBus.

Предыдущий урок     Список уроков     Следующий урок

9 комментариев на «Урок 56. Протокол последовательной передачи данных ModBus RTU.»

  1. Здравствуйте, Эдуард!
    Из Ваших уроков я пришел к выводу: (поправьте если ошибаюсь) если необходимо объединить несколько контроллеров, выполняющих роль пультов, датчиков и исполнительных устройств, по схеме — «Общая шина» обмен между ними должен происходить по средствам общего контроллера — Ведущего. Тот, в свою очередь, должен регулярно производить опрос каждого из устройств на шине, и «прослушивать» шину на случай вероятного отклика, и к тому-же должен делать это тем чаще, чем быстрее должна быть реакция на событие.
    Если события возникают не часто, но реакция на него должна быть достаточно быстрой, лучше использовать топологию — «Звезда», и решать проблему: количество контроллеров = количество портов и = количество линий связи?

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

      • Спасибо!
        Но я несколько не о том, к примеру создаем систему, где есть главный контроллер и несколько подчиненных, которые выполняют определенные действия, и с периодичностью 1-5 сек. главный контроллер обменивается данными с подчиненными. Но вот в момент срабатывания датчика или кнопки на подчиненном, главный контроллер должен это зарегистрировать и оперативно скорректировать работу всех остальных устройств, скажем, с задержкой 20-50 мс. Для того чтобы это действие не было отложено на 1-5 сек., я так понимаю, должен быть опрос состояния подчиненных значительно чаще, это при топологии «Общая шина» либо делать «Звезду» где каждый контроллер подключен к своему порту и постоянно «прослушивается».

  2. Здравствуйте Эдуард. Хочу Вас поблагодарить за уроки. темой Ардуино интересуюсь более двух лет, за это время прочитал множество уроков, проектов, даже одну печатную книгу иностранного автора. Могу с увереностью сказать , что Ваш материал самый лучший.! Пока изучаю уроки вначале, многое узнаю нового. Хочу пожелать Вам творческих успехов , здоровья и благополучия.

  3. Эдуард, просто классный труд! Спасибо огромное за такую «Книгу». Планируете ли еще уроки, и если да, то на какие темы?

    • Спасибо за добрые слова. Да, я добавляю уроки по мере времени. Еще очень много тем. Сейчас про обмен данными между платами мне писать и писать.
      Если есть пожелания по урокам, напишите на форуме сайта. Там есть тема «Какие нужны уроки.»

  4. Огромная, нужная работа вами проделана. Таких пособий в инете больше нет. Спасибо.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *