W5500 lwip Arduino Core 3.1.1 not working with Emodbus async TCP

zlomennypez
Posts: 2
Joined: Thu Feb 13, 2025 9:11 am

W5500 lwip Arduino Core 3.1.1 not working with Emodbus async TCP

Postby zlomennypez » Thu Feb 13, 2025 9:23 am

Hello,

I´m trying to use async Emodbus library: https://github.com/eModbus/eModbus

with Ethernet on Pioarduino, but it works only over WiFi and WiFiClient. Arduino use class NetworkClient for Ethernet, which works with default example: https://github.com/espressif/arduino-es ... no_SPI.ino

This is my code on ESP32S3

Code: Select all

 /*
    This sketch shows the Ethernet event usage

*/

#include <ETH.h>
#include <SPI.h>
#include <ModbusClientTCPasync.h>

// Set this to 1 to enable dual Ethernet support
#define USE_TWO_ETH_PORTS 0

#ifndef ETH_PHY_CS
#define ETH_PHY_TYPE ETH_PHY_W5500
#define ETH_PHY_ADDR 1
#define ETH_PHY_CS   5
#define ETH_PHY_IRQ  4
#define ETH_PHY_RST  -1
#endif

// SPI pins
#define ETH_SPI_SCK  18
#define ETH_SPI_MISO 19
#define ETH_SPI_MOSI 23

#if USE_TWO_ETH_PORTS
// Second port on shared SPI bus
#ifndef ETH1_PHY_CS
#define ETH1_PHY_TYPE ETH_PHY_W5500
#define ETH1_PHY_ADDR 1
#define ETH1_PHY_CS   32
#define ETH1_PHY_IRQ  33
#define ETH1_PHY_RST  18
#endif
ETHClass ETH1(1);
#endif
NetworkClient client;


IPAddress ip = {192, 168, 0, 224};          // IP address of modbus server
uint16_t port = 502;  


static bool eth_connected = false;

void onEvent(arduino_event_id_t event, arduino_event_info_t info) {
  switch (event) {
    case ARDUINO_EVENT_ETH_START:
      Serial.println("ETH Started");
      //set eth hostname here
      ETH.setHostname("esp32-eth0");
      break;
    case ARDUINO_EVENT_ETH_CONNECTED: Serial.println("ETH Connected"); break;
    case ARDUINO_EVENT_ETH_GOT_IP:    Serial.printf("ETH Got IP: '%s'\n", esp_netif_get_desc(info.got_ip.esp_netif)); Serial.println(ETH);
#if USE_TWO_ETH_PORTS
      Serial.println(ETH1);
#endif
      eth_connected = true;
      break;
    case ARDUINO_EVENT_ETH_LOST_IP:
      Serial.println("ETH Lost IP");
      eth_connected = false;
      break;
    case ARDUINO_EVENT_ETH_DISCONNECTED:
      Serial.println("ETH Disconnected");
      eth_connected = false;
      break;
    case ARDUINO_EVENT_ETH_STOP:
      Serial.println("ETH Stopped");
      eth_connected = false;
      break;
    default: break;
  }
}

void testClient(const char *host, uint16_t port) {
  Serial.print("\nconnecting to ");
  Serial.println(host);

  
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    return;
  }
  client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host);
  while (client.connected() && !client.available());
  while (client.available()) {
    Serial.write(client.read());
  }

  Serial.println("closing connection\n");
  client.stop();
}


ModbusClientTCPasync MB(ip, port);

// Define an onData handler function to receive the regular responses
// Arguments are Modbus server ID, the function code requested, the message data and length of it, 
// plus a user-supplied token to identify the causing request
void handleData(ModbusMessage response, uint32_t token) 
{
  Serial.printf("Response: serverID=%d, FC=%d, Token=%08X, length=%d:\n", response.getServerID(), response.getFunctionCode(), token, response.size());
  for (auto& byte : response) {
    Serial.printf("%02X ", byte);
  }
  Serial.println("");
}

// Define an onError handler function to receive error responses
// Arguments are the error code returned and a user-supplied token to identify the causing request
void handleError(Error error, uint32_t token) 
{
  // ModbusError wraps the error code and provides a readable error message for it
  ModbusError me(error);
  Serial.printf("Error response: %02X - %s token: %d\n", (int)me, (const char *)me, token);
}


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

  SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
  ETH.begin(ETH_PHY_TYPE, ETH_PHY_ADDR, ETH_PHY_CS, ETH_PHY_IRQ, ETH_PHY_RST, SPI);
#if USE_TWO_ETH_PORTS
  ETH1.begin(ETH1_PHY_TYPE, ETH1_PHY_ADDR, ETH1_PHY_CS, ETH1_PHY_IRQ, ETH1_PHY_RST, SPI);
#endif

 MB.onDataHandler(&handleData);
// - provide onError handler function
  MB.onErrorHandler(&handleError);
// Set message timeout to 2000ms and interval between requests to the same host to 200ms
  MB.setTimeout(10000);
// Start ModbusTCP background task
  MB.setIdleTimeout(60000);

}

void loop() {
  
  static unsigned long lastMillis = 0;
  if (millis() - lastMillis > 5000) {
    lastMillis = millis();

    // Create request for
    // (Fill in your data here!)
    // - server ID = 1
    // - function code = 0x03 (read holding register)
    // - start address to read = word 10
    // - number of words to read = 4
    // - token to match the response with the request. We take the current millis() value for it.
    //
    // If something is missing or wrong with the call parameters, we will immediately get an error code 
    // and the request will not be issued
    Serial.printf("sending request with token %d\n", (uint32_t)lastMillis);
    Error err;
    err = MB.addRequest((uint32_t)lastMillis, 1, READ_HOLD_REGISTER, 10, 4);
    if (err != SUCCESS) {
      ModbusError e(err);
      Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
    }
    // Else the request is processed in the background task and the onData/onError handler functions will get the result.
    //
    // The output on the Serial Monitor will be (depending on your WiFi and Modbus the data will be different):
    //     __ OK __
    //     . WIFi IP address: 192.168.178.74
    //     Response: serverID=20, FC=3, Token=0000056C, length=11:
    //     14 03 04 01 F6 FF FF FF 00 C0 A8
  }
}


and platformio Setup:

Code: Select all

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32dev]
platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip
board = esp32dev
framework = arduino
board_build.filesystem = littlefs
monitor_speed = 115200

lib_deps =
        miq19/eModbus@1.7.1
       




If I add WiFiClient a nd run WiFi.begin, it starts to work with WiFi but not with w5500..

Thank you fo any help.

lbernstone
Posts: 916
Joined: Mon Jul 22, 2019 3:20 pm

Re: W5500 lwip Arduino Core 3.1.1 not working with Emodbus async TCP

Postby lbernstone » Fri Feb 14, 2025 5:38 am

You can use `Network.setDefaultInterface(ETH);` to set the default outgoing interface (v3.x+)

Who is online

Users browsing this forum: No registered users and 109 guests