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

Материал из Wiren Board
(Новая страница: «In older firmware versions <syntaxhighlight lang="bash">| xxd -r -p</syntaxhighlight> wasn't necessary»)
Строка 120: Строка 120:
<syntaxhighlight lang="bash">WBMR14</syntaxhighlight>
<syntaxhighlight lang="bash">WBMR14</syntaxhighlight>


В старых версиях прошивки <syntaxhighlight lang="bash">| xxd -r -p</syntaxhighlight> не было нужно.
In older firmware versions <syntaxhighlight lang="bash">| xxd -r -p</syntaxhighlight> wasn't necessary





Версия 20:23, 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

Parameter values (address, timeout, function type, etc.) can be specified in both hexadecimal (0x**) and decimal.

  • The first argument --debug — is arbitrary. It can be specified in any position and enables debugging by displaying the hexadecimal codes of the data being sent and received.
  • The next argument is -m. It must be specified first on the command line, or second if the first argument is --debug or the file name of the RS-485 port. The argument specifies the type of Protocol used -mrtu — Modbus RTU, -mtcp — Modbus TCP.
  • The -a argument specifies the Modbus address of the device we are accessing. If the argument is not used, the default address is 0x01.
  • The -c argument determines how many items we request. The default value is one.
  • The -r argument specifies the start address for reading or writing. The default value is 100 (0x64).
  • The-t argument specifies the Modbus function code. They are briefly listed in the modbus_client output, the code values are described in more detail on the Modbus Protocol page.
  • The -o argument specifies a timeout in milliseconds (the default is 1000).
  • The -0 (zero) argument reduces the address specified by the -r argument by one. This can be useful when working with devices with non-standard addressing, for example, with the address range 1 — 65536 instead of the usual 0 — 65535.

Then you enter the specific parameters of the protocol (Modbus RTU or Modbus TCP). Despite the information displayed in the tooltip, these parameters also start with a '-' (minus) sign.

For Modbus RTU:

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

For Modbus TCP:

  • -p — TCP port number of the device which the controller communicates with.


This is followed by the file name of the RS-485 port or host address, and at the end (optional, only for recording functions) — data.


Examples of use in Modbus RTU

Here are some examples illustrating the capabilities of this utility.



1. Write the new address of the WB-MR14 device to the 0x80 register using the 0x06 (Write Single Register) function.

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

Where 0x02 is the address to be set. Answer:

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!

The error message always occurs when writing to the special address 0 (-a0x00). Now the device needs to contact us at the address 0x02.

An example of improper use:

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

It does not specify the address to be given to the device and the device will receive an unknown address. To fix this, you need to access the device at the special address 0x00 (see the first command).


2. Check: read the contents of the register 0x80 (now from the device with the address 0x02) using the function 0x03 (Read Holding Registers). Note that in Wiren Board devices, the functions 0x03 and 0x04 are interchangeable and lead to the same result.

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. Read the registers of the relay module WB-MR14 with address 0x01, containing the signature of the device, WBMR14. It is known that the signature is stored at 200 and occupies 6 registers.

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

In the answer we received 6 16-bit values, each of which contains the code of one ASCII-character. Convert them, replacing the initial 0x00 with /x and removing spaces, to the form \x57, etc, which is understandable to the echo command, and display the resulting:

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

Answer:

WBMR14

In older firmware versions

| xxd -r -p

wasn't necessary



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.