Знакомство с Modbus

в 14:46, , рубрики: C, c++, modbus, serial, tcp

Modbus — это протокол, который используют поверх TCP сокетов или в RTU варианте поверх работы с Serial портом, или 485 интерфейса насколько это встречалось в моей практике.

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

Кратко покажу что такое modbus rtu:

unsigned char* response;
response = new unsigned char[8];
ReadFile(hSer, (char*)response, 8, &size, 0);

Так можно прочитать приходящие на сервер запросы modbus rtu. Структура 8 байт. FF это байт.
Может прийти сообщение вида: 02 03 A0 28 00 04 93 2A

Расшифрую сообщение. 02 — это номер устройства, к которому идет обращение. 03 — номер функции, т.е. 3 — читать регистры, а бывает еще записывать, регистры, коилы по 1 биту и т.д.

A0 28 если перевести в десятичную систему будет 41000 — номер регистра, 00 04 — значит еще 4 регистра нужно считать от 41000. Последние 2 числа — 2 байта кода CRC16.

Раз такое сообщение пришло, соответственно так же нужно заполнить массив на стороне отправки, и переправить либо через tcp сокеты, либо через com порт, или другим способом.

Ответ так же заполняется, но там будет уже сообщение вида: 02 03 08 00 01 00 02 00 03 00 04 95 В8 т.е. код устройства, код функции, количество передаваемых байт, 1234 данных (это как бы значения регистров). 2 байта код CRC.

Код CRC рассчитывается от сообщения не включая 2 байта кода CRC. Это для функции 3. В коде:

unsigned char* request
request = new unsigned char[reqsize];

Заполнить данными и подсчитать CRC:

crc.i = CRC16((unsigned char *)request, reqsize-2);
request[reqsize-2] = crc.ch[1];
request[reqsize-1] = crc.ch[0];

И отправить по Serial порту:

BOOL iRet = WriteFile(hSer, (char*)request, reqsize, &dwBytesWritten, NULL );

Таким образом отправили и ответили на функцию 3 (чтение нескольких регистров) по протоколу Modbus.

Спасибо за внимание! Читайте спецификации на официальном сайте протокола.

Автор: weterokstudio_ru

Источник

Поделиться

* - обязательные к заполнению поля