Modbus TCP Programming and Experimentation

Modbus TCP Programming and Experimentation

11.7 Modbus TCP Programming and Experimentation

This course does not support sensors that use the Modbus TCP protocol, so we will write two programs:

① modbus_server_tcp.c: Simulate a Modbus TCP sensor

② modbus_client_tcp.c: Operate the sensor

The program structure is shown in the figure below:

Modbus TCP Programming and Experimentation

No special connections are required on the hardware.

The source code for this section is located in the following directory:

Modbus TCP Programming and Experimentation

Next, we will explain the code using a scenario analysis method. Suppose the following commands are executed on the development board:

Swipe left and right to view the complete content

# ./modbus_server_tcp 127.0.0.1 &# ./modbus_client_tcp 127.0.0.1 led1 on
Modbus TCP Programming and Experimentation

11.7.1 Server Initialization and Waiting for Connection

In “modbus_server_tcp.c”, the code is as follows:

Swipe left and right to view the complete content

41 ctx = modbus_new_tcp(argv[1], 1502);42 if (ctx == NULL) {43 fprintf(stderr, "Unable to allocate libmodbus context\n");44 return -1;45 }4647 //modbus_set_slave(ctx, SERVER_ID);4849 mb_mapping = modbus_mapping_new_start_address(0,50 NB_BITS, /* 5 DO registers, corresponding to beep1, beep2, led1, led2, led3 */51 0,52 NB_INPUT_BITS,53 0,54 NB_REGISTERS,55 0,56 NB_INPUT_REGISTERS); /* 2 AI registers, corresponding to temperature and humidity */57 memset(mb_mapping->tab_bits, 0, NB_BITS);58 memset(mb_mapping->tab_input_registers, 0, NB_INPUT_REGISTERS*2);5960 memset(old_bits, 0, NB_BITS);61 memset(old_regs, 0, NB_INPUT_REGISTERS*2);6263 s = modbus_tcp_listen(ctx, 1);64 modbus_tcp_accept(ctx, &s);
  • Line 41: Allocates a modbus_t structure containing the IP and port.

  • Line 47: Sets the sensor address, this line is commented out, in the Modbus TCP protocol, even if the client sends requests with different device addresses, the server will receive all these requests (it ignores the device address).

  • Lines 49~56: Allocates Modbus registers. It simulates a sensor based on the “11.5.2 Sensor Point Table”.

  • Lines 57~58: Initializes the DO and AI registers to 0.

  • Lines 60~61: Sets the values of two arrays to 0; these two arrays will be used to compare with the Modbus registers to determine if the Client program has modified these values.

  • Lines 63~64: This is different from the Modbus RTU protocol; they initialize the socket and wait for a client connection.

Modbus TCP Programming and Experimentation

11.7.2 Client Initialization and Connection Request

In “modbus_client_tcp.c”, the code is as follows:

Swipe left and right to view the complete content

33 ctx = modbus_new_tcp(argv[1], 1502);34 if (ctx == NULL) {35 fprintf(stderr, "Unable to allocate libmodbus context\n");36 return -1;37 }3839 modbus_set_slave(ctx, SERVER_ID);4041 if (modbus_connect(ctx) == -1) {42 fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));43 modbus_free(ctx);44 return -1;45 }
  • Line 33: Allocates a modbus_t structure, setting the IP and port.

  • Line 39: Sets the Modbus sensor address to access.

  • Line 41: Sends a connection request.

Modbus TCP Programming and Experimentation

11.7.3 Server Waiting for Request

In “modbus_server_tcp.c”, the code is as follows:

Swipe left and right to view the complete content

66 while (1)67 {68 do {69 rc = modbus_receive(ctx, query);70 /* Filtered queries return 0 */71 } while (rc == 0);72
  • Line 69: Waits for a client to send a request.

Modbus TCP Programming and Experimentation

11.7.4 Client Sends Request

In “modbus_client_tcp.c”, the code is as follows:

Swipe left and right to view the complete content

65 if (!strcmp(argv[2], "beep1"))66 addr = 0;67 if (!strcmp(argv[2], "beep2"))68 addr = 1;69 if (!strcmp(argv[2], "led1"))70 addr = 2;71 if (!strcmp(argv[2], "led2"))72 addr = 3;73 if (!strcmp(argv[2], "led3"))74 addr = 4;7576 if (addr == -1)77 {78 usage(argv[0]);79 return -1;80 }8182 if (!strcmp(argv[3], "on"))83 status = 1;84 else85 status = 0;8687 rc = modbus_write_bit(ctx, addr, status);88 if (rc == 1)89 {90 printf("modbus_write_bit ok\r\n");91 }92 else93 {94 printf("modbus_write_bit err: %d, %s\r\n", rc, strerror(errno));95 }
  • Lines 65~85: Set addr and status based on parameters.

  • Line 87: Sends a request to “write AO register”.

Modbus TCP Programming and Experimentation

11.7.5 Server Processes Request and Responds

In “modbus_server_tcp.c”, the code is as follows:

Swipe left and right to view the complete content

75 if (rc >= 0) {7677 printf("Get query for UID %d\r\n", query[6]);7879 /* Simulate temperature and humidity using random numbers */80 mb_mapping->tab_input_registers[0] = rand() % 1000; /* Temperature, unit: 0.1C */81 mb_mapping->tab_input_registers[1] = rand() % 1000; /* Humidity, unit: 0.1% */8283 rc = modbus_reply(ctx, query, rc, mb_mapping);84 }85 if (rc == -1) {86 printf("Connection closed!\r\n");87 modbus_close(ctx);88 modbus_tcp_accept(ctx, &s);89 }9091 /* Based on the values set by the client, pretend to operate the buzzer and LED */92 if (mb_mapping->tab_bits[0] != old_bits[0])93 {94 printf("set beep1 %s\r\n", mb_mapping->tab_bits[0] ? "on" : "off");95 old_bits[0] = mb_mapping->tab_bits[0];96 }9798 if (mb_mapping->tab_bits[1] != old_bits[1])99 {100 printf("set beep2 %s\r\n", mb_mapping->tab_bits[1] ? "on" : "off");101 old_bits[1] = mb_mapping->tab_bits[1];102 }103104 if (mb_mapping->tab_bits[2] != old_bits[2])105 {106 printf("set led1 %s\r\n", mb_mapping->tab_bits[2] ? "on" : "off");107 old_bits[2] = mb_mapping->tab_bits[2];108 }109110 if (mb_mapping->tab_bits[3] != old_bits[4])111 {112 printf("set led2 %s\r\n", mb_mapping->tab_bits[4] ? "on" : "off");113 old_bits[3] = mb_mapping->tab_bits[4];114 }115116 if (mb_mapping->tab_bits[4] != old_bits[4])117 {118 printf("set led3 %s\r\n", mb_mapping->tab_bits[4] ? "on" : "off");119 old_bits[4] = mb_mapping->tab_bits[4];120 }
  • Line 77: Prints the “device address” from the request packet sent by the client; you can use this “device address” to operate different devices, but this program does not use it.

  • Lines 80~81: Fills the AO registers with random numbers to simulate temperature and humidity. If the client reads the temperature and humidity, the “modbus_reply” on line 83 will respond with these values.

  • Line 83: Uses “modbus_reply” to send a response packet to the client.

  • Lines 85~89: If there is an error, wait for the client to establish a connection again.

  • Lines 91~120: Operates the hardware based on the data sent by the client (here, it only prints information).

Modbus TCP Programming and Experimentation

11.7.6 Hands-on Experiment

Upload the code to Ubuntu.

Then, execute the following command in Ubuntu to compile:

Swipe left and right to view the complete content

$ source /opt/remi-sdk/environment-setup-aarch64-poky-linux$ make$ scp modbus_client_tcp [email protected]:/home/root$ scp modbus_server_tcp [email protected]:/home/root

Finally, execute the following commands on the development board (first execute modbus_server):

Swipe left and right to view the complete content

# cd /home/root# ./modbus_server_tcp 127.0.0.1 &# ./modbus_client_tcp 127.0.0.1 led1 onGet query for UID 4set led1 onmodbus_write_bit okConnection closed!# ./modbus_client_tcp 127.0.0.1 readGet query for UID 4Temperature = 38.6C, Humidity = 49.2%Get query for UID 4Temperature = 64.9C, Humidity = 42.1%Get query for UID 4Temperature = 36.2C, Humidity = 2.7%
Modbus TCP Programming and Experimentation
Modbus TCP Programming and Experimentation

Need product and solution support?

Please scan the code to register

Modbus TCP Programming and Experimentation

Need technical support?

If you have any questions while using Renesas MCU/MPU products, you can scan the QR code below or copy the URL into your browser to open the Renesas Technical Forum to find answers or get online technical support.

Modbus TCP Programming and Experimentation

https://community-ja.renesas.com/zh/forums-groups/mcu-mpu/

To be continued

Recommended Reading

Modbus TCP Programming and Experimentation

libmodbus Scenario Analysis – RZ MPU Industrial Control Tutorial Series (39)

Modbus TCP Programming and Experimentation

Master Device Read Response and Common Interface Functions – RZ MPU Industrial Control Tutorial Series (40)

Modbus TCP Programming and Experimentation

Modbus Interface and Data Processing – RZ MPU Industrial Control Tutorial Series (41)

For more exciting content, please follow us

Modbus TCP Programming and Experimentation
Modbus TCP Programming and Experimentation
Modbus TCP Programming and Experimentation
Modbus TCP Programming and Experimentation

Need product and solution support?

Please scan the code to register

Leave a Comment