Modbus RTU client can't read from server

Hello

I am experimenting with the Modbus RTU and using the Arduino MKR boards and RS485 shields. The sketches for both server and client are given below:

****************** Server sketch **************

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

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

  // start the Modbus RTU server, with (slave) id 1
  if (!ModbusRTUServer.begin(1, 9600)) {
    Serial.println("Failed to start Modbus RTU Server!");
    while (1);
  }

  // configure holding registers at address 0x00
  ModbusRTUServer.configureHoldingRegisters(0x00, 1);
}

void loop() {
  // poll for Modbus RTU requests
  ModbusRTUServer.poll();

  ModbusRTUServer.holdingRegisterWrite(0, 100);
  delay(5000);
}
}

The client sketch is:

***************Client*****************

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
}

void loop() {

  readHoldingRegisterValues();

  delay(5000);
  Serial.println();
}

void readHoldingRegisterValues() {
  Serial.print("Reading Holding Register values ... ");
  ModbusRTUClient.holdingRegisterRead(0x00, 1);

  while (ModbusRTUClient.available()) {
    Serial.print(ModbusRTUClient.read());
    Serial.print(' ');
  }
  Serial.println();
}

When I see the serial monitor for client side, I do not read anything. However, if I use this following sketch for the client side:

***************Client sketch 2******************

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

void setup() {
  Serial.begin(9600);
  while (!Serial);

  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
}

void loop() {

  readHoldingRegisterValues();

  delay(5000);
  Serial.println();
}

void readHoldingRegisterValues() {
  Serial.print("Reading Holding Register values ... ");

  if (!ModbusRTUClient.requestFrom(1, HOLDING_REGISTERS, 0x00, 1)) {
    Serial.print("failed! ");
    Serial.println(ModbusRTUClient.lastError());
    } else {
    Serial.println("success");
    }
  while (ModbusRTUClient.available()) {
    Serial.print(ModbusRTUClient.read());
    Serial.print(' ');
  }
  Serial.println();
}

then the serial monitor shows success and the value 100 three times, and then fails with the error timeout one time. Again three times 100 value and then one timeout.

My question is, why can't I read the 100 value with the first sketch of the client but can read with the second sketch, and secondly, why do I have a timeout error after three consecutive successful readings? Looking forward to your assistance. Thank you

The .requestFrom() function is the one that actually fetches the data from the server. Your first client code does not contain this call so nothing is fetched.

As for the timeout, why do you have a 5 second delay in your server? During this delay(), the server can not respond to any requests from the slave. That is most likely your issue. I would get rid of that part of your server code.

Because you use the wrong order of the arguments:

The first argument is the slave id (some people prefer the term server id), the second is the register number to start.

yes, this was a mistake. I also tried with (1, 0x00) by having the slave ID first but still no response.

Ok, but in the example they have shown if I want to read just one register, I can use the first client code, for more registers I need to use the second sketch. I was expecting the first client sketch to read this value but none.

In the second paragraph, you said (As for the timeout, why do you have a 5 second delay in your server? During this delay(), the server can not respond to any requests from the slave.) Did you mean the server/slave can't respond to any requests from the client? And yes the delay was an issue. I removed the delay on server sketch and then no issue. I put a delay deliberately to see how would it respond, I mean in reality that's possible that I read different sensors and writing the values to the registers could create some delay. But after this test it seems like I could encounter issue if I have delay on the server side, but a bigger delay on client side also make problem. Additionally, I saw that when there is absolutely no delay on server side after writing the register, then I get an error that (response was not from the request slave). Nevertheless, when I introduced a 100 ms delay after writing the register then it was ok.

Yes. The poll() method must be called as often as possible but at least once in less than the client timeout. A 5 second delay is way out of the range.

What kind of problems does the delay on the client side pose?

Where do you get that error?

This shouldn't be needed but your code doesn't make sense as you write exactly the same value in every run of the loop.

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