Modbus TCP Server - Arduino Uno with ethernet shield

Hello!

I am using an Arduino Uno with an ethernet shield on top as my server, and I want to send and recieve data using Modbus TCP. I am using arduinos ArduinoModbus library.

Right now I am only trying to read a coil on the server from my client (raspberry pi 3). The modbus message is received on the server, but it's not sending back a modbus message with the data on the coil. The client then get a timeout error after a few seconds.

Any ideas?

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
IPAddress myDns(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);

// TCP defaults to port 502
EthernetServer server(502);

ModbusTCPServer modbusTCPServer;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Modbus TCP Server Setup");

  // configure the LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  
  /*
    ------- Ethernet Init -------
  */
  // Initialize the ethernet device
  Ethernet.begin(mac, ip, myDns, gateway, subnet);
  /*
  if (Ethernet.begin(mac) == 0)
	{
		Serial.println("Failed to configure Ethernet using DHCP");
		// No point in carrying on, stop here forever.
		while(true) ;
	}*/

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start listening for clients
  server.begin();

  Serial.print("Server address: ");
  Serial.println(Ethernet.localIP());
  
  /*
    ------- Modbus Init -------
  */
  // start the Modbus TCP server with slaveID 1
  if (!modbusTCPServer.begin(1)) {
    Serial.println("Failed to start Modbus TCP Server!");
    while (1);
  }

  // configure a single coil at address 0x3E
  if (!(modbusTCPServer.configureCoils(0x3E, 1)==1)){
    Serial.println("Failed to configure coils");
    while (1);
  }
  
  Serial.println("Successfully started Modbus TCP Server!");
}

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  
  if (client) {
    // a new client connected
    Serial.println("new client");
    
    // let the Modbus TCP accept the connection 
    modbusTCPServer.accept(client);
    Serial.println("accepted client");

    while (client.connected()) {
      // poll for Modbus TCP requests, while client connected
      modbusTCPServer.poll();
      
      // update the LED
      updateLED();
    }
    
    Serial.println("client disconnected");
  }
}

void updateLED() {
  // read the current value of the coil
  int coilValue = modbusTCPServer.coilRead(0x3E);
  
  Serial.println(coilValue);

  if (coilValue) {
    // coil value set, turn LED on
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    // coil value clear, turn LED off
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Please post the Arduino serial output you got!

Did you sniff the network segment to log the network traffic between the two nodes? If yes, please post the dumped data.