How to use a time out?

Hello,

I am running a program in which master communicates with two slaves. It sends a request to both slaves and receives the values. If in case the first slave is busy with another operation, the master needs to move to second slave for the further operation.

But this does not happen, the master is stuck with the first slave and never goes to second slave. How do I add a time-out if a particular slave does not reply at a certain time and so the Master shall send request to next slave?

Here is my master code:

#include "RS485_protocol.h"
#include <SoftwareSerial.h>
#define TOTAL_SLAVES 2
const byte ENABLE_PIN = 2;
long data_matrix[TOTAL_SLAVES][2];
//const byte ENABLE_PIN1 = 3;
SoftwareSerial rs485 (10, 11);

long data_s[2];

uint8_t x = 0;
uint8_t y = 0;
//uint8_t a[3][2] = {0};
boolean stopp = false;
int n = 1;
uint8_t ch;
int col = 0;
long  bignum;
uint8_t b[4];
long values_rec[2];
boolean rep = false;
void setup() {


  rs485.begin (28800);
  pinMode (ENABLE_PIN, OUTPUT);
  Serial.begin(9600);

}


void loop() {
  Serial.flush();
  char req[2];

  req[0] = 'R';
  req[1] = n + '0';
  digitalWrite (ENABLE_PIN, HIGH);
  rs485.write(req, sizeof(req));
  Serial.println("requesting from slave ");
  Serial.println(n);
  digitalWrite (ENABLE_PIN, LOW);
  delay(1000);

  while ( rs485.available())
  {
    digitalWrite (ENABLE_PIN, LOW);
    while ((ch = rs485.read()) != 'E') {

      //Serial.println(x);

      b[0] = ch;
      b[1] = rs485.read();
      b[2] = rs485.read();
      b[3] = rs485.read();

      bignum = *((long *)b);

      Serial.println("Value received:");
      data_matrix[n - 1][col++] = bignum;
      Serial.println(bignum);
      delay(1000);

    }
    if (ch == 'E') {

      Serial.println("End Value received from slave:");
      Serial.println(n);

      n++;
      col = 0;

      digitalWrite (ENABLE_PIN, HIGH);
      delay(1000);
      ch = 0;
      if (n > TOTAL_SLAVES) {
        Serial.println("Sending back all values");
        for (int i = 0; i < TOTAL_SLAVES; i++)
        {
          uint8_t buf[6] = {0};
          for (int j = 0; j < 2; j++)
          {
            Serial.println(data_matrix[i][j]);
            buf[5] = (uint8_t)((data_matrix[i][j] >> 24) & 0xFF);
            buf[4] = (uint8_t)((data_matrix[i][j] >> 16) & 0xFF);
            buf[3] = (uint8_t)((data_matrix[i][j] >> 8) & 0xFF);
            buf[2] = (uint8_t)(data_matrix[i][j] & 0xFF);
            buf[1] = i + 1;
            buf[0] = 'S';

            rs485.write(buf, sizeof(buf));
            delay(100);
          }

        }
        n = 1;
        //delay(200);
      }

      digitalWrite (ENABLE_PIN, LOW);

    }

  }

}

Thank you.

write RS485 in the title of the thread

saifshk17:
if in case the first slave is busy with another operation, the master needs to move to second slave for the further operation.

In that case the very last thing you should have in your program is delay() because that prevents the Arduino from doing anything else.

The simple way to implement a timeout is to save the value of millis() when you send a message and then constantly compare the latest value of millis() with the saved value. If no response comes before the timeout interval then move on to the other slave. Something like this pseudo code

void loop() {
    if (waitingForReply == false) {
        Serial.println(messageToSlave);
        messageSentMillis = millis();
        waitingForReply = true;
    }
    checkForReply();
    if (waitingForReply == false and millis() - messageSentMillis >= timeoutMillis) {
       // reply is taking too long
    }
}

...R