Car wiper script, intermittent wipers, failing to stop (SOLVED!)

Hi,

I am trying to write some code for the windscreen wipers. This is my attempt at writing out in English the logic.

If the ‘wp’ (windscreen wiper on button) button is pressed, then the sequence begins, it does a pulse of 1.5 seconds to set the wipers going, (The wipers have a mechanical/electrical latching mechanism in the motor which mean that will complete one wipe) then there is a pause, this duration is set by mapping the potentiometer to vary from something like 0.6 seconds though 10 seconds. (I will change these to more realistic times later). When the wp button is down, wiping should commence. When the wp button is released I want the final wipe to happen, i.e. for the remainder of the on wipe 1.5 second duration to complete (This is where my issue is), then for the sequence of events to stop when it’s in the pause part of the sequence. This is so that there is never a shorter than 1.5 second on pulse sent to the wipers. This would cause them to do a part wipe and stop on the windscreen, or if the wp buttons is released during the wipe period, then the wiping becomes constant and does not go off at all.

Thanks for any help you can give me.

//OUTPUTS:************************
int wip = 41; //Windscreen Wiper Output

//INPUTS*************************

int wp = 7;


//Constants***************************

const unsigned int wipOnTime = 1500; //just enough to make a single wipe occur??

//Variables*******************************

int unsigned long wipOffValue;
int unsigned long potPin = A1; //Added
int unsigned long potValue;
unsigned long WiperPreviousMillis=0;

int interval = wipOnTime;
int wipState = HIGH;
int wpVal = HIGH;

void setup() {
  
  pinMode(wp, INPUT_PULLUP);
  pinMode(wip, OUTPUT);
  pinMode(potPin, INPUT);
}

void loop() {
  
     digitalWrite(wip, wipState);   //sets the output to the windscreen wipers HIGH and thus off.
     int wpVal = digitalRead(wp);   //Reads the wiper switch and writes to a variable (not convinced this is required)
  potValue = analogRead(potPin);    // read the value from the potenitometer
  wipOffValue = map(potValue, 0, 1023, 500, 10000);
    unsigned long currentMillis = millis();
      if (wpVal == LOW && (unsigned long)(currentMillis - WiperPreviousMillis) >= interval) {
      if (wipState) {
      interval = wipOnTime;
    } else {
      interval = wipOffValue;
    }
    wipState = !(wipState);
    WiperPreviousMillis = currentMillis;
    } 
//    if (wpVal == HIGH) {
//     if (wipState) {
//     wipState = HIGH;
//     digitalWrite(wip, wipState);
//  }
//  }
}

Thanks again,

Brendan

I have realised that the functionality that i am trying to re-create is that of a delay for the period that the 1.5 seconds of ON time is happening, such that the code does not re-check the switch during that time, it only goes back and checks whether the wp switch, (not momentary button) is made or not when it's in the OFF period. I am adding other parts to this code so that the Arduino can control other things, not just the wipers, so i cannot use the delay function. I hope this helps make my statement clearer.

Just send a pulse long enough to get the mechanism off the "park" switch, 300mS should be enough ?), and don't send another 'til the wiper has time to get back to park (2000 mS?) so minimum time between pulses would be 2 seconds.

I don't think I explained myself very well. That aspect of the code works fine.

If during that (the one that turns on the wipers for 1.5 seconds) pulse the on/off switch is turned off, then the code leaves the state of the output in it's current state. I wish to reset the state, but only once the wiper has finished receiving it's 1.5 second long pulse. I can't seem to get my head around how to reset the code, but only once it's done... Thanks for your reply.

Here is another way of wording my question:

I think that perhaps what i need is an if statement which says, if the button state has changed AND the wiper state has also changed from last time and is now in the delay/stopped/resting state, when this is true, now pass the writeDigital command to turn the wipers off.

I can’t seem to find what variables I have to use to do this. I feel like this should be so simple, but clearly I’m not that bright enough to work out this simple thing!!! lol

And the solution to my issue:

//OUTPUTS:************************
int wip = 41; //Windscreen Wiper Output
//INPUTS*************************
int wp = 7;
//Constants***************************
const unsigned int wipOnTime = 1500; //just enough to make a single wipe occur??
//Variables*******************************
int unsigned long wipOffValue;
int unsigned long potPin = A1; //Added
int unsigned long potValue;
unsigned long WiperPreviousMillis=0;
int interval = wipOnTime;
int wipState = HIGH;
int wpVal = HIGH;

void setup() {
  
  pinMode(wp, INPUT_PULLUP);
  pinMode(wip, OUTPUT);
  pinMode(potPin, INPUT);
}

void loop() {

[color=red]  int wpVal;
if (wipState == HIGH) {
 wpVal = digitalRead(wp);   //Reads the wiper switch and writes to a variable 
} else {
  wpVal = LOW;
}[/color]
   digitalWrite(wip, wipState);   //sets the output to the windscreen wipers HIGH and thus off.
  potValue = analogRead(potPin);    // read the value from the potenitometer
  wipOffValue = map(potValue, 0, 1023, 500, 5000);
    unsigned long currentMillis = millis();
      if (wpVal == LOW && (unsigned long)(currentMillis - WiperPreviousMillis) >= interval) {
      if (wipState) {
      interval = wipOnTime;
    } else {
      interval = wipOffValue;
    }
    wipState = !(wipState);
    WiperPreviousMillis = currentMillis;
    }
}