Non-Blocking sktech

Hello agili

Of course, my sketch is a test version and you still need to adapt the sketch to your requirements, as mentioned before.

Have a nice day and enjoy programming in C++ and learning.

I´m not desperate !!

This line of code is extremely intelligently designed and must be seen in the overall context.

In short words: if the last member of the sequence was activated than use member One or use the next one.

LOL, I'm talking to the original poster, who appears to say, "that's not quite the finished complete sketch that I need, yet". :slight_smile:

My interpretation, asking to use member One is a way to force a repeat of the sequence. But it was a guess.

Did I get it right?

The OP wants a sequence to run after a button switch event, run to completion and wait for the next button switch event. Edit - perhaps allow the button to restart the sequence at any time... EDit or cancel the sequence.. unsure...

Which should be fairly easy to add to any sequencing code...

Hello aarg

Yes you are right.

Indeed it seems to be easy to add a button action to the sketch.

PSEUDOCODE:

if (button==pressed && sequencerIsNotRunning) startSequencer(); 

However, this exention could and should be coded by the questioner themself.

Have a nice day and enjoy programming in C++ and learning.

I think this is not the questioners mindset. :slight_smile:

That's because I reversed the logic, my mistake. I based the code solely on the code in the opening post and did not consider code in later posts (#24).

Your relays are ON when you write a LOW so let's add that to the code.

// define sensible names for on and off
#define RELAY_ON LOW
#define RELAY_OFF !RELAY_ON

You can now use RELAY_ON to switch the relay ON and RELAY_OFF to switch it off. If you ever have to change it, you only have to changethe first line and the second line will follow.

I've added your relay names and adjusted the array.

// macro to calculate the number of elements in any type o array (int, char, struct)
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))

// define sensible names for on and off
#define RELAY_ON LOW
#define RELAY_OFF !RELAY_ON

// relay pins
const uint8_t RelayPompe = 2;
const uint8_t RelayVanne7 = 3;
const uint8_t RelayVanne6 = 4;
const uint8_t RelayVanne5 = 5;
const uint8_t RelayVanne4 = 6;
const uint8_t RelayVanne3 = 7;
const uint8_t RelayVanne2 = 8;
const uint8_t RelayVanne1 = 9;


// structure with information about a relay event
struct RELAY_EVENT  //
{
  const uint8_t pin;        // the pin that the relay is connected to
  const uint8_t pinState;   // the state that you want to set the pin to (LOW or HIGH)
  const uint32_t duration;  // the duration that we need to wait before continuing with the next relay event
  uint8_t smState;          // the state of the relay statemachine (0 = set pin state and start delay timer, 1 = wait for delay timer to time out)
};

// array with relay events
RELAY_EVENT events[] = {
  { RelayPompe, RELAY_ON, 10000UL, 0 },
  { RelayVanne1, RELAY_ON, 3000UL, 0 },
  { RelayVanne2, RELAY_ON, 15000UL, 0 },
  { RelayVanne1, RELAY_OFF, 20000UL, 0 },
};

// the button
const uint8_t buttonPin = 12;

void setup()  //
{
  Serial.begin(115200);
  // loop through the events to set the pin mode; note that they might be multiple times
  for (uint8_t cnt = 0; cnt < NUMELEMENTS(events); cnt++)  //
  {
    Serial.print(F("Switching relay OFF on pin "));
    Serial.println(events[cnt].pin);
    digitalWrite(events[cnt].pin, RELAY_OFF);

    Serial.print(F("Switching relay pin "));
    Serial.print(events[cnt].pin);
    Serial.println(F(" to output"));
    pinMode(events[cnt].pin, OUTPUT);
  }

  pinMode(buttonPin, INPUT_PULLUP);
}

And the rest of the code; I've made some modifications to the sequencer so you have a better idea what is happening.

void loop()  //
{
  if (sequencer() == false) {
    Serial.println(F("Sequence complete"));
    // hang forever
    for (;;)  //
    {
    }
  }

  if (digitalRead(buttonPin) == LOW) //
  {
    Serial.print(millis());
    Serial.println(F("\tbutton is pressed"));
  }
}


/*
  sequencer to control the relay sequence
  Returns:
    true if sequence is in progress
    false if sequence is completed (or aborted)
*/
bool sequencer() {
  static uint8_t activeEventNumber = 0;
  static uint32_t startTime;

  if (events[activeEventNumber].smState == 0)  //
  {
    digitalWrite(events[activeEventNumber].pin, events[activeEventNumber].pinState);
    startTime = millis();

    Serial.print(millis());
    Serial.print(F("\tStep: "));
    Serial.print(activeEventNumber);
    Serial.print(F(", smState = "));
    Serial.print(events[activeEventNumber].smState);
    Serial.print(F(", Relay on pin "));
    Serial.print(events[activeEventNumber].pin);
    if(events[activeEventNumber].pinState == RELAY_OFF)
    {
       Serial.println(F(" switched OFF"));
    }
    else
    {
       Serial.println(F(" switched ON"));
    }

    events[activeEventNumber].smState++;
  }     //
  else  //
  {
    if (millis() - startTime >= events[activeEventNumber].duration)  //
    {
      Serial.print(millis());
      Serial.print(F("\tStep: "));
      Serial.print(activeEventNumber);
      Serial.print(F(", smState = "));
      Serial.print(events[activeEventNumber].smState);
      Serial.println(F(" timed out"));

      events[activeEventNumber].smState = 0;
      activeEventNumber++;
      if (activeEventNumber >= NUMELEMENTS(events)) {
        // if all step of the sequence are executed, return false to indicate that the sequencer is no longer in prograss
        return false;
      }
    }
  }
  // indicate that the sequencer is in progras.
  return true;
}

Output:

Switching relay OFF on pin 2
Switching relay pin 2 to output
Switching relay OFF on pin 9
Switching relay pin 9 to output
Switching relay OFF on pin 8
Switching relay pin 8 to output
Switching relay OFF on pin 9
Switching relay pin 9 to output
15	Step: 0, smState = 0, Relay on pin 2 switched ON
10015	Step: 0, smState = 1 timed out
10015	Step: 1, smState = 0, Relay on pin 9 switched ON
13015	Step: 1, smState = 1 timed out
13015	Step: 2, smState = 0, Relay on pin 8 switched ON
28015	Step: 2, smState = 1 timed out
28015	Step: 3, smState = 0, Relay on pin 9 switched OFF
48015	Step: 3, smState = 1 timed out
Sequence complete

Hope i gets you on the right track now.

@agili
Paul's got it.

aarg yes so desperate trying to explain the kind of issue I have, as I wrote several time I need a simple function like this one but in non blocking sketch:


      digitalWrite(Relay1, LOW);
      delay(3000); 

      digitalWrite(Relay2 LOW);
      delay(10000);    

      digitalWrite(Relay3, LOW);
      delay(3000);

      digitalWrite(Relay2, HIGH);
      delay(10000);

      digitalWrite(Relay4 LOW);
      delay(3000);

      digitalWrite(Relay3, HIGH);
      delay(10000);

      digitalWrite(Relay5, LOW);
      delay(3000);

      digitalWrite(Relay4, HIGH;
      delay(10000);

      digitalWrite(Relay6, LOW);
      delay(3000);

      digitalWrite(Relay5 HIGH);
      delay(10000);

      digitalWrite(Relay7 LOW);
      delay(3000);

      digitalWrite(Relay6 HIGH);
      delay(10000);

      digitalWrite(Relay8, LOW);
      delay(3000);

      digitalWrite(Relay7, HIGH);
      delay(10000);

      digitalWrite(Relay8, HIGH);
       delay(3000);

      digitalWrite(Relay1, HIGH);

I tryied all suggessions posted but they simply dont do the same sequece as this blocking sketch.

then you have to pay someone to write it for you

aarg I would drop using millis and use an other arduino board, but am on the way learning and know will do it it is a matter of time, I have plently of time to try again and again. Thanks for advice

@aarg
if you know how to do it you wouldn't hesitate to tell but you dont know how just watching. I understand it is complicated as it is so simple, but it has a solution for sure wil popup soon.

i have done it hundreds of times. applying the technique still requires a lot of time and effort. so it is very unlikely that anyone here will do it for free.

the theory is simple but to code a specific sequence for specific applications is a time consuming job.

at least I am correct, you are sitting there waiting for someone to do your work for you.

@agili
You tell us repeatedly you've tried everything we've suggested, but I have to say you haven't grasped the basic precept here - people don't just write your code for you, they try to help you comprehend what needs doing by providing samples, pointers to samples, etc. so that you can learn and do it yourself. Doing it for you, that's likely easy, but you'll pay. To be quite honest, you'll face a mountain of questioning from someone who sets out to do it for $, because they will want to know what you want done in excruciating detail, before committing to even naming a price. So you have a choice, you can try to learn from what's been said, or you can go to the jobs subforum here and pay someone for your needs; be prepared to document what you want very well, if you do that. That's my two cents, anyway.
C

camsysca I never asked to write a sketch for me, apparently you dont read my posts, it is only small part of my sketch wich I have difficulty to solve else my sketch is much larger than that part, I appreciate your effort helping me. Thanks

Something for you to experiment with

//https://forum.arduino.cc/t/non-blocking-sktech/1013571

const byte relayPins[] = {3, 5, 6, 9};

struct phaseData
{
  byte pinIndex;        //index to relay pin
  byte state;           //state for this phase
  unsigned long period; //length of this phase
};

phaseData phases[] =
{
  {0, LOW, 1000}, //relay 0 on for 1000 milliseconds
  {0, HIGH, 500},   //turn off relay 0 for 500 milliseconds
  {1, LOW, 2000}, //relay 1 on for 2000 milliseconds
  {1, HIGH, 500},   //turn off relay 1 for 500 milliseconds
  {2, LOW, 3000}, //and so on
  {2, HIGH, 500},
  {3, LOW, 4000},
  {3, HIGH, 500},
  {0, LOW, 1000}, //blink relay 0 twice
  {0, HIGH, 1000},
  {0, LOW, 1000},
  {0, HIGH, 1000},
  //add more phases here in the same format
};

const byte RELAY_COUNT = sizeof(relayPins) / sizeof(relayPins[0]);
const byte PHASE_COUNT = sizeof(phases) / sizeof(phases[0]);
boolean phasesDone = false;

void setup()
{
  Serial.begin(115200);
  Serial.print(PHASE_COUNT);
  Serial.println(" phases");
  for (int relay = 0; relay < RELAY_COUNT; relay++)
  {
    pinMode(relayPins[relay], OUTPUT);
    digitalWrite(relayPins[relay], HIGH);
  }
}

void loop()
{
  if (!phasesDone)
  {
    phaseControl();
  }
  //
  //any other **non blocking** code goes here
  //
}

void phaseControl()
{
  unsigned long currentTime = millis();
  static unsigned long phaseStartTime = millis();
  static byte phase = 0;
  currentTime = millis();
  digitalWrite(relayPins[phases[phase].pinIndex], phases[phase].state);
  if (currentTime - phaseStartTime >= phases[phase].period)
  {
    phaseStartTime = currentTime;
    phase++;
    if (phase == PHASE_COUNT)
    {
      phasesDone = true;
    }
  }
}

NOTE that you need to adjust the data in the relayPins array to match your pin numbers and the data in the phases array to match what you want the relays to do

I fully expect you to freak at this line

  digitalWrite(relayPins[phases[phase].pinIndex], phases[phase].state);

You can choose to just use it as it is or analyse how it gets the pin number and state

Snippets-R-Us! :grin:

UKHeliBob great job many thanks for your and all who helped with this issue, I had to do few changes and looks like this know:

phaseData phases[] = {
{ 1, LOW, 3000 },
{ 0, LOW, 10000 },
{ 2, LOW, 3000 },
{ 1, HIGH, 10000 },
{ 3, LOW, 3000 },
{ 2, HIGH, 10000 },
{ 4, LOW, 3000 },
{ 3, HIGH, 10000 },
{ 5, LOW, 3000 },
{ 4, HIGH, 10000 },
{ 6, LOW, 3000 },
{ 5, HIGH, 10000 },
{ 7, LOW, 3000 },
{ 6, HIGH, 10000 },
{ 8, LOW, 3000 },
{ 0, HIGH, 3000 },
{ 8, HIGH, 10000 }, // Only this pin it does not turn off at the end of sequence? any idea?
};

Paul_B I am not snipping anything but just learning, this is no commercial work, besides, why telling Snippets-R- "Us" ??? why you include your self in this sketch :face_with_raised_eyebrow: as far as I see you are an Unused Expression. :slight_smile: anway thank you too.

Add another phase
(8, LOW, 0) //relay 8 LOW and end phase immediately

don know how to thank you. thank you every body participated in correction this sketch. To tell you, all my confiusing was the number of the pin of the first relay wich was 0 and not 1, anyway I will remember that forever. Great forum great members and admins. I will stay here learning more :slight_smile: