Modbus TCP Server Issue with MKR Wifi 1000 + MKR ETH

Hi all,

I’ve been trying to get a modbus TCP server to work on a MKR wifi 1000 with an MKR ETH shield.

I have modified the example ‘WifiModbusServerLED’, which uses Wifi, to use Ethernet instead. I first tried with the client (WifiModbusClientToggle) example and managed to get it working - I used the ‘Modbus Slave’ PC application to test it.

I am have an issue with getting the server working. Below is the code I am using:

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


byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE8 }; // Ethernet MAC Address
IPAddress ip(192,168,1,140); // Ethernet MAC IP address

const int ledPin = LED_BUILTIN;

EthernetServer ethernetServer(502);
ModbusTCPServer modbusTCPServer;

unsigned long CoilResult, ModbusTCPResult;

void setup() {
   delay(3000);
   Serial.begin(9600);

 //Deselect the SD card
  pinMode(4,OUTPUT);
  digitalWrite(4, HIGH);

 // start the Ethernet connection:
   Serial.println("Trying to configure using Fixed IP");
   Ethernet.begin(mac, ip);
   Serial.print("  Fixed IP: ");
   Serial.println(Ethernet.localIP());


  // configure the LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // configure a single coil at address 0x00
  CoilResult = modbusTCPServer.configureCoils(0x00, 1);
   Serial.print(" Initializing Coils Result =  ");
   Serial.println(CoilResult);
}

void loop() {

  // listen for incoming clients
  EthernetClient client = ethernetServer.available();
  
 
  if (client) {
    // a new client connected
    Serial.println("new client");


    Serial.print(" Initializing Modbus Server Result =  ");
    Serial.println(ModbusTCPResult);
    ModbusTCPResult = modbusTCPServer.begin();
    Serial.print(" Initializing Modbus Server Result =  ");
    Serial.println(ModbusTCPResult);


   
 // let the Modbus TCP accept the connection 
    modbusTCPServer.accept(client);

    while (client.connected()) {
      // poll for Modbus TCP requests, while client connected
      modbusTCPServer.poll();
      //delay(2000);
      Serial.print("poll");
      Serial.print("\n");
      unsigned long coilValue = modbusTCPServer.coilRead(0x00);
      Serial.print("Coil Value:");
      Serial.print(coilValue);
      Serial.print("\n"); 

      // update the LED
      updateLED();
    }
    Serial.println("client disconnected");
  }
}

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

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

The serial output I am getting after opening a connection using the windows app ‘Radzio’ is the following:

13:45:55.805 -> Trying to configure using Fixed IP
13:45:56.368 ->   Fixed IP: 192.168.1.140
13:45:56.368 ->  Initializing Coils Result =  1
13:46:13.412 -> new client
13:46:13.412 ->  Initializing Modbus Server Result =  0
13:46:13.412 ->  Initializing Modbus Server Result =  1
13:46:13.412 -> poll
13:46:13.412 -> Coil Value:4294967295
13:46:13.412 -> poll
13:46:13.412 -> Coil Value:4294967295
13:46:13.412 -> poll
13:46:13.412 -> Coil Value:4294967295
13:46:13.412 -> poll

Radzio keeps showing a timeout error and each poll results in an error.

Any help is appreciated!

The modbusTCPServer.begin() call must not be in the loop() but in the setup() and before the configureCoils() call!

Thank you for that!

I also was not starting the ethernet server anywhere :smiley:

Here is the code that got it working for anyone that comes across this post in the future:

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xE8 }; // Ethernet MAC Address
IPAddress ip(192,168,1,140); // Ethernet MAC IP address

const int ledPin = LED_BUILTIN;

EthernetServer ethernetServer(502);
ModbusTCPServer modbusTCPServer;

unsigned long CoilResult, ModbusTCPResult;

void setup() {
Serial.begin(9600);
while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

 // start the Ethernet connection:
   Serial.println("Trying to configure using Fixed IP");
   Ethernet.begin(mac, ip);
   Serial.print("  Fixed IP: ");
   Serial.println(Ethernet.localIP());

  // start the server
 ethernetServer.begin();

  // start the Modbus TCP server
  if (!modbusTCPServer.begin()) {
    Serial.println("Failed to start Modbus TCP Server!");
    while (1);
  }

 //Deselect the SD card
  pinMode(4,OUTPUT);
  digitalWrite(4, HIGH);

  // configure the LED
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);

  // configure a single coil at address 0x00
  CoilResult = modbusTCPServer.configureCoils(0x00, 1);
   Serial.print(" Initializing Coils Result =  ");
   Serial.println(CoilResult);
}

void loop() {

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

    while (client.connected()) {
      // poll for Modbus TCP requests, while client connected
      modbusTCPServer.poll();
      //delay(2000);
      Serial.print("poll");
      Serial.print("\n");
      unsigned long coilValue = modbusTCPServer.coilRead(0x00);
      Serial.print("Coil Value:");
      Serial.print(coilValue);
      Serial.print("\n"); 

      // update the LED
      updateLED();
    }
    Serial.println("client disconnected");
  }
}

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

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

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