modbus_slave - эмулятор Modbus RTU устройств
Утилита modbus_slave эмулирует до 30 независимых Modbus RTU slave-устройств на одном последовательном порту. Для мастера (ПЛК, SCADA) всё выглядит так, как будто на шине RS-485 подключены реальные приборы.
Для чего это нужно
- Проверить мастер-опросник, когда физических датчиков нет под рукой
- Показать демо заказчику без реального оборудования
- Нагрузочное тестирование шины - запустить 30 устройств одной командой
- Подать в мастер реальные данные (температура CPU, время, показания I2C/1-Wire) через файлы
Быстрый старт
Скачайте готовый бинарь из репозитория для своей платформы:
| Файл | Платформа |
|---|---|
bin/modbus_slave | Linux x86_64 |
bin/modbus_slave_aarch64 | Linux aarch64 (NAPI, Сборщики) |
bin/modbus_slave.exe | Windows x64 |
Запуск одного устройства с рандомными регистрами:
./modbus_slave -p /dev/ttyUSB0 -b 115200
Теперь по адресу 1 на порту /dev/ttyUSB0 отвечает виртуальный Modbus-slave с 20 регистрами (FC03). Значения случайные, обновляются при каждом запросе.
Проверка с помощью mbpoll:
mbpoll -a 1 -b 115200 -r 1 -c 10 /dev/ttyUSB0
Несколько устройств
Запуск 5 устройств на одном порту (slave ID 1..5):
./modbus_slave -p /dev/ttyUSB0 -b 115200 -a 5
Максимум -- 30 устройств. Каждое отвечает на FC03 (Read Holding Registers), 20 регистров по адресам 0..19.
Реальные данные из файлов
По умолчанию регистры заполняются случайными числами. Но можно привязать к устройству текстовый файл - одно число на строку, до 20 строк:
./modbus_slave -p /dev/ttyUSB0 -b 115200 -a 3 \
-f 1:/tmp/cpu.dat \
-f 2:/tmp/time.dat
Здесь slave 1 читает регистры из /tmp/cpu.dat, slave 2 - из /tmp/time.dat, а slave 3 отдаёт случайные значения.
Формат файла - просто числа, по одному на строку:
42
1024
65535
0
Скрипты-источники
В каталоге scripts/ лежат примеры скриптов, которые пишут данные в файлы:
cpu_temp_to_modbus.sh - температура процессора:
#!/bin/bash
while true; do
temp=$(cat /sys/class/thermal/thermal_zone0/temp)
echo $((temp / 1000)) > /tmp/cpu.dat
sleep 1
done
time_to_modbus.sh - текущее время (часы, минуты, секунды в отдельных регистрах):
#!/bin/bash
while true; do
echo $(date +%H) > /tmp/time.dat
echo $(date +%M) >> /tmp/time.dat
echo $(date +%S) >> /tmp/time.dat
sleep 1
done
Можно написать свой скрипт, который читает данные с любого источника (I2C, 1-Wire, sysfs, MQTT, HTTP API) и пишет числа в файл. Файлы рекомендуется размещать в /tmp -- это tmpfs (RAM-диск), SD-карта не изнашивается.