Modbus TCP/IP between ESP32 and software Modbus Slave in PC via LAN8720 module

Hi everyone, I'm having a problem. I want to establish communication between my ESP32 (as a Modbus TCP client) and a Modbus Slave software in my PC via the RJ45 port. I'm using the LAN8720 module for the Ethernet connection.

However, I haven't been able to make it work, and I'm not sure if there's something wrong with my code.

First, this is my schematic, and I didn't use the resistors shown in the picture:

Second, this is my Modbus Slave interface:

And finally, here is my source code:


#include <ETH.h>
#include <ModbusIP_ESP8266.h>

// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110)
#define ETH_PHY_ADDR 1 // DEFAULT VALUE IS 0 YOU CAN OMIT IT
// Type of the Ethernet PHY (LAN8720 or TLK110)
#define ETH_PHY_TYPE ETH_PHY_LAN8720 // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the enable signal for the external crystal oscillator (-1 to disable for internal APLL source)
#define ETH_PHY_POWER -1 // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C clock signal for the Ethernet PHY
#define ETH_PHY_MDC 23 // DEFAULT VALUE YOU CAN OMIT IT
// Pin# of the I²C IO signal for the Ethernet PHY
#define ETH_PHY_MDIO 18 // DEFAULT VALUE YOU CAN OMIT IT
// External clock from crystal oscillator
#define ETH_CLK_MODE ETH_CLOCK_GPIO0_IN // DEFAULT VALUE YOU CAN OMIT IT

// Cấu hình địa chỉ IP tĩnh cho ESP32
IPAddress localIP(192, 168, 1, 100); // Địa chỉ IP của ESP32
IPAddress subnet(255, 255, 255, 0);  // Subnet mask
IPAddress gateway(0, 0, 0, 0);       // Không có gateway
IPAddress dns1(0, 0, 0, 0);          // Không có DNS

IPAddress modbusServerIP(192, 168, 1, 30); // Address of Modbus Server device
const int startRegister = 0;               // Starting holding register
const int numberRegister = 10;             // Number of holding registers to read
const int interval = 1000;                 // interval between reads (in milliseconds)

ModbusIP modbus;

uint16_t res[numberRegister];

void setup()
{
  Serial.begin(115200);

  // Khởi tạo kết nối Ethernet
  ETH.begin(ETH_PHY_ADDR, ETH_PHY_POWER, ETH_PHY_MDC, ETH_PHY_MDIO, ETH_PHY_TYPE, ETH_CLK_MODE);

  // Cấu hình Ethernet với IP tĩnh và subnet
  if (ETH.config(localIP, gateway, subnet, dns1))
    Serial.println("Ethernet initialized successfully.");
  else
    Serial.println("Failed to initialize Ethernet.");

  // Kiểm tra kết nối Ethernet
  if (ETH.linkUp())
    Serial.println("Ethernet connection established.");
  else
    Serial.println("Ethernet connection failed.");

  modbus.client();
  modbus.connect(modbusServerIP, 502);

  if (modbus.isConnected(modbusServerIP))
    Serial.println("Connect to Server successfully!");
  else
    Serial.println("Connected to Server failed!");
}

void loop()
{

  if (modbus.isConnected(modbusServerIP))
  {
    // Read holding registers from Modbus Slave
    uint8_t transaction = modbus.readHreg(modbusServerIP, startRegister, res, 10, nullptr, 1);

    // Wait for the transaction to complete
    while (modbus.isTransaction(transaction))
    {
      modbus.task();
      delay(10);
    }

    // Print holding register values
    Serial.println("Holding Register Values:");
    for (int i = 0; i < numberRegister; i++)
    {
      Serial.print("Register ");
      Serial.print(i);
      Serial.print(": ");
      Serial.println(res[i]);
    }
  }
  else
  {
    // If not connected, try to connect
    Serial.println("Unconnected!");
    modbus.connect(modbusServerIP);
  }

  delay(interval);
}

It always prints "Unconnected", even though I can ping the ESP32's IP address from my CMD and it responds.

Hello,

First thing first, you said you can ping your ESP from the computer; but did you try the opposit?

You have some Library such as ESP32Ping (or others) that could help you to ping.

Did you make sure that the IP Address of your computer is 192, 168, 1, 30 ?
Be aware, if you are using WiFi with your computer then you'll have two IP Addresses. Here this is the IP Address of your Ethernet port that you have to set up to 192, 168, 1, 30.

You are right, 192.168.1.30 is the IP of Ethernet Port in my PC, and the Wifi's IP is 192.168.1.67. I have tried to established Modbus TCP via Wifi, that means the IP of Modbus Server is same as Wifi, and it was successful without any problem. But when I tried with Ethernet, I couldn't communicate. And, as you say, I also can't ping 192.168.1.30 from my ESP32.

do the basic Ethernet examples work with ETH.h?

Is the computer you wanna use old? How many years?

Let me explain why I ask this.
You could see the Ethernet cable as a serie cable. On your computer you would have a Rx input and a Tx output.
Same for you box. When you connect your computer (client) to your box (server) with the cable, then:

Rx computer -> Tx box
Tx computer -> Rx box

The same happens when you want to connect your arduino board (client) to the box (server)

Rx board -> Tx box
Tx board -> Rx box

However, using the same cable to connect the board to the computer, that are both designed to be client and not server, this happens:

Rx board -> Rx computer
Tx board -> Tx computer

Therfore it cannot work. Recent computers have an (automatic) option that can switch Rx/Tx but maybe you don't.

Do you have any switch that you could use to interface the connection between the computer and the board?

You could also use a software such as WireShark to watch the messages that are exchanged over the Ethernet port and try to see if something is coming out of the board

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.