Modbus TCP server side questions

Hi!
On MKR ZERO + MKR ETH devices (Tried, well configured setup):
Question1:
If Master(client) send a request (FC03 read holding register or FC06 write holding register), i can only decide which FC came by comparing registry content: Attention whether the content of the registry used to change is varying (FC06 by master).
Is this normal?
Question2:
If come one by one FC03 from Master I can't evaluate the requested address, so now the master is "asking for everything" and I'll send it back "everything":

void response_to_master() {
  uint16_t responseArray[12];
  for (uint8_t i = 0; i <= 11; i++) {
   responseArray[i] = akt_values;
  }
 for (uint8_t i = 0; i <= 11; i++) {
  local_modbusTCP_server.holdingRegisterWrite(i + 40001, responseArray[i]);
 }
}

After sending the register's, the previous (!) content appear in Master side (Node-Red, Modbus Poll). Of course, before sending, check the responseArray value, that is correct

Using which library? There are more than one Modbus IP library available.

These are statements, there is no question.

I am using native arduino library (v1.0.8). Is there better/smarter?
Q2: After sending the register's, WHY the previous (!) content appear in Master side (Node-Red, Modbus Poll)? Of course, before sending, check the responseArray value, that is correct

I guess that means the library "ArduinoModbus".

I would subclass the ModbusTCPServer class and overwrite the poll() method to implement the function handling yourself.

We cannot answer this question because you're still hiding the majority of your code from us.

If that's for NodRed why are you using that PLC address ranges? There is no need for that if both sides implement Modbus correctly. Many PLC implementations are crippled that's why you need address ranges to distinguish the function code to be used. Neither NodeRed nor ArduinoModbus have this disability.

I guess that means the library "ArduinoModbus".

yes

I would subclass the ModbusTCPServer class and overwrite the poll() method to implement the function handling yourself.

how?
I use this way:

EthernetServer eth_server(502);
ModbusTCPServer local_modbusTCP_server;
void setup() {
.
.
if (!local_modbusTCP_server.begin(2)) {
    Serial.println("Failed to start local Modbus TCP Server!");
  }
  else {
    Serial.println("Local Modbus TCP Server started");
    local_modbusTCP_server.configureHoldingRegisters(40001, 40);
  }
}

void loop ()
{
EthernetClient remote_modbusTCP_client = eth_server.available();
 if (remote_modbusTCP_client) {
  local_modbusTCP_server.accept(remote_modbusTCP_client);
  if (remote_modbusTCP_client.connected()) {
   while (local_modbusTCP_server.poll() > 0);
   // reading holding registers:
.
.
   // I can only decide from the contents of the Holding Registers designated for writing
   // that setting or request has come
   // If the content of a holding register has changed, writing came
   // if not changed, request came to all registers content (otherwise I can't decide(?)), 
   // then I return the contents of all (agreed) registers this way:
   for (uint8_t i = 0; i <= 11; i++) {
    local_modbusTCP_server.holdingRegisterWrite(i + 40001, responseArray[i]);
  }
  // the responseArray always Includes the current values

Thereafter always the previously sent content will arrived at the Master... :face_with_raised_eyebrow:
The Master is now Node-Red, later ClearScada

Once the poll() returns the Modbus request is already handled, so if you write later to the holding register it will not be used until the next request.

I guess that ClearScada uses a crippled implementation too, if you write it this way.

Derive a class from ModbusTCPServer and in that class overwrite the poll method. The library doesn't support the way you want to use it but it is implemented in a way that sub-classing is supported.

Post your actual code and not pseudo code! If you actually use it the way you show in the posted code you can simply write to the holding registers when you get the values in the responseArray, you don't have to wait until the request arrives.

It seems to be solved: I thought it was my job to pay attention (to treat as an event) the master side readHoldingRegister. Using Arduinomodbus.h so much I have to keep up "fresh" (server side writeHoldingRegister) those Holdingregisters what the master doesn't write, just ask, the server class immediately replies in the background.
When package came from the master, I tried to decide what master wants: to write (writeHoldingRegister) or want to read (readHoldingRegister). If the master want to read (because didn't write to the holding register), then I wrote back the fresh value, meanwhile, the buffer included the previous content, that the server immediately sent back.
If master writes the holdingregister(s), as an event I can't handle it, only by monitoring the content (previous/current), or I will delete the content after reading:

master writeHoldingRegisters
server poll, package came
server readHoldingRegisters
which register is not 0, wrote in the Master 
server writeHoldingRegisters to 0, what the master can write

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