From Wiren Board
Jump to navigation Jump to search
This page is a translated version of the page Modbus-client and the translation is 100% complete.
Other languages:
English • ‎русский

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
        (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
Examples (run with default mbServer at port 1502): 
        Write data:     modbus_client --debug -mtcp -t0x10 -r0 -p1502 0x01 0x02 0x03
        Read that data: modbus_client --debug -mtcp -t0x03 -r0 -p1502 -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)
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)
Waiting for a confirmation...
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)
Waiting for a confirmation...
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



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:


        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


Data to write: 0x1
Opening /dev/ttyAPP1 at 9600 bauds (N, 8, 2)
Waiting for a confirmation...
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


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)
Waiting for a confirmation...
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.