1

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;
       }
      
      ```
1
  • just a note ... if (ventGo1==true) is same as if (ventGo1)
    – jsotola
    Commented May 8, 2021 at 20:55

1 Answer 1

1

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();
  }

}
3
  • Great thanks Ve7jro. I put your code in my project and it works great, just what I needed. When the arduino is booted up for the first time, it does tigger the the led or in my case the valve. Is there a way to stop that from happening? Thanks
    – Jason8899
    Commented May 8, 2021 at 23:24
  • @Jason8899 _ If you update your question with the complete "sketch", I'll take a look at it for you. Keep in mind that, ThreeSecondTimer.ReStart(); in setup() starts the timer immediately, so you should remove it from setup() and add it to your code, the "event driven" part of your code.
    – VE7JRO
    Commented May 8, 2021 at 23:44
  • I found the issue, thanks again.
    – Jason8899
    Commented May 9, 2021 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.