Probem witch SimpleModbus and delay [SOLVED]

EDIT real Solution:

I did not know explain. Now I know. :wink:

-1 Master and 6 slaves. (or more, or less)
-Slaves gave many errors if they spoke together. (Slaves sometimes stopped working! )
-Slaves were very well if they were called just one. :fearful:
-Do not know why. If each slave was fine alone, why they went wrong if together?
(I was going crazy) =(

The problem was that reading 18B20 12-bit resolution is VERY SLOW. 750ms for reading. All slaves had 18B20.

Simplemodbus works poorly if there is delay in the slave. I think after the timeout slaves respond. I think buffer problem.

The solution: Read 18B20 dallastemperature asynchronously.

Here’s how to:

I hope to help someone.


Hello

I have a problem with SimpleModbus and waits.

Slaves SimpleModbus stops responding with long waits. Sometimes, after a few minutes! becomes responsive, but usually never ever responds. It is necessary to reset the slave.

If we read temperature “DallasTemperature” and OneWire, the code has long waits. > 1000ms

I do not understand why he does this. It is possible a solution?

Thanks

#include <SimpleModbusSlave.h>

#define  LED 9  

enum 
{     
  ADC_VAL,     
  PWM_VAL,  
  kkk  ,
  kkk2,
  kkk3,
  mmmm,
  llll,
  HOLDING_REGS_SIZE // leave this one
};

unsigned int holdingRegs[HOLDING_REGS_SIZE]; // function 3 and 16 register array

void setup()
{
	
  modbus_configure(&Serial, 9600, SERIAL_8N2, 4, 2, HOLDING_REGS_SIZE, holdingRegs);

}


unsigned long tiempo;
#define RETARDO_SENSORES 10000 
void loop()
{
  
  modbus_update();
  
  holdingRegs[ADC_VAL] = 888;
  holdingRegs[kkk] = 444;
  holdingRegs[kkk2] = 4445;

  
  if(millis() - tiempo > RETARDO_SENSORES){ 
    delay(1500);
   } 
    
}
#include <SimpleModbusMaster.h>

#define baud 9600
#define timeout 500
#define polling 200 // the scan rate
#define retry_count 100
#define TxEnablePin 2 

enum
{
  PACKET1,
  TOTAL_NO_OF_PACKETS // leave this last entry
};

Packet packets[TOTAL_NO_OF_PACKETS];

packetPointer packetSalon = &packets[PACKET1];
unsigned int RegistrosSalon[11];

void setup()
{
  
  Serial.begin(115200);
  modbus_construct(packetSalon, 4, READ_HOLDING_REGISTERS, 0, 7, RegistrosSalon);
  modbus_configure(&Serial1, baud, SERIAL_8N2, timeout, polling, retry_count, TxEnablePin, packets, TOTAL_NO_OF_PACKETS);
  
}


unsigned long tiempo=0;
void loop()
{
  modbus_update();
  
if(millis() > tiempo+3000){
    
  Serial.println("");
   Serial.print("SALON->Paquetes_OK: ");
   Serial.print(packetSalon->successful_requests);  
   Serial.print("  SALON->Paquetes_MAL:  ");
   Serial.println(packetSalon->failed_requests);    
   Serial.print("Resultados: ");
   Serial.println(RegistrosSalon[0]);  
   Serial.print("Temp Salon: "); 
   Serial.println(RegistrosSalon[1]);  
   Serial.print("Luz Salon: ");       
   Serial.println(RegistrosSalon[2]);  
   Serial.print("Tiempo PIR Salon: ");       
   Serial.println(RegistrosSalon[3]);   
   Serial.println(RegistrosSalon[4]);   
   Serial.print("Errores transmision: ");       
   Serial.println(RegistrosSalon[5]);  
 tiempo=millis();
}   
}

the delay doesn't seem to be doing anything... is it a placeholder for some reason?

Additionally, if the master doesn't receive a reply from the slave it just stops sending to it, it looks like you tried to fix it with the increased retry count, but with a lot of long delays no number will suffice.

CraigF is correct.

Plus you do the followingunsigned long tiempo;

Then without equating it to anything you promptly do the followingif(millis() - tiempo > RETARDO_SENSORES)

That variable possibly is zero, but you need to assign it something like the previous millis() for it to make any sort of sense.

Look at examples of how to use a non-blocking delay correctly.


Paul

Thanks for responding.

“Delay (1500);” replaces a code to read temperature sensor 18B20.

I used “delay (1500);” to make the code more understandable.

if(millis() - tiempo > RETARDO_SENSORES)

This is for reading “Serial.print ();” more easily. Please ignore it.

Edit: Sorry rockwallaby. You’re right.

Additionally, if the master doesn't receive a reply from the slave it just stops sending to it, it looks like you tried to fix it with the increased retry count, but with a lot of long delays no number will suffice.

CraigF, Yes I know.
If you test code that will verify the slave will never again respond (unless reset slave). You can restart the master many times as you want. That's the problem.

Delay(1500); = SimpleModbus Slave Kaput, KO, Off... =(

SOLVED¡¡

  if(millis() - tiempo > RETARDO_SENSORES){ 
    delay(1500);
  modbus_update_comms(9600, SERIAL_8N2, 1);    //  <- "Edit: NO" SOLVED PROBLEM (apparently)
   }

It’s not elegant, but it works.
I’m testing now. For now it works ¡

Thanks¡

Edit: The problem is reduced but does not disappear.

rockwallaby say ok.
It is a programming error of mine.

Sorry.

Hi Antonio,

For reference I have included the email you sent me that links to this thread:

"Hello Juan

Sorry for translation.
Thank you for your very good simplemodbus library.
I have a problem.
I have home automation system with 7 slaves in my house.
Modbus works perfect with each one individually, but when more than one start errors.
—> If the master calls a only one slave, everything works perfectly. <—
If not, some slaves stop responding. And never respond more (normally). You need reset.
Randomly, sometimes, a slave still working. After a while.
Wear weeks testing combinations of parameters. Always similar result. (slaves off change)

Testing baud 57400 and 14400
Testing timeout 1000 to 50
Testing polling 500 to 10
Testing TxEnablePin 2 to 5 (possible interrupt problem)

I’m desperate.
Can you help?

Best regards,
Antonio"

Looking at your timeout and polling values I can see why you are getting random successful responses from your slave.

Your understanding of polling and timeout is resulting in some confusion.

The slave is responding with valid information only 750ms - 1000ms because of the onewire communication delay. Serial information is still received by the SMS library and once it gets to modbus_update() it responds with valid information but the master has already timed out as a result of your low timeout value. A small polling value only makes matters worst. If the master transmits a package it waits for the slave to respond but this never happens in time. It then goes to the next slave at the rate determined by the polling rate. If the polling rate is too fast the slave will never react on the message in the first place.

I have added a delay of 5000ms to the example sketch and tested it with Mtester with a timeout of 1000ms and a polling of 200ms and guess what… it does not work. I get maybe 1 successful response at random every 2 minutes or so. I then increased the polling rate to 5000ms and get valid responses more frequently but also at random. Finally I increased the timeout value to 5000ms and get a 100% success rate for 5 minutes with polling rate of 100ms. The low polling value shows how quick the arduino with the example sketch is returning to the start of the finite state machine. Most slaves do not return to idle (the start of the state machine cycle) in such a short time. Usually its around 200ms - 1000ms. Definitely the timeout and maybe the polling is affecting your response success rate.

Try a timeout of 2000ms and a polling value of 2000ms. If you are happy with the communication try to reduce the polling value so that the slaves are polled more frequently until you get some errors, this is the polling limit. The timeout should never come in to play if the slaves are responding in time.

Good luck.

Hello JuanB

Thanks, again, for your simplemodbus library.

The major problem is that the slave stops responding and not awake (never ever). Because of the delay().

Is it possible that the slave detects the standby status and restart?

I thought that the master sends a data every second for the slave restart when not received. But it is not elegant solution.

Thank you