Modbus-client/en: различия между версиями

Материал из Wiren Board
(Новая страница: «== Command line call and arguments ==»)
(Новая страница: «Calling modbus_client without arguments will display a brief description of the possible arguments for the command: <syntaxhighlight lang="bash"> modbus_client [-…»)
Строка 15: Строка 15:
== Command line call and arguments ==
== Command line call and arguments ==


Вызов modbus_client без аргументов выдает краткое описание возможных аргументов команды:
Calling modbus_client without arguments will display a brief description of the possible arguments for the command:
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
modbus_client [--debug] [-m {rtu|tcp}] [-a<slave-addr=1>] [-c<read-no>=1]
modbus_client [--debug] [-m {rtu|tcp}] [-a<slave-addr=1>] [-c<read-no>=1]

Версия 20:12, 30 мая 2019

Другие языки:

General information

The modbus-client utility is used to communicate via Modbus RTU and Modbus TCP protocols from the command line. The main purpose of this utility is to use Modbus devices as a debugging or configuration tool. The modbus-client utility comes with a set of Wiren Board controller software. The utility is written in C language and uses the open libmodbus library. The fork of this utility, supplied with the Wiren Board devices, is stored here.

IMPORTANT: since the Modbus driver is running on the functioning Wiren Board controller, it must be stopped before working with the modbus-client — they cannot use the same RS-485 port together.

Commands to stop the service:

  • for Wiren Board 5 and above:
    service wb-mqtt-serial stop
    
  • for Wiren Board 4:
    service wb-homa-modbus stop
    

IMPORTANT: When writing any value, do not forget to specify the value itself! Otherwise, the registers may contain random information (see examples of use for details).


Command line call and arguments

Calling modbus_client without arguments will display a brief description of the possible arguments for the command:

modbus_client [--debug] [-m {rtu|tcp}] [-a<slave-addr=1>] [-c<read-no>=1]
        [-r<start-addr>=100] [-t<f-type>] [-o<timeout-ms>=1000] [{rtu-params|tcp-params}] serialport|host [<write-data>]
NOTE: if first reference address starts at 0, set -0
f-type:
        (0x01) Read Coils, (0x02) Read Discrete Inputs, (0x05) Write Single Coil
        (0x03) Read Holding Registers, (0x04) Read Input Registers, (0x06) WriteSingle Register
        (0x0F) WriteMultipleCoils, (0x10) Write Multiple register
rtu-params:
        b<baud-rate>=9600
        d{7|8}<data-bits>=8
        s{1|2}<stop-bits>=1
        p{none|even|odd}=even
tcp-params:
        p<port>=502
Examples (run with default mbServer at port 1502): 
        Write data:     modbus_client --debug -mtcp -t0x10 -r0 -p1502 127.0.0.1 0x01 0x02 0x03
        Read that data: modbus_client --debug -mtcp -t0x03 -r0 -p1502 127.0.0.1 -c3

Значения параметров (адрес, таймаут, тип функции и т.д.) можно указывать как в шестнадцатеричном (0x**), так и в десятичном виде.

  • Первый аргумент --debug — произвольный. Он может указываться в любой позиции и включает отладку, выводя на экран шестнадцатеричные коды отправляемых и принимаемых данных.
  • Следующий аргумент -m. Он должен указываться первым в командной строке, или вторым, если первый аргумент — --debug или имя файла порта RS-485. Аргумент определяет тип используемого протокола -mrtu — Modbus RTU, -mtcp — Modbus TCP.
  • Аргумент -a задает Modbus-адрес устройства, к которому мы обращаемся. Если аргумент не используется, то по умолчанию выбирается адрес 0x01.
  • Аргумент определяет, какое количество элементов мы запрашиваем. По умолчанию — один.
  • Аргумент -r задает начальный адрес для чтения или записи. По умолчанию используется значение 100 (0x64).
  • Аргумент -t указывает код функции Modbus. Кратко они перечислены в выводе modbus_client, подробнее значения кодов описаны на странице Протокол Modbus.
  • Аргумент -o задает таймаут в миллисекундах (по умолчанию 1000).
  • Аргумент -0 (ноль) уменьшает на единицу адрес, задаваемый аргументом -r. Это может быть полезным при работе с устройствами с нестандартной адресацией, например, с диапазоном адресов 1 — 65536 вместо привычного 0 — 65535.

Затем указываются специфические параметры протокола (Modbus RTU или Modbus TCP). Несмотря на информацию, выводимую в подсказке, эти параметры также начинаются со знака '-' (минус).

Для Modbus RTU:

  • -b — скорость передачи данных по последовательной линии (по умолчанию — 9600).
  • -d — количество передаваемых бит данных (7 или 8, по умолчанию — 8).
  • -s — количество стоповых битов (1 или 2, по умолчанию — 1).
  • -p — контроль четности (-p none — нет проверки, -p even — передается бит контроля на четность, -p odd — передается бит контроля на нечетность). По умолчанию передается бит контроля на четность(E).

Для Modbus TCP:

  • -p — номер TCP-порта устройства, с которым взаимодействует контроллер.


Далее следует имя файла порта RS-485 или адрес хоста, а в конце (факультативно, только для функций записи) — данные.


Примеры использования в Modbus RTU

Приведем несколько примеров, иллюстрирующих возможности данной утилиты.



1. Запись нового адреса устройства WB-MR14 в регистр 0x80, используя функцию 0x06 (Write Single Register).

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80 0x02

Где 0x02 - адрес, который нужно задать. Ответ:

Data to write: 0x2
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
[00][06][00][80][00][02][08][32]
Waiting for a confirmation...
ERROR Connection timed out: select
ERROR occured!

Сообщение об ошибке возникает всегда, когда запись производится на специальный адрес 0 (-a0x00). Теперь к устройству нужно обращаться по адресу 0x02.

Пример неправильного использования команды:

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80

Здесь не указан адрес, который нужно задать устройству и устройство получит неизвестный адрес. Для исправления, нужно обратиться к устройству по специальному адресу 0x00 (см. первую команду).


2. Проверка: читаем содержимое регистра 0x80 (теперь уже с устройства с адресом 0x02) с помощью функции 0x03 (Read Holding Registers). Заметим, что в устройствах Wiren Board функции 0x03 и 0x04 взаимозаменяемы и приводят к одному и тому же результату.

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a2 -t0x03 -r0x80

Ответ:

Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
[02][03][00][80][00][01][85][D1]
Waiting for a confirmation...
<02><03><02><00><02><7D><85>
SUCCESS: read 1 of elements:
        Data: 0x0002

3. Прочтем регистры релейного модуля WB-MR14 с адресом 0x01, содержащие сигнатуру устройства, WBMR14. Известно, что сигнатура хранится по адресу 200 и занимает 6 регистров.

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x03 -r200 -c 6

Ответ:

Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
[01][03][00][C8][00][06][44][36]
Waiting for a confirmation...
<01><03><0C><00><57><00><42><00><4D><00><52><00><31><00><34><D4><76>
SUCCESS: read 6 of elements:
        Data: 0x0057 0x0042 0x004d 0x0052 0x0031 0x0034

В ответе мы получили 6 16-битных значений, в каждом из которых содержится код одного ASCII-символа. Преобразуем их, заменив начальные 0x00 на /x и удалив пробелы, к виду \x57 и т.д., который понятен команде echo, и выведем на экран получившееся:

echo  -e `modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 \
-a1 -t0x03 -r200 -c 6 | \
grep Data | sed -e 's/0x00/\\\x/g' -e 's/Data://' -e 's/\s//g'`| xxd -r -p

Ответ:

WBMR14

В старых версиях прошивки

| xxd -r -p

не было нужно.



4. Определим текущий адрес устройства, подключенного к Wiren Board. Адрес нам неизвестен и мы не хотим его менять. Для этого в командной строке выполним циклическую команду опроса регистра 0x80 устройств с адресами с 1 по 247:

root@wirenboard:~# for i in {1..247}; do modbus_client -mrtu /dev/ttyAPP1 --debug -a$i -t3 -r0x80 -s2 -pnone; done 2>/dev/null | grep Data:

Ответ:

        Data: 0x0072

Результат: адрес подключенного устройства — 0x0072, то есть 114. Перебор всех адресов от 1 до 247 занимает чуть больше 2 минут.


5. На модуле WB-MR14 включим реле с номером 6 (адреса регистрв флагов начинаются с нуля, помним об этом!). Используем для этого команду 0x05 (Write Single Coil):

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x05 -r0x05 0x01

Ответ:

Data to write: 0x1
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
[01][05][00][05][FF][00][9C][3B]
Waiting for a confirmation...
<01><05><00><05><FF><00><9C><3B>
SUCCESS: written 1 elements!

Обратите внимание, утилита modbus_client при записи заменила 1 на 0x00FF, поскольку именно это значение служит для включения реле. Любое ненулевое значение будет заменено на 0x00FF, поэкспериментируйте.


6. Включим все нечетные реле и выключим все четные. Для этого используем функцию 15 (Write Multiple Coils). В модуле всего 14 реле, так что мы должны передать значения для 14 регистров с 0 по 13.

modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x0f -r0x00 -c 14 0x00FF 0x0000 0x00FF 0x0000 0x00FF 0x0000 0x00FF 0x0000 0x00FF 0x0000 0x00FF 0x0000 0x00FF 0x0000

Ответ:

Data to write: 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
[01][0F][00][00][00][0E][02][55][15][1A][97]
Waiting for a confirmation...
<01><0F><00><00><00><0E><D4><0F>
SUCCESS: written 14 elements!


Обратите внимание на структуру данных запроса:

  • [01] — адрес
  • [0F] — код функции Write Multiple Coils
  • [00][00] — адрес первого регистра флагов для записи
  • [00][0E] — количество элементов для записи (14)
  • [02] — количество байт данных (14 бит помещаются в 2 байтах)
  • [55][15] — 01010101 00010101 (первое реле — младший бит первого байта, 8 реле — старший бит первого байта, 9 реле — младший бит второго байта)
  • [1A][97] — CRC16

А так же на структуру ответа:

  • <01> — адрес
  • <0F> — код функции Write Multiple Coils
  • <00><00> — адрес первого регистра флагов для записи
  • <00><0E> — количество записанных регистров флагов
  • <D4><0F> — CRC16

Подробнее описание структуры данных запросов и ответов можно найти на странице Протокол Modbus.