What’s the best logic for this?

I have 5 slave units that need to report their condition. They all must report before the loop ends and the result would be: correct order results in output. Or incorrect sequence results in other output (this output would reset all slaves and at that point they would begin again anew). I would prefer that the concept be one that allows the slaves to go from high to low upon completion of their sequence as they are programmed this way already and the units are sealed. I have had an issue or two so far and I would like some ideas on what types of logic you might use to tackle such a problem before I offer my thoughts and contaminate the thought pool. Any ideas welcome and thanks for your input.

1.) Please explain what your project is supposed to do once it's completed. This give you (and us) a roadmap as to what you want to accomplish
2.) Please post your code in tags (slave code and current master code)
3.) Please, please, please do not use run-on sentences. They are difficult to follow

tinvestor:
They all must report before the loop ends

Before what loop ends?

tinvestor:
They all must report before the loop ends

Note that the process of working through a logical "loop" in your project may take several hundred, or maybe several thousand iterations of the Arduino loop() function.

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be many calls to a function before it is actually time for it to do anything.

Plus what @Power_Broker asked.

...R

Robin2:
Note that the process of working through a logical "loop" in your project may take several hundred, or maybe several thousand iterations of the Arduino loop() function.

That's why I asked what OP meant by "loop": their idea of a logical loop (which might perhaps be better called a "cycle" to prevent confusion) or the Arduino's idea of loop().

One certainly never wants to discourage loop() from running as fast as it can.

i read the concept of several thing at a time but all was so confusion ... can you explain as simple in words

Asad_Ullah019:
i read the concept of several thing at a time but all was so confusion

Did you only read it, or did you work through the code and run it? All you need is a few leds, a button (or jumper wire) and a servo.

So to summarise (this is back to tinvestor’s main thread) and having looked at your other thread, you have 5 inputs that need to go low in order from 0-4. If they do go low in order, that counts as Success; if any one goes low out of sequence, that’s a Failure. For the purposes of this thread, to get the logic sorted, they can just be buttons held high until pressed low?

Is that it?

I’d go for something along the lines of using state change detect but with the pins in an array, and a counter for what input is expected to go low next. If the correct pin goes low, increment the counter ready for the next one, until the end of the array at which point we know the sequence was correct: Success. If the pin that goes low is not the one we expect: Failure. In either case, the counter is reset: either because we were happy with the sequence and are ready for the next cycle, or because we aborted this cycle.

Asad_Ullah019:
i read the concept of several thing at a time but all was so confusion ... can you explain as simple in words

I don't know how to explain it more simply than what I said in Reply #3.

I find that computer stuff starts to make sense after the 14th read (not entirely a joke). Certainly the hour and a half between my Reply #3 and your Reply #5 is not enough thinking / learning time.

A good analogy is the business of roasting a chicken. You don't sit in front of the oven for 90 minutes waiting for the roast to complete. You put the chicken in the oven, note the time and every so often you check the clock to see if 90 minutes has elapsed. In between checking the clock you may be writing a letter to your Grandma or hoovering the living room or ...

...R

Asad_Ullah019:
I read the concept of several thing at a time but all was so confusion ... can you explain as simple in words

Let me try. The loop() consists of a chain of tests. Each test determines whether something has happened which requires an action and if so, performs that action or if not, just passes on to the next test in the chain.

Each action in terms of this definition is instant, it takes no time to perform. Or at least, no significant time in terms of the overall process. There is no delay involved in such an action.

So you say "but I need a delay here and there"! That's OK, it's quite easy! A delay involves two actions; starting the delay and ending the delay. To start the delay, you set a flag to mark that a delay is occurring, and you take a note (in a variable) of the time in millis() that it started. But that's all you do; you then pass on to the next step in the loop() chain.

To determine the end of the delay, a step in the loop() looks at the flag (the first test), sees that a delay is in progress, so looks at the current millis() and compares it to (subtracts from it) the recorded time the delay started. If (second test) the elapsed time is less than the desired delay, it passes on to the next step in the loop() chain. If the delay has expired, then it initiates the action that was to be performed after the delay (and clears the delay flag so that does not continue to be trapped in successive passes of the loop()).

Any other process in handled in the same manner - start that process, set a flag to mark that it is happening, test on successive passes through the loop() to see if it is complete or a next step is required.

If a process actually requires substantial computational time, that process (element in the chain) may need to be broken up into smaller sections to allow for other important tests to be made, especially those which may need to interrupt - that is, abort - that process. This is quite different to and must not be confused with the use of the interrupt functionality of the processor.

Back to OP’s question.

The code below does what I summarised earlier, ie simply checks if 5 pins go low in the right order, and reports Success or Failure.

Press a button....
 
Button 4 was pressed out of sequnece
*** FAILURE ***
Resetting for next cycle
Button 0 was pressed in sequence
Button 1 was pressed in sequence
Button 2 was pressed in sequence
Button 3 was pressed in sequence
Button 2 was pressed out of sequnece
*** FAILURE ***
Resetting for next cycle
Button 0 was pressed in sequence
Button 1 was pressed in sequence
Button 2 was pressed in sequence
Button 3 was pressed in sequence
Button 4 was pressed in sequence
*** SUCCESS ***
Resetting for next cycle
// https://forum.arduino.cc/index.php?topic=649880
// check to see if buttons are pressed in the right order
// state change detect on a button array
// 24 nov 2019

// the buttons
byte buttonPins[] = {14, 15, 16, 17, 18}; //the buttons must be wired from pin to ground, pinmodes are input_pullup
const byte howManyButtons(sizeof(buttonPins) / sizeof(buttonPins[0]));
bool buttonStates[howManyButtons];         // current state of the button
bool lastButtonStates[howManyButtons];     // previous state of the button
byte expectingButtonNumber = 0;

void setup()
{
  // initialize serial communication:
  Serial.begin(9600);
  Serial.println("setup() ... ");
  Serial.println("Buttons pressed in right sequence?");

  // initialize the button pins as input with pullup so active low
  //    make sure the button is from pin to ground
  Serial.print("Initialising "); Serial.print(howManyButtons); Serial.println(" buttons (button/pin):");
  for (int i = 0; i < howManyButtons; i++)
  {
    pinMode(buttonPins[i], INPUT_PULLUP);
    Serial.print(i); Serial.print("/");
    Serial.print(buttonPins[i]); Serial.print(" ");
    //initialize button states
    buttonStates[i] = digitalRead(buttonPins[i]);
    lastButtonStates[i] = buttonStates[i];
  }
  Serial.println(" ");
  Serial.println("setup() done");
  Serial.println("Press a button....");
  Serial.println(" ");
}

void loop()
{
  checkForNextButton();
} //loop

void checkForNextButton()
{
  for (int i = 0; i < howManyButtons; i++)
  {
    buttonStates[i] = digitalRead(buttonPins[i]);
    // compare the buttonState to its previous state
    if (buttonStates[i] != lastButtonStates[i]) // means it changed... but which way?
    {
      if (buttonStates[i] == LOW)  // changed to pressed
      {
        Serial.print("Button ");
        Serial.print(i);
        Serial.print(" was pressed");
        if (expectingButtonNumber == i)
        {
          Serial.println(" in sequence");
          expectingButtonNumber++;
          if (expectingButtonNumber == howManyButtons)
          {
            Serial.println("*** SUCCESS ***");
            Serial.println("Resetting for next cycle");
            expectingButtonNumber = 0;
          }
        }
        else
        {
          Serial.println(" out of sequnece");
          Serial.println("*** FAILURE ***");
          Serial.println("Resetting for next cycle");
          expectingButtonNumber = 0;
        }
      }
      // ersatz de-bounce
      delay(50);
    }
    // save the current state as the last state, for next time through the loop
    lastButtonStates[i] = buttonStates[i];
  }
} // checkForNextButton()

Should be easy enough to incorporate that thinking into your main sketch, and have it do whatever it needs to do on success or failure?

Asad_Ullah019:
i read the concept of several thing at a time but all was so confusion ... can you explain as simple in words

A tutorial on that lesson: Gammon Forum : Electronics : Microprocessors : How to do multiple things at once ... like cook bacon and eggs

Where he uses the cooking breakfast analogy, think turkey bacon which is allowed to all. (wink&smile)

He tells what the code will be doing and after he shows the code with more explaination.

Let's look at an analogy. Say you want to cook breakfast. You need to cook:

Coffee - takes 1 minute
Bacon - takes 2 minutes
Eggs - takes 3 minutes

Now a seasoned cook would NOT do this:

Put coffee on. Stare at watch until 1 minute has elapsed. Pour coffee.
Cook bacon. Stare at watch until 2 minutes have elapsed. Serve bacon.
Fry eggs. Stare at watch until 3 minutes have elapsed. Serve eggs.

The flaw in this is that whichever way you do it, something is going to be cooked too early (and get cold).

In computer terminology this is blocking. That is, you don't do anything else until the one task at hand is over.

What you are likely to do is this:

Start frying eggs. Look at watch and note the time.
Glance at watch from time to time. When one minute is up then ...
Start cooking bacon. Look at watch and note the time.
Glance at watch from time to time. When another minute is up then ...
Put coffee on. Look at watch and note the time.
When 3 minutes are up, everything is cooked. Serve it all up.

In computer terminology this is non-blocking. That is, keep doing other things while you wait for time to be up.

That last 2 lines are the point, the rest are how to make it so.

When one of the inputs goes low out of sequence, how specifically do you want to handle that? Do you report the error immediately, or do you wait for the remaining inputs to go low then report the error? When there is an error, do you need to wait until all inputs have gone low within that "cycle" before starting the next "cycle"? If not, is there some way for the arduino to signal to the slave units that the current "cycle" is over and to start a new one, so that the arduino doesn't start over in the middle of a previous "cycle" and start throwing error messages for every input until it gets back into synchronization with the slave units.

Another question pertaining to the code you posted in your other thread, when there is success or failure, you activate an output pin, delay, deactivate the output pin, then delay again. Are those delays expected by the slave units, or is there a possibility of the inputs going low during the delay time? If multiple inputs go low during the delay time, the arduino has no way to determine the order in which they went low.

david_2018:
When one of the inputs goes low out of sequence, how specifically do you want to handle that?....

All good questions. My code in #10 just says Failure as soon as it sees one out of sequence and resets the counter. My intention was just to show that it's easy to check the sequence with the pins in an array. Once OP replies to your questions, it would be quite simple to make the code more robust.