Intermittent Wiper Control, Reset Interval Timer When Button Released


I'm having some trouble "resetting" the Wiper OFF interval timer when the latching switch input is removed, returning back to the start of the loop awaiting another input as such.

The Wiper OFF interval timer continues to run for the 8 seconds before it allows another wiper relay output. So if the switch input is received during this 8 second OFF interval then the Wiper Relay won't turn ON again until after it has expired. Would give the impression that the wipers weren't working within this period.

I've been looking at various methods of doing this throughout the past few weeks but with no joy. I've tried button state flags which I thought would have been the way around this, but may not have had them setup correctly.

See below code as it stands now without any Button State flags etc. I've only recently got to grips with Arduino again after a few years away from it, so there may be other ways around doing this.

Thanks in advance for any help

int WiperRelay = 10; //Windscreen Wiper Output
int WiperInt = 4;
const int wipOnTime = 1500; //Enough time to pass the Wiper Stop point
const int wipOffTime = 8000;
long WiperOnMillis = 0;  // Time stamp for when the wipers relay last went to 1(HIGH). Initially set to 0(LOW)
int interval = wipOnTime;
int WiperState = LOW;
int WiperIntSwitchVal = 0;
int previousWiperIntSwitchVal = 0;
long WiperSwitchMillis = 0;  // Time stamp for when the switch last went to 1(HIGH). Initially set to 0(LOW)

void setup() {
  pinMode(WiperInt, INPUT_PULLUP);
  pinMode(WiperRelay, OUTPUT);
void loop() {

unsigned long currentMillis = millis();  //saves the time at the start of the loop

if (WiperState == LOW) {
 WiperIntSwitchVal = digitalRead(WiperInt);   //Reads the wiper switch and writes to a variable
} else {
  WiperIntSwitchVal = LOW;

   if ((WiperIntSwitchVal == LOW) && (previousWiperIntSwitchVal == HIGH))  //compares current switch status to previous

      previousWiperIntSwitchVal = WiperIntSwitchVal;  //sets the current status as the old status in preparation for the next check
      WiperSwitchMillis = currentMillis;  //sets a time stamp at the current time

   if ((WiperIntSwitchVal == LOW) && (currentMillis - WiperOnMillis >= interval)) 
        WiperOnMillis = currentMillis;  //saves current time
      if (WiperState == LOW)
      interval = wipOnTime;
      interval = wipOffTime;
      WiperState = !(WiperState);

     digitalWrite(WiperRelay, WiperState);   //sets the output to the windscreen wipers with the state of the variable 


Why build such a device at all? I bought such a one ready to use 45 years ago and it didn't cost much.

This is part of a larger arduino project that controls numerous other things on my racing car. Made sense to add this in too since the I/O was available.

Use a button library. Here's a good one

You can go through the example code. Try using button.wasReleased();

Seems like that's exactly what you need.

I think i see a problem in your code. Do check the logic on how you accept your button input. If it is low, you read what's on the input otherwise you set it to low. That's what your code does.

What I think is wrong is that every time the button reads high, your still not storing the value high because the else part of the code is being executed. So what I believe is happening is that the value high is never being written to your variable except for a border case scenario where the press happens after you've entered the if part but are yet to read the button value.

Not sure if you really need an if else to change the WiperIntSwitchVal. You're better off just reading it in the loop.