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

Материал из Wiren Board
(Новая страница: «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.»)
(Новая страница: «More detailed description of the request and response data structure can be found on the Modbus Protocol page.»)
 
(не показано 20 промежуточных версий этого же участника)
Строка 65: Строка 65:


<span id="примеры-использования в modbus rtu"></span>
<span id="примеры-использования в modbus rtu"></span>
== Примеры использования в Modbus RTU ==
== Examples of use in Modbus RTU ==


Приведем несколько примеров, иллюстрирующих возможности данной утилиты.
Here are some examples illustrating the capabilities of this utility.




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


<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80 0x02</syntaxhighlight>
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80 0x02</syntaxhighlight>
Где 0x02 - адрес, который нужно задать.
Where 0x02 is the address to be set.  
Ответ:
Answer:
<syntaxhighlight lang="bash">Data to write: 0x2
<syntaxhighlight lang="bash">Data to write: 0x2
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Строка 83: Строка 83:
ERROR occured!</syntaxhighlight>  
ERROR occured!</syntaxhighlight>  


Сообщение об ошибке возникает всегда, когда запись производится на специальный адрес 0 (-a0x00). Теперь к устройству нужно обращаться по адресу 0x02.
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:
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80</syntaxhighlight>
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a0x00 -t0x06 -r0x80</syntaxhighlight>
Здесь не указан адрес, который нужно задать устройству и устройство получит неизвестный адрес. Для исправления, нужно обратиться к устройству по специальному адресу 0x00 (см. первую команду).
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. Проверка: читаем содержимое регистра 0x80 (теперь уже с устройства с адресом 0x02) с помощью функции 0x03 (Read Holding Registers). Заметим, что в устройствах Wiren Board функции 0x03 и 0x04 взаимозаменяемы и приводят к одному и тому же результату.
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.


  <syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a2 -t0x03 -r0x80</syntaxhighlight>     
  <syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a2 -t0x03 -r0x80</syntaxhighlight>     
Строка 102: Строка 102:


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


<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x03 -r200 -c 6</syntaxhighlight>
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x03 -r200 -c 6</syntaxhighlight>
Строка 113: Строка 113:
         Data: 0x0057 0x0042 0x004d 0x0052 0x0031 0x0034 </syntaxhighlight>
         Data: 0x0057 0x0042 0x004d 0x0052 0x0031 0x0034 </syntaxhighlight>


В ответе мы получили 6 16-битных значений, в каждом из которых содержится код одного ASCII-символа. Преобразуем их, заменив начальные '''0x00''' на '''/x''' и удалив пробелы, к виду \x57 и т.д., который понятен команде echo, и выведем на экран получившееся:
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:
<syntaxhighlight lang="bash">echo  -e `modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 \
<syntaxhighlight lang="bash">echo  -e `modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 \
-a1 -t0x03 -r200 -c 6 | \
-a1 -t0x03 -r200 -c 6 | \
grep Data | sed -e 's/0x00/\\\x/g' -e 's/Data://' -e 's/\s//g'`| xxd -r -p </syntaxhighlight>
grep Data | sed -e 's/0x00/\\\x/g' -e 's/Data://' -e 's/\s//g'`| xxd -r -p </syntaxhighlight>
Ответ:
Answer:
<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




----
----
4. Определим текущий адрес устройства, подключенного к Wiren Board. Адрес нам неизвестен и мы не хотим его менять.
4. Determine the current address of the device connected to the Wiren Board. The address is unknown to us and we do not want to change it. To do this, at the command line, run a cyclic command to poll the register of 0x80 devices with addresses from 1 to 247:
Для этого в командной строке выполним циклическую команду опроса регистра 0x80 устройств с адресами с 1 по 247:
<syntaxhighlight lang="bash">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: </syntaxhighlight>
<syntaxhighlight lang="bash">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: </syntaxhighlight>
Ответ:      
Answer      
<syntaxhighlight lang="bash">        Data: 0x0072</syntaxhighlight>
<syntaxhighlight lang="bash">        Data: 0x0072</syntaxhighlight>
Результат: адрес подключенного устройства — 0x0072, то есть 114. Перебор всех адресов от 1 до 247 занимает чуть больше 2 минут.
Result: the address of the connected device is 0x0072, i.e. 114. It takes a little more than 2 minutes to search all addresses from 1 to 247.


----
----
5. На модуле WB-MR14 включим реле с номером 6 (адреса регистрв флагов начинаются с нуля, помним об этом!). Используем для этого команду 0x05 (Write Single Coil):
5.5. Let's turn on relay 6 on WB-MR14 relay module(addresses of flags registers start from zero, remember that!). Use the command 0x05 (Write Single Coil):
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x05 -r0x05 0x01</syntaxhighlight>
<syntaxhighlight lang="bash">modbus_client --debug -mrtu -pnone -s2 /dev/ttyAPP1 -a1 -t0x05 -r0x05 0x01</syntaxhighlight>
Ответ:
Answer:
<syntaxhighlight lang="bash">Data to write: 0x1
<syntaxhighlight lang="bash">Data to write: 0x1
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Строка 142: Строка 141:
SUCCESS: written 1 elements!</syntaxhighlight>
SUCCESS: written 1 elements!</syntaxhighlight>


Обратите внимание, утилита modbus_client при записи заменила 1 на 0x00FF, поскольку именно это значение служит для включения реле. Любое ненулевое значение будет заменено на 0x00FF, поэкспериментируйте.
Note that the modbus_client utility replaced 1 with 0x00FF when recording, because this value is used to turn on the relay. Any nonzero value is changed to 0x00FF, give it a try.


----
----
6. Включим все нечетные реле и выключим все четные. Для этого используем функцию 15 (Write Multiple Coils). В модуле всего 14 реле, так что мы должны передать значения для 14 регистров с 0 по 13.
6. Turn on all the odd relays and turn off all the even ones. To do this, use the function 15 (Write Multiple Coils). There are only 14 relays in the module, so we have to pass values for 14 registers from 0 to 13.


<syntaxhighlight lang="bash">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</syntaxhighlight>
<syntaxhighlight lang="bash">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</syntaxhighlight>
Ответ:
Answer:
<syntaxhighlight lang="bash">Data to write: 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00 0xff 0x00  
<syntaxhighlight lang="bash">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)
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Строка 157: Строка 156:




Обратите внимание на структуру данных запроса:
Note the structure of the query data:


*[01] — адрес
*[01] — address
*[0F] — код функции Write Multiple Coils
*[0F] — write Multiple Coils function code
*[00][00] — адрес первого регистра флагов для записи
*[00][00] — address of the first flag register to be recorded
*[00][0E] — количество элементов для записи (14)
*[00][0E] — number of items to record (14)
*[02] — количество байт данных (14 бит помещаются в 2 байтах)
*[02] — number of data bytes (14 bits are placed in 2 bytes)
*[55][15] — 01010101 00010101 (первое реле — младший бит первого байта, 8 реле — старший бит первого байта, 9 реле — младший бит второго байта)
*[55][15] — 01010101 00010101 (the first relay is the lowest bit of the first byte, 8th relay is the highest bit of the first byte, 9th relay is the lowest bit of the second byte)
*[1A][97] — CRC16
*[1A][97] — CRC16


А так же на структуру ответа:
As well as note the structure of the answer:


*<01> — адрес
*<01> — address
*<0F> — код функции Write Multiple Coils
*<0F> — write Multiple Coils function code
*<00><00> — адрес первого регистра флагов для записи
*<00><00> — address of the first flag register to be recorded
*<00><0E> — количество записанных регистров флагов
*<00><0E> — number of recorded flag registers
*<D4><0F> — CRC16
*<D4><0F> — CRC16


Подробнее описание структуры данных запросов и ответов можно найти на странице [[Special:MyLanguage/Протокол Modbus|Протокол Modbus]].
More detailed description of the request and response data structure can be found on the [[Протокол Modbus/en|Modbus Protocol]] page.

Текущая версия на 20:30, 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. Determine the current address of the device connected to the Wiren Board. The address is unknown to us and we do not want to change it. To do this, at the command line, run a cyclic command to poll the register of 0x80 devices with addresses from 1 to 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:

Answer

        Data: 0x0072

Result: the address of the connected device is 0x0072, i.e. 114. It takes a little more than 2 minutes to search all addresses from 1 to 247.


5.5. Let's turn on relay 6 on WB-MR14 relay module(addresses of flags registers start from zero, remember that!). Use the command 0x05 (Write Single Coil):

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

Answer:

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!

Note that the modbus_client utility replaced 1 with 0x00FF when recording, because this value is used to turn on the relay. Any nonzero value is changed to 0x00FF, give it a try.


6. Turn on all the odd relays and turn off all the even ones. To do this, use the function 15 (Write Multiple Coils). There are only 14 relays in the module, so we have to pass values for 14 registers from 0 to 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

Answer:

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!


Note the structure of the query data:

  • [01] — address
  • [0F] — write Multiple Coils function code
  • [00][00] — address of the first flag register to be recorded
  • [00][0E] — number of items to record (14)
  • [02] — number of data bytes (14 bits are placed in 2 bytes)
  • [55][15] — 01010101 00010101 (the first relay is the lowest bit of the first byte, 8th relay is the highest bit of the first byte, 9th relay is the lowest bit of the second byte)
  • [1A][97] — CRC16

As well as note the structure of the answer:

  • <01> — address
  • <0F> — write Multiple Coils function code
  • <00><00> — address of the first flag register to be recorded
  • <00><0E> — number of recorded flag registers
  • <D4><0F> — CRC16

More detailed description of the request and response data structure can be found on the Modbus Protocol page.