Sequence of time-dependent operations

Okay, what your trying to do is quite tricky when using timeout timers.

First of all, it helps if you use tab indents in a sensible way when you write your code, and it also helps to add lots of comments (these are good things to do anyway, it make your code more readable).

This is what the code for a single timeout timer would look like…

BLYNK_WRITE(VPinSequence)
{
  if (param.asInt()==1)
  {   
    // we do the following if the VPinSequence switch widget is ON...
    
    // your code in here to Activate Relay 1 For 5 seconds...
    Relay1State = 1;
    digitalWrite(Digital1Pin, Relay1State);
    Blynk.virtualWrite(VPin1, Relay1State);    
    
    // now that Relay1 is on, we start a timer...
    timer.setTimeout(5000L,[]()
    {
    // the following code will execute when the timeout ends...
      //
      Relay1State = 0;  
      digitalWrite(Digital1Pin, Relay1State);
      Blynk.virtualWrite(VPin1, Relay1State);
      // If you wanted to trigger another timeout timer when this one completes
      // then that code would need to go in here...
       
    }); // End of the timeout timer lambda function
  }
  else
  {
    // We get here if the VPinSequence switch widget is OFF...
    // You can add your code in here to turn off all of your relays
  }
}

As you can see, you were previously turning your relay ON in the part of the code that is executed when the timeout timer ends.
The whole idea of using BlynkTimer in a timeout mode is that it’s non-blocking, but this causes a problem for you. Once the timer is started, the rest of the sketch is executed, and in your case this meant that these three lines of code were executed, which turned the relay OFF…

So, I’d imagine that when you turned the widget button on, the relay went off, then came on after 5 seconds and stayed on.

This non-blocking feature is also going to mean that you can’t simply add one timeout timer after another, they have to be nested within each other - I’ve added a comment saying:

  // If you wanted to trigger another timeout timer when this one completes
  // then that code would need to go in here...

This obviously gets very messy, even if you’ve structured and commented the code well.

I’ve explained this issue with an example in the “Timeout Timers” section of this tutorial…

There is also another potential issue. What do you want to happen if you turn the widget button off, before the sequence has ended and you’ve reached point “D” in your sequence?
If you’re happy to wait until the full 18 second sequence has ended then that’s fine, otherwise your code will need more refinements.

So, the simplest solution is not to use the Lambda function when using your timeout timers. Instead simply have the timers call a function when they have completed, and use that function to call the next timer in the sequence. Like this,

BLYNK_WRITE(VPinSequence)
{
  if (param.asInt()==1)
  {   
    // we do the following if the VPinSequence switch widget is ON...
    
    // call the function that starts the cascading sequnece of timers
    relay1_on();
  }
  else
  {
    // We get here if the VPinSequence switch widget is OFF...
    // You can add your code in here to turn off all of your relays
  }
}

void relay1_on()
{
  // start by turning relay 1 on...  
  
  Relay1State = 1;
  digitalWrite(Digital1Pin, Relay1State);
  Blynk.virtualWrite(VPin1, Relay1State);   
  
  // then start a timer that will call the relay1_off_relay2_on function when it completes...
  timer.setTimeout(5000L, relay1_off_relay2_on);
}

void relay1_off_relay2_on()
{
  // start by turning relay 1 off...
  Relay1State = 0;  
  digitalWrite(Digital1Pin, Relay1State);
  Blynk.virtualWrite(VPin1, Relay1State);
  
  // then turn relay 2 on...
  Relay2State = 1;
  digitalWrite(Digital2Pin, Relay2State);
  Blynk.virtualWrite(VPin2, Relay2State);     
  
  // then start a timer that will call the relay2_off_relay1_on_again function when it completes...  
  timer.setTimeout(8000L, relay2_off_relay1_on_again);  
}

void relay2_off_relay1_on_again()
{
  // start by turning relay 2 off...
  Relay2State = 0;  
  digitalWrite(Digital2Pin, Relay2State);
  Blynk.virtualWrite(VPin2, Relay2State);

  // then turn relay 1 on (again)...
  Relay1State = 1;
  digitalWrite(Digital1Pin, Relay1State);
  Blynk.virtualWrite(VPin1, Relay1State); 
  
  // then start a timer that will call the relay1_off_relay3_on function when it completes...  
  timer.setTimeout(5000L, relay1_off_relay3_on);  
}


void relay1_off_relay3_on()
{
  // start by turning relay 1 off...
  Relay1State = 0;  
  digitalWrite(Digital1Pin, Relay1State);
  Blynk.virtualWrite(VPin1, Relay1State);

  // then turn relay 3 on...
  Relay3State = 1;
  digitalWrite(Digital3Pin, Relay3State);
  Blynk.virtualWrite(VPin3, Relay3State); 
  
  // No timer this time, relay 3 just stays on  
}

Pete.

1 Like