user76566: So Im having trouble trying to figure this out. My project needs a valve to stay shut and when an event is triggered, 3 seconds into that event the valve opens for 2 seconds, then remain shut till it's triggered again. I was just treating it like an LED in the code. I was trying to code it to jump from one if-statement to the next with the appropriate delays but it doesn't work the way i thought it would. Any help would be great. Thanks
//the event does ventGo0 = true;
     
 if(((millis() - previousVenting) > offoffDuration)&&(ventGo0==true)){ 
        previousVenting1 = millis();
        ventGo1=true;
        ventGo0=false;
       }

 

     if(((millis() - previousVenting1) > onDuration)&&(ventGo1==true)){ 
       digitalWrite(ventPin, HIGH);
       previousVenting2 = millis();
       ventGo2=true;
       ventGo1=false;
     }
       
    
      
       if(((millis() - previousVenting2) > offDuration)&&(ventGo2==true)){  
         digitalWrite(ventPin, LOW);
         ventGo2=false;
       }
      
      ```


user37523: You could use two millis() based timers.
// Sketch uses 1066 bytes (3%) of program storage space.
// Global variables use 27 bytes (1%) of dynamic memory.
// Arduino Uno, IDE 1.8.9
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

    MillisTimer(unsigned long timeInMilliSeconds):
      m_timeInMilliSeconds(timeInMilliSeconds){
      m_timerActive = 0;
      m_previousMillis = 0;
    }

    bool Update(){
      if(m_timerActive && (millis() - m_previousMillis >= m_timeInMilliSeconds)){
        m_previousMillis += m_timeInMilliSeconds;
        return 1;
      }
      else{
        return 0;
      }
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_previousMillis = millis();
    }

    byte IsActive(){
      return m_timerActive;
    }

};

// Make copies of the object to work with.
MillisTimer TwoSecondTimer(2000);
MillisTimer ThreeSecondTimer(3000);

void setup(){

  // Call this function when an event is triggered.
  ThreeSecondTimer.ReStart();

  // Timer status indicator.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

}

void loop(){

  // Call the update function as fast as possible.
  if(ThreeSecondTimer.Update()){
    digitalWrite(LED_BUILTIN, HIGH);
    ThreeSecondTimer.Stop();
    TwoSecondTimer.ReStart();
  }

  // Call the update function as fast as possible.
  if(TwoSecondTimer.Update() && !ThreeSecondTimer.IsActive()){
    digitalWrite(LED_BUILTIN, LOW);
    TwoSecondTimer.Stop();
  }

}


76566: <p>So Im having trouble trying to figure this out. My project needs a valve to stay shut and when an event is triggered, 3 seconds into that event the valve opens for 2 seconds, then remain shut till it's triggered again. I was just treating it like an LED in the code. I was trying to code it to jump from one if-statement to the next with the appropriate delays but it doesn't work the way i thought it would. Any help would be great. Thanks</p>
<pre><code>//the event does ventGo0 = true;
     
 if(((millis() - previousVenting) &gt; offoffDuration)&amp;&amp;(ventGo0==true)){ 
        previousVenting1 = millis();
        ventGo1=true;
        ventGo0=false;
       }

 

     if(((millis() - previousVenting1) &gt; onDuration)&amp;&amp;(ventGo1==true)){ 
       digitalWrite(ventPin, HIGH);
       previousVenting2 = millis();
       ventGo2=true;
       ventGo1=false;
     }
       
    
      
       if(((millis() - previousVenting2) &gt; offDuration)&amp;&amp;(ventGo2==true)){  
         digitalWrite(ventPin, LOW);
         ventGo2=false;
       }
      
      ```
</code></pre>
 37523: <p>You could use two <code>millis()</code> based timers.</p>
<pre class="lang-cpp prettyprint-override"><code>// Sketch uses 1066 bytes (3%) of program storage space.
// Global variables use 27 bytes (1%) of dynamic memory.
// Arduino Uno, IDE 1.8.9
class MillisTimer{

  private:

    unsigned long m_timeInMilliSeconds;
    unsigned long m_previousMillis;
    byte m_timerActive;

  public:

    MillisTimer(unsigned long timeInMilliSeconds):
      m_timeInMilliSeconds(timeInMilliSeconds){
      m_timerActive = 0;
      m_previousMillis = 0;
    }

    bool Update(){
      if(m_timerActive &amp;&amp; (millis() - m_previousMillis &gt;= m_timeInMilliSeconds)){
        m_previousMillis += m_timeInMilliSeconds;
        return 1;
      }
      else{
        return 0;
      }
    }

    void Start(){
      m_timerActive = 1;
    }

    void Stop(){
      m_timerActive = 0;
    }

    void ReStart(){
      m_timerActive = 1;
      m_previousMillis = millis();
    }

    byte IsActive(){
      return m_timerActive;
    }

};

// Make copies of the object to work with.
MillisTimer TwoSecondTimer(2000);
MillisTimer ThreeSecondTimer(3000);

void setup(){

  // Call this function when an event is triggered.
  ThreeSecondTimer.ReStart();

  // Timer status indicator.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

}

void loop(){

  // Call the update function as fast as possible.
  if(ThreeSecondTimer.Update()){
    digitalWrite(LED_BUILTIN, HIGH);
    ThreeSecondTimer.Stop();
    TwoSecondTimer.ReStart();
  }

  // Call the update function as fast as possible.
  if(TwoSecondTimer.Update() &amp;&amp; !ThreeSecondTimer.IsActive()){
    digitalWrite(LED_BUILTIN, LOW);
    TwoSecondTimer.Stop();
  }

}
</code></pre>
