При разработке устройств на базе микроконтроллеров ESP8266/ESP32/Arduino работающих через RS-485 по протоколу Modbus немаловажным моментовм является конфигурирование Modbus операций.
Смысла «изобретать велосипед» в части разработки формата конфигурации нет. В одном из проектов использовал JSON описание конфигурации Modbus для Microsoft IoT Edge. Собственно, имеет смысл использовать этот формат конфигурации, поскольку он хорошо закрывает большинство вопросов.
Исходный конфигурационный файл немного модифицирую, поскольку работа с JSON файлом на микроконтроллере сложнее из-за ограничений по памяти.
[ { "Slave": { "Connection": "ttyS0", "RxPin": "15", "TxPin": "13", "PollingInterval": "2000", "RetryCount": "10", "RetryInterval": "100", "HwId": "TermoSensor-0a:01:01:01:01:02", "BaudRate": "9600", "Config": "SERIAL_8N1", "Ops": [ { "PollingInterval": "2000", "UnitId": "1", "Function": "0x04", "Address": "0x01", "Len": "1", "DisplayName": "Temp" }, { "PollingInterval": "2000", "UnitId": "1", "Function": "0x04", "Address": "0x02", "Len": "1", "DisplayName": "Humidity" } ] } }, { "Slave": { "Connection": "192.168.1.2", "TcpPort": "502", "PollingInterval": "2000", "HwId": "TermoSensor-0a:01:01:01:01:02", "Ops": [ { "PollingInterval": "2000", "UnitId": "1", "Function": "0x04", "Address": "0x01", "Len": "1", "DisplayName": "Temp" } ] } } ]
Расшировка полей:
- «PublishInterval» — Interval between each push to
cloud server inmillisecond . - «Slave» — Contains one or more Modbus slaves’ configuration.
- «SlaveConnection» — Ipv4 address or the serial port name of the Modbus slave.
- «RxPin» — Rx pin (e.g. for SoftwareSerial initialization).
- «TxPin» — Rx pin (e.g. for SoftwareSerial initialization).
- «RetryCount» — Max retry attempt for reading data, default to 10.
- «RetryInterval» — Retry interval between each retry attempt, default to 50 milliseconds
- «HwId» — Unique Id for each Modbus slave (
user defined ). - «BaudRate» — Serial port communication parameter. (valid values: …9600, 14400,19200…)
- «Config» — serial port configuration. Default SERIAL_8N1. Possible values see here.
- «Ops» — Contains one or more Modbus read requests.
- «PollingInterval»: Interval between each read request in
millisecond . - «UnitId» — The unit id (SlaveID) to be read.
- «Function» — номер функции (регистра) для считывания данных. Вместо «StartAddress» в исходном варианте JSON.
- «Address» — смещение адреса в выбранном регистре.
- «Len» — Number of registers/bits to be read. Вместо «Count» в исходном варианте.
- «DisplayName» — Operation name.
- «CorrelationId» — The Operations with the same id will be grouped together in their output message. (for future releases).
- «PollingInterval»: Interval between each read request in
Библиотека для реализации конфигурационного файла для Modbus — ArduinoJSON. Для чтения конфиги с точки зрения работы с файловой системой используется код описанный ранее. Созданный конфигурационный JSON файл может быть загружен в файловую систему ESP8266/ESP32 либо с облачного сервера, либо через Arduino IDE.
При работе с утилитой загрузки файлов в SPIFFS через Arduino IDE нужно учитывать, что
- При аплоаде утилита добавляет к файлу расширение «.txt». Соответственно, если в папку /data положили файл rs485cfg, то в SPIFFS уже будет лежать файл rs485cfg.txt.
- При каждой загрузке утилита предварительно удаляет ВСЕ ранее созданные файлы. Если вы программно создали какие-то файлы, то они также будут затерты.
Возможные значения Modbus «Function»:
Код функции | Описание | Тип значения | Тип доступа |
---|---|---|---|
01 (0x01) | Read Coil Status | Дискретное | Чтение |
02 (0x02) | Read Input Status | Дискретное | Чтение |
03 (0x03) | Read Holding Registers | 16 битное | Чтение |
04 (0x04) | Read Input Registers | 16 битное | Чтение |
05 (0x05) | Write Single Coil | Дискретное | Запись |
06 (0x06) | Write Single Register | 16 битное | Запись |
15 (0x0F) | Write Multiple Coils | Дискретное | Запись |
16 (0x10) | Read/Write Multiple Registers | 16 битное | Чтение/Запись |
Но на данный момент меня интересует только чтение. Поле «Address» смещает адрес в выбранном регистре.
Тестовый конфигурационный файл для датчика тепературы и влажности следующий.
[ { "Slave": { "Connection": "tty0", "PollingInterval": "4000", "RetryCount": "20", "RetryInterval": "100", "HwId": "TermoSensor-0a:01:01:01:01:02", "RxPin": "15", "TxPin": "13", "BaudRate": "9600", "Config": "SERIAL_8N1", "Ops": [ { "PollingInterval": "2000", "UnitId": "1", "Function": "0x04", "Address": "0x01", "Len": "1", "DisplayName": "Temp" }, { "PollingInterval": "2000", "UnitId": "1", "Function": "0x04", "Address": "0x02", "Len": "1", "DisplayName": "Humidity" } ] } } ]
Выложил библиотеку ModbusConfig, написанную для работы с конфигурационным файлом Modbus, на Github.