Modbus RTU library Problem of time consuming when multiple slave on same bus

Hi,

I'm using a arduino every ( ATMEGA4809) with library official from arduino

Modbus RTU 9600.
The arduino is the slave.

The master is a industrial automation system configured :

COM3|9600 Bauds|None|8 Data Bits|1 Stop Bit|RS485

I had some issues of time consuming "ModbusRTUServer.poll();" method so i made a measure and had these results :

  • when the master is not polling any devices on modbus : 0 to 2ms maximum => Fine for me
  • when the master pool the arduino device : 36-37ms => fine for me
  • when the master pool another address :
    ms: 7
    ms: 500
    ms: 7
    ms: 500
    ms: 8
    ms: 500
    ms: 8
    ms: 500

So here there is a problem because it block my program for half a second when the master interrogate another device.

Do i need to configure something for to solve this ?
Is the library capable of doing 1 master with several slaves ? I supposed it was possible.

Thanks
Best regards

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

//  LED MODBUS
#define LEDMODBUS 7

//  MODBUS
#define MODBUS_ADDRESS 102
#define MODBUS_INPUTREG 11
#define MODBUS_BAUDRATE 9600




// Variables General
unsigned int cycle;




/**********************************************/
/********** Setup *****************************/
/**********************************************/
void setup(void) {


  byte i;

  //  LED Modbus
  pinMode(LEDMODBUS, OUTPUT);
  digitalWrite(LEDMODBUS, LOW);

  Serial.begin(115200);

  delay(500);

  digitalWrite(LEDMODBUS, HIGH);


  ModbusRTUServer.begin(MODBUS_ADDRESS, MODBUS_BAUDRATE);
  ModbusRTUServer.configureInputRegisters(0x00, MODBUS_INPUTREG);
}

/**********************************************/
/********** Main LOOP *************************/
/**********************************************/
void loop(void) {
  byte i;



  digitalWrite(LEDMODBUS, LOW);
  cycle = millis();

  // Pool for modbus requests
  ModbusRTUServer.poll();

  cycle = millis() - cycle ;
  if ( cycle > 2 )
  {
    Serial.print("ms: ");
    Serial.println(cycle);
  }


  digitalWrite(LEDMODBUS, HIGH);
}

Hi Again,

Sorry to insist but today i tested again the problem.
So instead of Arduino Nano, i used :

  • Regular Arduino MEGA
  • example software "Modbus RTU Server Kitchen Sink" with just adding few lines to measure the time of the Pool() method and sent the time to Serial2 for logging purpose
  • Arduino mega is connected without RS485, direct on a RS232 TTL to a computer.
  • Arduino Master RTU is a Computer software used : QModMaster

Modbus adress is 42.

When sending to device 42
[RTU]>Tx > 13:36:22:648 - 2A 03 00 00 00 01 82 11
[RTU]>Rx > 13:36:22:673 - 2A 03 02 00 00 9C 42
Everything fine, pool method using 15ms of time.

When sending to device 41 ( who do not exist )

[RTU]>Tx > 13:36:32:289 - 29 03 00 00 00 01 82 22
Nobody reply, so normal but the "pool() method on the arduino adr42 take 7ms and then 500ms.

So this 500ms block the rest of the program in the arduino.

So there is a problem in this library in general.
That's so strange that nobody had this issue before, it is so simple to encounter.

Hope someone can give me directions because i'm not good enough to modify library

I send the issue on github
[u]https://github.com/arduino-libraries/ArduinoModbus/issues/43[/u]

/*
  Modbus RTU Server Kitchen Sink

  This sketch creates a Modbus RTU Server and demostrates
  how to use various Modbus Server APIs.

  Circuit:
   - MKR board
   - MKR 485 shield
     - ISO GND connected to GND of the Modbus RTU server
     - Y connected to A/Y of the Modbus RTU client
     - Z connected to B/Z of the Modbus RTU client
     - Jumper positions
       - FULL set to OFF
       - Z \/\/ Y set to OFF

  created 18 July 2018
  by Sandeep Mistry
*/

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


unsigned int cycle;

const int numCoils = 10;
const int numDiscreteInputs = 10;
const int numHoldingRegisters = 10;
const int numInputRegisters = 10;

void setup() {


  
  Serial.begin(9600);
  while (!Serial);
  
  Serial2.begin(115200);

  Serial2.println("Modbus RTU Server Kitchen Sink");

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

  // configure coils at address 0x00
  ModbusRTUServer.configureCoils(0x00, numCoils);

  // configure discrete inputs at address 0x00
  ModbusRTUServer.configureDiscreteInputs(0x00, numDiscreteInputs);

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

  // configure input registers at address 0x00
  ModbusRTUServer.configureInputRegisters(0x00, numInputRegisters);


}

void loop() {


  cycle = millis();

  // Pool for modbus requests
  ModbusRTUServer.poll();

  cycle = millis() - cycle ;
  if ( cycle > 2 )
  {
    Serial2.print("ms: ");
    Serial2.println(cycle);
  }



  

  // map the coil values to the discrete input values
  for (int i = 0; i < numCoils; i++) {
    int coilValue = ModbusRTUServer.coilRead(i);

    ModbusRTUServer.discreteInputWrite(i, coilValue);
  }

  // map the holiding register values to the input register values
  for (int i = 0; i < numHoldingRegisters; i++) {
    long holdingRegisterValue = ModbusRTUServer.holdingRegisterRead(i);

    ModbusRTUServer.inputRegisterWrite(i, holdingRegisterValue);
  }
}

I didn't like ATMEGA4809. (Better to use STM32F103 instead = better, faster, cheaper.)
USART - Universal Synchronous and Asynchrono ...
I would use a converter to I2C or SPI. The converters can be assembled on ATMega8.
Then each ATMega8 on the slow 9600 interface will exchange and put (take) information from the device.
And a separate controller, for example ATMega328, will collect instantly (as received or exchanged)
the necessary information with ATMega8 and do what is required.
This will give us an analogue of DMA. Otherwise, while you are working with the UART, nothing else is available.

Hi,
Thanks EmSerg for your advice.

But unfortunately my cards are already made and based on the arduino every board.

But the probleme do not come with this card ATMEGA4809 , it is also same problem on the arduino MEGA board 2560 like i said on my second post.

Here is a library issue because why always 500ms delay, something go to a timeout inside library.