Interrupting a delay with a pushbutton

So, here's my problem (i'm a bit of a noob with arduino).

I'm making a timer/switchbox for an outdoor fountain, with a momentary backlit pushbutton, wich if pressed for less than 2 seconds, will turn the fountain on for 30 minutes.
If you'd press the same button (when the fountain is off) for longer than 2 seconds, the fountain will work for 4 hours.

const int ledPin0 = 4;
const int solidState = 13;
int pompaan = 0;

//================

unsigned long keyPrevMillis = 0;
const unsigned long keySampleIntervalMs = 25;
byte longKeyPressCountMax = 80;    // 160 * 25 = 2000 ms = 2 seconds
byte longKeyPressCount = 0;
byte prevKeyState = HIGH;         // button is active HIGH
const byte keyPin = 6;            // button is connected to pin 6 and GND



//=================

void setup() {
 
  pinMode(ledPin0, OUTPUT);
  pinMode(solidState, OUTPUT);
  pinMode(keyPin, INPUT);
  digitalWrite(keyPin, HIGH);
}


//=================

// called when key goes from pressed to not pressed
void keyRelease() {
    
    if (longKeyPressCount >= longKeyPressCountMax) {
        longKeyPress();
    }
    else {
        shortKeyPress();
    }
}



// called when button is kept pressed for less than 2 seconds
void shortKeyPress() {
   pompaan=1;
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   
   digitalWrite(solidState, HIGH);
   delay(11800000);
   digitalWrite(solidState, LOW);
}


// called when button is kept pressed for more than 2 seconds
void longKeyPress() {
    pompaan=1;
    digitalWrite(ledPin0, HIGH);
    delay(4000);
    digitalWrite(ledPin0, LOW);
    digitalWrite(solidState, HIGH);
    delay(14400000);
    digitalWrite(solidState, LOW);    
     
}



// called when key goes from not pressed to pressed
void keyPress() {
    longKeyPressCount = 0;
    
}




   


void loop() {
    // key management section
    if (millis() - keyPrevMillis >= keySampleIntervalMs) {
        keyPrevMillis = millis();
        
        byte currKeyState = digitalRead(keyPin);
        
        if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
            keyPress();
        }
        else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
            keyRelease();
        }
        else if (currKeyState == LOW) {
            longKeyPressCount++;
        }
        
        prevKeyState = currKeyState;
    }

}

This part works.

Now, i want to make it when you'd press the button for longer than 2 seconds while the fountain is on, the fountain gets turned off, so i added

void resetPomp(){
    if((pompaan==1)&&(longKeyPressCount >= longKeyPressCountMax)) {
        digitalWrite(solidState, LOW);
    }

But, when i press the button for >2 seconds while the pump is on, nothing happens.
I have no idea why, tried some things but nothing seems to work.

Any idea what might be the solution to this problem ? Any help would be much appreciated :slight_smile:

Hi ultrakiller

    digitalWrite(solidState, HIGH);
    delay(14400000);
    digitalWrite(solidState, LOW);

You keep the fountain turned on for 4 hours using delay(). Program execution blocks on this statement until the period is finished; no other processing can happen during that time.

You will need to modify your code to extend your use of the "blink without delay" concept and millis() to control the fountain off time, so that you can detect the switch.

Regards

Ray

Allright, didn't know a delay inside a void ( :sweat_smile: ) would halt any other actions inside the whole program..
Will look into the blink without delay and try that.

thanks!

As told before, you have to use millis(). Check some examples to get used to the function. After you get used to it you won't need delay functioj anymore.

Yes, look at the Blink Without Delay example sketch and the extended demo in the first post in this Thread.

While delay() is running the Arduino can't attend to anything else.

...R

Ok so, i kind of get the idea of the millis() , alltough it still doesn't work and now even the pump won't turn on after pressing the button.

const int ledPin0 = 4;
const int solidState = 13;

unsigned long Present =0;
unsigned long Starttimer =0;
unsigned long Endtimer =0;

unsigned long Starttimer1 =0;
unsigned long Endtimer1 =0;
unsigned long Present1 =0;
int pompaan;


//================

unsigned long keyPrevMillis = 0;
const unsigned long keySampleIntervalMs = 25;
byte longKeyPressCountMax = 80;    // 160 * 25 = 2000 ms = 2 seconds
byte longKeyPressCount = 0;
byte prevKeyState = HIGH;         // button is active HIGH
const byte keyPin = 6;            // button is connected to pin 6 and GND



//=================

void setup() {
 
  pinMode(ledPin0, OUTPUT);
  pinMode(solidState, OUTPUT);
  pinMode(keyPin, INPUT);
  digitalWrite(keyPin, HIGH);
  
  unsigned long Starttimer =0;
  unsigned long Endtimer;
  
  unsigned long Starttimer1 =0;
  unsigned long Endtimer1;

  
}

void loop() {
    // key management section
    
    
    if (millis() - keyPrevMillis >= keySampleIntervalMs) {
        keyPrevMillis = millis();
        
        
        byte currKeyState = digitalRead(keyPin);
        
        if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
            keyPress();
        }
        else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
            keyRelease();
        }
        else if (currKeyState == LOW) {
            longKeyPressCount++;
        }
        
        prevKeyState = currKeyState;
    }
    

}


//=================

// called when key goes from pressed to not pressed
void keyRelease() {
    
    if (longKeyPressCount >= longKeyPressCountMax) {
        longKeyPress();
    }
    else {
        shortKeyPress();
    }
}



// called when button is kept pressed for less than 2 seconds
void shortKeyPress() {
   
   
   
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   delay(100);
   digitalWrite(ledPin0 ,HIGH);
   delay(100);
   digitalWrite(ledPin0 ,LOW);
   
   //===
   Present=millis();
   Starttimer=millis();
   Endtimer=Starttimer + 11800000;

   while((Endtimer > Present)&&(pompaan==1)){
   digitalWrite(solidState, HIGH);
   pompaan=1; 
   
   //===
   
}
}

// called when button is kept pressed for more than 2 seconds
void longKeyPress() {
    
    digitalWrite(ledPin0, HIGH);
    delay(4000);
    digitalWrite(ledPin0, LOW);
    
    //========
    Present1=millis();
   Starttimer=millis();
   Endtimer1=Starttimer1 + 14400000;

   while((Endtimer1 > Present1)&&(pompaan==1)){
   digitalWrite(solidState, HIGH);
   pompaan=1; 
    
    //========
        
     
}
}



// called when key goes from not pressed to pressed
void keyPress() {
    longKeyPressCount = 0;
    
}




   


   void resetPomp(){
    if((pompaan==1)&&(longKeyPressCount >= longKeyPressCountMax)) {
        pompaan=0;
    }
  }

It's probably something stupidly simple, but i'm still learning arduino, and certainly new to the blink without delay/millis function, and i can't find the correct way to implement it...

You might find it easier to modify my demo code to run your pump rather than convert your own code to use BWoD.

It's usually much easier if you start your project using BWoD.

...R