Май 12 2010

Протокол Modbus в устройствах на базе микроконтроллеров. Часть 1.0

Продолжение. Начало здесь: http://32bit.me/?p=355

Оставим пока в стороне скучную теорию и примемся за эксперименты.

Возьмём панель оператора Weintek MT6070TV и зальём в неё проект, состоящий из нескольких числовых полей (Numeric Display) и кнопки, устанавливающей значение переменной (Set Word). Вид экрана изображён на рис 1.

Рис. 1. Вид экрана панели

Полям ввода присвоены адреса переменных 110, 1010, 1110, 1210, 1310, 1410, кнопке присвоен адрес 3010, значение, записываемое при нажатии на кнопку 555510. Такое расположение адресов позволит нам определить, как система опрашивает одиночные переменные и группы переменных, расположенных последовательно.

Настраиваем панель на протокол Modbus ASCII и подключаем её к компьютеру, на котором установлена программа просмотра данных COM-портов. Программа может быть любой, я пользуюсь программой COMPump (http://www.compump.narod.ru/index.html). Она бесплатна и удобна в использовании, рекомендую.

Итак, запускаем COMPump, включаем панель и видим, что она передаёт следующее (в символах ASCII, разумеется):

:010300000001FB

Забегая вперёд, скажем, что означает этот запрос:

: — начало любой передачи в протоколе ASCII

01 — адрес ведомого, которому предназначен запрос

03 — команда «Read Holding Registers»

0000 — адрес, начиная с которого ведомый должен прочитать свои регистры

0001 — количество регистров, которые должен прочитать и отослать в своём ответе ведомый

FB — контрольная сумма

Панель циклически выдаёт одну и ту же строку. То есть, она пытается прочитать переменную по адресу 0 из устройства по адресу 1, и, так как устройство ей не отвечает, панель не пытается прочитать другие переменные, повторяя данный запрос раз за разом.

Если нажать на кнопку на экране панели, мы увидим, что панель отправила следующий запрос:

:0110001D00010215B307

Расшифровывается он так:

:01 — команда ведомому устройству с адресом 01

10 — команда «Preset Multiple Registers»

001D — начальный адрес, с которого устанавливаются регистры ведомого. 1D16 = 2910

0001 — количество регистров, которые будут записаны

02 — количество байт, которое будет передано

15B3 — Передаваемые данные. 15B316 = 555510

07 — контрольная сумма.

Можно обойтись и без реальной панели, программное обеспечение Weintek работает в режиме симуляции, принимая и передавая данные через COM-порт компьютера. Программу EasyBuilder 8000, которая может использоваться для такой симуляции, можно бесплатно скачать с сайта Weintek (www.weintek.com) или с сайта их представителей в России, компании ПЛК Системы (www.plcsystems.ru).

Теперь удалим из проекта кнопку с адресом 1, оставив только кнопки с адресами 10-14. Запрос изменился:

:010300090005EE

Расшифровывается он так:

:01 — адрес ведомого устройства

03 — команда «Read Holding Registers»

0009 — начальный адрес чтения регистров

0005 — количество регистров, которые нужно прочесть

EE — контрольная сумма.

То есть, как для чтения одиночной переменной, так и для чтения нескольких переменных, расположенных по смежным адресам, используется одна и та же команда 03- «Read Holding Registers»

Теперь включим в панели протокол RTU. Что изменилось?

Во-первых, данные сейчас передаются не в ASCII, а «как есть», байтами.

Во-вторых, нет двоеточия перед посылкой. (Почему в режиме ASCII нужен специальный символ начала посылки, а в RTU не нужен, будет рассматриваться ниже).

Запрос на чтение регистров с адресами 10-14 теперь выглядит так:

01 03 00 09 00 05 55 CB

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

Запрос на запись в регистр в RTU выглядит так:

01 10 00 1D 00 01 02 15 B3 EA F8

Сравним его с ASCII: «:0110001D00010215B307»

Снова изменилась только контрольная сумма.

У читателя может возникнуть ещё один вопрос: почему адреса переменных в проекте панели на единицу больше передаваемых в Modbus — запросах? То есть, для переменной с адресом 1 запрашивается регистр 0, для переменной с адресом 10 — регистр 9, для пременной с адресом 30 — регистр 29?

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

Поэтому, если в проекте панели переменная имеет адрес 1, в проекте ISaGRAF переменная также имеет адрес 1, то между панелью и контроллером передаётся посылка, где указан адрес 0, и разработчик программ ПЛК и панели может об этом даже не знать. (На самом деле, лучше всё-таки знать, потому что бывают системы с нумерацией адресов, начиная с нуля).

Теперь можно подключить к панели контроллер, и посмотреть, что он передаёт в ответ на запросы панели.

Для этого воспользуемся контроллером ICP-DAS i7188EGD.

Продолжение следует

Владимир Татарчевский