Wiznet makers

ronpang

Published December 11, 2023 ©

125 UCC

10 WCC

32 VAR

0 Contests

1 Followers

0 Following

Original Link

25. W5100S/W5500+RP2040 Raspberry Pi Pico<Modebus TCP Server Example>

25. W5100S/W5500+RP2040 Raspberry Pi Pico<Modebus TCP Server Example>

COMPONENTS Hardware components

WIZnet - W5100S-EVB-Pico

x 1


WIZnet - W5500-EVB-Pico

x 1


PROJECT DESCRIPTION

1 Introduction

Modbus TCP protocol is a data communication protocol widely used in industrial automation, building automation, energy management and other fields. It is based on the TCP/IP network, encapsulates the Modbus protocol in the TCP/IP protocol stack, uses Ethernet as the physical layer, and implements communication between devices through TCP connections.

 W5100S/W5500 is an embedded Ethernet controller integrating a full hardware TCP/IP protocol stack. It is also an industrial-grade Ethernet control chip. This tutorial will introduce the basic principles, usage steps, application examples and precautions of W5100S/W5500 Ethernet FTP application to help readers better master this technology.

2 Protocol Introduction

2.1 What is Modbus TCP?

Modbus TCP is essentially the Modbus protocol (or Modbus RTU) running on an Ethernet TCP/IP network. Like Modbus RTU, Modbus TCP also works on the client/server principle, but in this case the client (master device) initiates requests and responses from the server (slave device). Any device can be a client or server.

Modbus TCP does not need to calculate the checksum because the lower layers already provide checksum protection. It uses the 10 Mbps Ethernet standard to transmit the entire structure of Modbus messages. Modbus TCP protocol provides fast communication between many devices in a single network.

2.2 Introduction to Modbus TCP instructions

The data frame of the Modbus TCP protocol can be divided into two parts: MBAP and PDU.

MBAP (Modbus Application Protocol header):

Transaction identification: an incrementing number, incremented each time a message is sent, and try not to repeat it. Because it occupies 2 bytes, the range is: 0~65535.  Protocol identification: Fixed value 0, indicating Modbus TCP protocol.  Length: equal to the length of the following field.  Unit identifier: slave address, also known as slave id. PDU (Protocol Data Unit):

Function code: Modbus stipulates multiple functions, and each function is set with a function code. What operation do you want to perform on the slave machine? Just set it here. The slave machine will know what to do after reading this data.  Data: For the master, it means what data in the slave register it wants to operate.

A variety of function codes are defined in the Modbus TCP protocol, including:

0x01: Read coil 0x05: Write a single coil 0x0F: Write multiple coils 0x02: Read discrete input 0x04: Read input register 0x03: Read holding register 0x06: Write a single holding register 0x10: Write multiple holding registers Each function code corresponds to Both operations and data formats differ.

For example, function code 0x01 is used to read coils, and the request format is "MBAP function code starting address H starting address L quantity H quantity L"

The response format is "MBAP function code data length data".

2.3 Requesting data process

During a typical Modbus TCP communication:

A Modbus TCP client (also called a master device) sends a request to a Modbus TCP server (also called a slave device). This request contains a function code (indicating the type of operation to be performed) and may also include a data address and value, depending on the function code.

After receiving the request, the Modbus TCP server processes it according to the function code. For example, if the function code indicates a read operation, the server will access the specified data address in its memory and prepare the corresponding data in response.

The Modbus TCP server then sends a response to the client. This response contains the function code and the requested data (for read operations) or a confirmation of the performed operation (for write operations).

The Modbus TCP client receives the server's response and processes the data as necessary.

2.4 Advantages of Modbus TCP protocol

The advantages of MODBUS TCP protocol include:

Flexible network topology: MODBUS TCP is based on Ethernet communication, so its network topology is more flexible. From the structure of one master and multiple slaves on the serial link, it has evolved into the structure model of multi-client/multi-server.

Easy to address: Using MODBUS TCP, the master device (client) can find the MODBUS slave device (server) by IP address and connect to another MODBUS RTU network through the MODBUS gateway.

Master-slave mode: The working principle of MODBUS protocol is based on the master-slave mode. In a network, the MODBUS protocol exchanges information through a request-response mechanism between the master device (client) and the slave device (server). This model makes the communication process clear and easy to understand.

Openness: MODBUS is an open protocol, which means it can be supported by equipment from any manufacturer, thereby improving interoperability between devices.

Simplicity: The MODBUS protocol is simple to understand, easy to implement and maintain.

Efficiency: MODBUS TCP protocol runs on the TCP/IP network, taking advantage of the advantages of the TCP/IP protocol, such as efficient data transmission, error detection and repair, etc.

2.5 Modbus TCP application scenarios

The Modbus TCP protocol has a wide range of application scenarios. The following are some main areas:

Industrial automation: Modbus TCP protocol is widely used in the field of industrial automation, especially in smart manufacturing and industrial Internet of Things. It allows reliable communication between devices to automate and control production processes.

Building automation: In the field of building automation, Modbus TCP protocol can be used to connect building equipment (such as temperature controllers, lighting systems, security systems, etc.) to achieve energy saving and comfortable indoor environment.

Energy Management: In the field of energy management, the Modbus TCP protocol can be used to monitor and control energy usage in systems. By connecting energy measurement equipment and control systems, real-time energy monitoring and optimized control can be achieved, reducing energy consumption and improving energy efficiency.

Process control: In the field of process control, Modbus TCP protocol can be used to connect sensors and actuators to achieve real-time monitoring and control. It can be applied in various industrial processes such as chemical industry, pharmaceuticals, food processing, etc.

Smart home: In the field of smart home, Modbus TCP protocol can be used to connect smart home devices (such as smart light bulbs, smart sockets, smart security, etc.) to achieve home automation and smart control.

 

3 WIZnet Ethernet chip

WIZnet mainstream hardware protocol stack Ethernet chip parameter comparison

ModelEmbedded CoreHost I/FTX/RX BufferHW SocketNetwork Performance
W5100STCP/IPv4, MAC & PHY8bit BUS, SPI16KB4Max.25Mbps
W6100TCP/IPv4/IPv6, MAC & PHY8bit BUS, Fast SPI32KB8Max.25Mbps
W5500TCP/IPv4, MAC & PHYFast SPI32KB8Max 15Mbps

W5100S/W6100 supports 8-bit data bus interface, and the network transmission speed will be better than W5500.

W6100 supports IPV6 and is compatible with W5100S hardware. If users who already use W5100S need to support IPv6, they can be Pin to Pin compatible.

W5500 has more Sockets and send and receive buffers than W5100S.

4 Modbus TCP example overview and usage

4.1 Flowchart

The running block diagram of the program is as follows:

4.2 Core preparation work

Software

Visual Studio Code

WIZnet UartTool

Modbus Poll

Hardware

W5100S IO module + RP2040 Raspberry Pi Pico development board or WIZnet W5100S-EVB-Pico development board

Micro USB interface data cable

TTL to USB

cable

4.3 Connection method

Connect the USB port of the PC through the data cable (mainly used for burning programs, but can also be used as a virtual serial port)

Convert TTL serial port to USB and connect the default pin of UART0:

RP2040 GPIO0 (UART0 TX) <----> USB_TTL_RX

RP2040 GPIO1 (UART0 RX) <----> USB_TTL_TX

When wiring using module connection RP2040

RP2040 GPIO16 <----> W5100S MISO

RP2040 GPIO17 <----> W5100S CS

RP2040 GPIO18 <----> W5100S SCK

RP2040 GPIO19 <----> W5100S MOSI

RP2040 GPIO20 <----> W5100S RST

Connect the PC and device to the router LAN port through network cables

4.4 Main code overview

We are using the official ioLibrary_Driver library of WIZnet. The library supports rich protocols and is easy to operate. The chip integrates the TCP/IP protocol stack on the hardware. The library also encapsulates the protocols above the TCP/IP layer. We only need to simply call the corresponding function to complete the application of the protocol. .

Step 1: Reference the corresponding library file in the modbus_tcp.c file.

Step 2: Define macro constants and define global variables.

Step 3: Define two functions, including a 1-second timer callback function (used to handle DHCP timeout processing) and a function to set the network address.

Step 4: The main function first initializes the serial port and SPI and detects the link. Then set the network address of W5100S. First use DHCP to obtain it. If it fails, use the preset static IP address. Then initialize the LED GPIO. Finally, the Modbus TCP state machine program is run in the main loop.

Step 5: In the state machine, first open a socket in TCP Server mode, and then wait for the client to connect. After the connection is successful, it will wait for the client's request information. After receiving the request information, it will parse the package content and respond with operations and replies.

/* main function */
int main()
{
   struct repeating_timer timer; // Define the timer structure

   /*mcu init*/
   stdio_init_all();     // Initialize the main control periphera
   wizchip_initialize(); // spi initialization
   wizchip_setnetinfo(&net_info); // Configure once first
   
   /*dhcp init*/
   DHCP_init(SOCKET_ID, ethernet_buf);                                        // DHCP initialization
   add_repeating_timer_ms(1000, repeating_timer_callback, NULL, &timer); // Add DHCP 1s Tick Timer handler

   printf("wiznet chip modbus tcp server example.\r\n");
   network_init(&net_info);              // Configuring Network Information
   print_network_information(&get_info); // Read back the configuration information and print it

   /* LED gpio init */
   gpio_init(PICO_DEFAULT_LED_PIN);
   gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
   
   while (true)
  {
       do_Modbus(SOCKET_ID);
  }
}

/* Do_Modubs function */
void do_Modbus(uint8_t sn)
{
uint8_t state = 0;
uint16_t len;
getSIPR(lip);
state = getSn_SR(sn);
switch (state)
{
case SOCK_SYNSENT:
break;
case SOCK_INIT:
listen(sn);
if (!b_listening_printed)
{
b_listening_printed = 1;
printf("Listening on %d.%d.%d.%d:%d\r\n",
  lip[0], lip[1], lip[2], lip[3], local_port);
}
break;
case SOCK_LISTEN:
break;
case SOCK_ESTABLISHED:
if (getSn_IR(sn) & Sn_IR_CON)
{

setSn_IR(sn, Sn_IR_CON);
printf("Connected\r\n");
getSn_DIPR(sn, rip);
port = getSn_DPORT(sn);
printf("RemoteIP:%d.%d.%d.%d Port:%d\r\n", rip[0], rip[1], rip[2], rip[3], port);

if (b_listening_printed)
b_listening_printed = 0;
}
len = getSn_RX_RSR(sn);
if (len > 0)
{
mbTCPtoEVB(sn);
}
break;
case SOCK_CLOSE_WAIT:
disconnect(sn);
break;
case SOCK_CLOSED:
case SOCK_FIN_WAIT:
close(sn);
socket(sn, Sn_MR_TCP, local_port, Sn_MR_ND); // Sn_MR_ND
break;
default:
break;
}
}

/* mbTCPtoEVB function */
void mbTCPtoEVB(uint8_t sn)
{
int32_t ret;
if (MBtcp2evbFrame() != 0) // Frame received complete
{
uint16_t maxsize = 0;
if (pucASCIIBufferCur[0] == 0x01)//Check whether the device address is 0x01
{
if ((uint8_t)pucASCIIBufferCur[1] == 0x05)//Write to a single device
{
if ((uint8_t)pucASCIIBufferCur[4] == 0xff)
{
gpio_put(PICO_DEFAULT_LED_PIN, 1);
printf("LED ON\r\n");
}
else if ((uint8_t)pucASCIIBufferCur[4] == 0x00)
{
printf("LED OFF\r\n");
gpio_put(PICO_DEFAULT_LED_PIN, 0);
}
send(sn, recv_data, recv_len);
}
else if ((uint8_t)pucASCIIBufferCur[1] == 0x01)//Read Write to a single device
{
if (recv_data[recv_len - 1] != 0x01)
{
printf("len error!\r\n");
}
else
{
printf("Read OK!\r\n");
send_data[0] = recv_data[0];
send_data[1] = recv_data[1];
send_data[2] = recv_data[2];
send_data[3] = recv_data[3];
send_data[4] = 0x00;
send_data[5] = 0x04;
send_data[6] = 0x01;
send_data[7] = 0x01;
send_data[8] = 0x01;
send_data[9] = gpio_get(PICO_DEFAULT_LED_PIN);
send_len = 10;
send(sn, (uint8_t *)send_data, send_len);
memset(send_data, 0, send_len);
}
}
else
{
printf("error code!\r\n");
}
}
else
{
printf("address error!\r\n");
}
}
}

4.5 Results demonstration

1. Connect to W5100S using Modbus Poll

2. Send a write command to turn on the LED light

3. Set the read command to 0x01 and the read number to 1

4. Send a read command

5. The reading is successful and the LED status is displayed on the Modbus Poll.

5 Precautions

The address set and read must be 1, and the number read must be 1, otherwise information cannot be written or read. If you need to modify it, please modify the mbTCPtoEVB function in the mb.c file in the app/MODBUS_TCP_SERVER directory.

If we want to use WIZnet's W5500 to implement the example in this chapter, we only need to modify two places:

(1) Find the wizchip_conf.h header file under library/ioLibrary_Driver/Ethernet/ and modify the WIZCHIP macro definition to W5500.

(2) Find the CMakeLists.txt file under library and set COMPILE_SEL to ON. OFF is W5100S and ON is W5500.

Documents
  • Code for this article

  • WIZnet Official Website

  • WIZnet Official IO library

  • YouTube Demo

Comments Write