Функции записи Modbus: 0x05, 0x06, 0x0F, 0x10
Запись в Modbus устроена проще чтения: устройство подтверждает команду, возвращая её же — эхо запроса. Это удобно для проверки, но не означает, что значение реально применилось: подтверждается приём команды, а не результат.
0x05 — запись одного бита
Включаем выход с адресом 172 (0x00AC) у устройства 17:
11 05 00 AC FF 00 4E 8B
| Байты | Смысл |
|---|---|
| 11 | адрес устройства |
| 05 | функция |
| 00 AC | адрес бита — 172 |
| FF 00 | включить. Выключение — 00 00; других значений нет |
Ответ — точная копия запроса. Значение FF 00 непривычно: это не «255», а признак включения, заданный стандартом.
0x06 — запись одного регистра
Записываем значение 3 в регистр 1:
11 06 00 01 00 03 9A 9B
Ответ снова совпадает с запросом. Функция удобна для одиночных уставок: задать адрес устройства, скорость, порог срабатывания.
0x0F — запись нескольких битов
Запишем 10 бит начиная с адреса 19:
11 0F 00 13 00 0A 02 CD 01 BF 0B
| Байты | Смысл |
|---|---|
| 00 13 | начальный адрес — 19 |
| 00 0A | количество бит — 10 |
| 02 | сколько байт данных дальше |
| CD | биты 19–26: 1100 1101, младший разряд — бит 19 |
| 01 | биты 27–28: значащие только два младших разряда, остальные — нули |
Ответ короткий — устройство подтверждает адрес и количество, но не повторяет сами данные:
11 0F 00 13 00 0A 26 99
0x10 — запись нескольких регистров
Записываем два регистра со значениями 10 и 258 начиная с адреса 1:
11 10 00 01 00 02 04 00 0A 01 02 C6 F0
| Байты | Смысл |
|---|---|
| 10 | функция |
| 00 01 | начальный адрес |
| 00 02 | количество регистров |
| 04 | число байт данных: два регистра по два байта |
| 00 0A | первый регистр — 10 |
| 01 02 | второй регистр — 0x0102 = 258 |
Подтверждение:
11 10 00 01 00 02 12 98
Именно эта функция нужна для записи 32-битных значений и чисел с плавающей точкой: они занимают два регистра, и записать их надо одной командой, иначе устройство на мгновение увидит «половину» числа.
Тот же запрос в Modbus TCP
0A 2C 00 00 00 06 11 06 00 01 00 03
PDU не изменился — только вместо адреса и CRC появился заголовок с номером транзакции 0x0A2C, нулевым идентификатором протокола, длиной 6 и идентификатором устройства 17.
Что стоит помнить при записи
- Эхо не гарантирует применения. Устройство подтверждает приём. Проверять надо чтением того же регистра — особенно для уставок, которые прибор может ограничить своими пределами.
- Широковещательная запись. Адрес 0 в RTU означает «всем»: команда выполняется всеми ведомыми, ответа нет ни от кого. Функции чтения так использовать нельзя.
- Права и защита. Многие приборы принимают запись только после снятия аппаратной или программной блокировки — молчаливый отказ здесь редкость, обычно возвращается исключение 0x04 или 0x02.
- Атомарность. Пара регистров, образующих одно 32-битное число, должна писаться функцией 0x10 за один раз.
- Повтор после тайм-аута опасен. Если ответ потерян, а команда дошла, повтор выполнит операцию дважды. Для счётчиков импульсов и команд управления это критично — сначала прочитайте состояние.
