angeloc/simplemodbusng

malfunction in a bus with high trafic

Opened this issue · 1 comments

Hi to everyone!
Is my first time doing a contibuition in github. Sorry if here is not the place to do it.
I have tested the library in using a Attiny board. The application was a remote thermometer, so with this tiny board I had to interrogate a DS18B20 and to implement the Modbus slave.
It took me the 92% of the total memmorie but I reach the objetive.
When I comunicate with de slave in a bus with just this slave everithing goes rigth. The problem apeared when I tried to included in crouded bus, where the master interrogate almos the 100% of the time.
I made a little change in the code of the librarie and now is working OK.
I would like to share with you the solution.

The problem is the implementation of the timeout T1_5 in modbus_update() function.
The original code is:

  while (mySerial.available())
  {
    // The maximum number of bytes is limited to the serial buffer size of 128 bytes
    // If more bytes is received than the BUFFER_SIZE the overflow flag will be set and the 
    // serial buffer will be red untill all the data is cleared from the receive buffer.
    if (overflow) 
      mySerial.read();
    else
    {
      if (buffer == BUFFER_SIZE)
        overflow = 1;
      frame[buffer] = mySerial.read();
      buffer++;
    }
    delayMicroseconds(T1_5); // inter character time out
  }

Here the "time out" is not implemented, insted a delay off the entire timeout is included.
I have conclude this is the reason why in the crowded bus this slave can not follow the trafic.
So I remplaced the code by follows. It now use a 94% inted of 92% of total memmorie

    unsigned long timeOut = micros();
     while ((*_port).available() || (timeOut+T1_5 <= micros())) {
      if((*_port).available()) {
         timeOut = micros();
          // The maximum number of bytes is limited to the serial buffer size of 128 bytes
          // If more bytes is received than the BUFFER_SIZE the overflow flag will be set and the
          // serial buffer will be red untill all the data is cleared from the receive buffer.
          if (overflow)
              (*_port).read();
          else {
              if (buffer == BUFFER_SIZE)
                  overflow = 1;
              frame[buffer] = (*_port).read();
              buffer++;
          }
      }
    }


Thank you for the librarie!!!






Have You tried the low latency mode instead?