Modbus TCP/IP server side doesn't send the data after a while

Hello everyone,

I seem to be experiencing a problem with the function EthernetClient client = server.available();, attached is my sketch.

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

#define LED 1

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
byte mac[] = {0xAA, 0x01, 0x22, 0xA1, 0xB1, 0x06};

EthernetServer server(502);
ModbusTCPServer modbusTCPServer;

unsigned long currentMillis;
unsigned long status_Millis     = 0;
const    long status_interval   = 10000;

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  // Ethernet.init(5);   // MKR ETH shield
  pinMode(LED, OUTPUT);

  Ethernet.begin(mac);                                                    // initialize the ethernet device

  Serial.begin(9600);
  //while (!Serial) { }

  if (Ethernet.hardwareStatus() == EthernetNoHardware) {                  // Check for Ethernet hardware present
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
  }

  while (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

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

  Serial.print("Modbus server address: ");
  Serial.println(Ethernet.localIP());

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

  // configure a single coil at address 0x00 and 100 registers from address 0x00
  modbusTCPServer.configureCoils(0x00, 1);
  modbusTCPServer.configureHoldingRegisters(0x00, 100);

}

void loop() {
  currentMillis = millis();
  if (currentMillis - status_Millis >= status_interval) {
    status_Millis = currentMillis;
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
  }

  EthernetClient client = server.available();                              // wait for a new client
  if (client) {
    Serial.println("new client");                             // a new client connected
    modbusTCPServer.accept(client);     
    
// let the Modbus TCP accept the connection
    if (client.connected()) {
      modbusTCPServer.poll();                                              // poll for Modbus TCP requests, while client connected
      measurement();                                                            // update the measured current
    }
    Serial.println("client disconnected");
  }
}

This sketch is uploaded on Arduino MKR ZERO with an Ethernet shield. The problem is, on Friday, I was able to receive the data from this sketch using another Arduino board. I didn't turn off the Arduino MKR ZERO board since Friday, and now if I want to connect again to this board to grab the same data, it won't connect. I even tried to used a software on windows the QModMaster and that also gives the error saying "Connection failed and couldn't connect to TCP port". However, if I reset the Arduino ZERO board, I can again receive the data. It seems, the Arduino ZERO can't see the client request anymore. Can someone please assist? Thanks in advance

Hello bilal40
Try this:

const    unsigned long status_interval   = 10000;

Have a nice day and enjoy programming in C++ and learning.
Дайте миру шанс!

Yes, sure. But will it resolve that issue? Thanks for the help.

By the way, the MKR ethernet shield has SD card slot and the MKR Zero also has the SD slot. Are these two compatible with each other? Will they make any kind of conflict? For MKR ethernet shield, I read that to deselect sd slot, I need to make the pin 4 as HIGH. I didn't do it in my sketch, so, I will consider doing it. But do, I need to do some other settings as well?

ignore it, if you don´t like it

I made some changes to the above sketch like I have assigned a static IP, before it assigning the IP automatically. In the setup(), I did the Ethernet.init(5); then to deselect the sd slot, I made the pin 4 HIGH. Begin the Ethernet with (mac,ip). And the const long changed to const unsigned long. Since yesterday, it was working fine. I was reading the values from the holding register below by another arduino. But after reading the value for probably 600 times, I see that there is again no request by the new client EthernetClient client = server.available();. So, it can said that the request was seen and accepted for 600 times but then it stopped. I restarted the system again and it starts working.

The question is what could be the possible cause that the microcontroller don't see the client request after sometime? Is it possible that server is disconnecting? Do I need to call the server.begin(); in the loop function? Your kind assistance would be highly appreciated. Thank you.

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

#define LED 1

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
byte mac[] = {0xAA, 0x01, 0x22, 0xA1, 0xB1, 0x06};
IPAddress ip(192, 168, 178, 92);

EthernetServer server(502);
ModbusTCPServer modbusTCPServer;

int i = 0;

unsigned long currentMillis;
unsigned long status_Millis     = 0;
const    long status_interval   = 10000;

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  Ethernet.init(5);   // MKR ETH shield
  pinMode(LED, OUTPUT);
  
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);

  Ethernet.begin(mac, ip);                                                    // initialize the ethernet device

  Serial.begin(9600);
  //while (!Serial) { }

  if (Ethernet.hardwareStatus() == EthernetNoHardware) {                  // Check for Ethernet hardware present
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
  }

  while (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

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

  Serial.print("Modbus server address: ");
  Serial.println(Ethernet.localIP());

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

  // configure a single coil at address 0x00 and 100 registers from address 0x00
  modbusTCPServer.configureCoils(0x00, 1);
  modbusTCPServer.configureHoldingRegisters(0x00, 100);

}

void loop() {
  currentMillis = millis();
  if (currentMillis - status_Millis >= status_interval) {
    status_Millis = currentMillis;
    digitalWrite(LED, HIGH);
    delay(500);
    digitalWrite(LED, LOW);
  }

  EthernetClient client = server.available();                              // wait for a new client
  if (client) {
    Serial.println("new client");                             // a new client connected
    modbusTCPServer.accept(client);     
    
// let the Modbus TCP accept the connection
    if (client.connected()) {
      modbusTCPServer.poll();                                              // poll for Modbus TCP requests, while client connected
      measurement();                                                            // update the measured current
    }
    Serial.println("client disconnected");
  }

void measurement() {

  modbusTCPServer.holdingRegisterWrite(0, i);
  i++;
  delay(100);
}

And this is the sketch I am using for another (client) Arduino to read the value from the (server) arduino.

/*
  WiFi Modbus TCP Client Toggle

  This sketch toggles the coil of a Modbus TCP server connected
  on and off every second.

  Circuit:
   - MKR1000 or MKR WiFi 1010 board

  created 16 July 2018
  by Sandeep Mistry
*/

#include <SPI.h>
#include <WiFiNINA.h> // for MKR WiFi 1010

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

#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

int status = WL_IDLE_STATUS;

int data;

WiFiClient wifiClient;
ModbusTCPClient modbusTCPClient(wifiClient);

IPAddress server(192, 168, 178, 92); // update with the IP Address of your Modbus server

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 Client Toggle");

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
}

void loop() {
  if (!modbusTCPClient.connected()) {
    // client not connected, start the Modbus TCP client
    Serial.println("Attempting to connect to Modbus TCP server");

    if (!modbusTCPClient.begin(server)) {
      Serial.println("Modbus TCP Client failed to connect!");
    } else {
      Serial.println("Modbus TCP Client connected");
    }
  } else {
    // client connected

    // write the value of 0x01, to the coil at address 0x00
    if (!modbusTCPClient.requestFrom(1, HOLDING_REGISTERS, 0, 1)) {
      Serial.print("Failed to read! ");
      Serial.println(modbusTCPClient.lastError());
    } else {
      Serial.println("Register read success");
    }
    while (modbusTCPClient.available()) {
      int receivedByte = modbusTCPClient.read();
    }
  }
  Serial.println(receivedByte);
  delay(6000);                                        // wait for 6 seconds otherwise timeout occurs
}

@pylon any assistance, please? :slight_smile:

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