In principle I think this should work (compiles, not tested.) It's a way to do it using millis().
It looks complicated but it's really not. It divides the timing up into 4 distinct states:
- initialize, which reads the switches and determines the on/off times from two tables. If the on/off times
are "invalid" - not one of your patterns -- the values are set to zero which results in no aerator operation. You can change this to whatever you'd like
- if a valid switch input is recognized, the on/off times are grabbed from the tables, the aerator turned on and the timing started
- when the on-time is done, the aerator is turned off and the off-timing starts
- when the off-time is done the aerator is turned back on and the on-timing starts again
If you change the condition of the input switches, the code should immediately turn off the aerator, wait 5-seconds and then re-init the timers and start again. If you set the switches to all-off (or one of the unrecognized patterns) the aerator will stay off.
As I said, compiles but not tested. Give it a try and see if it makes sense to you.
/* The purpose of this sketch is to control the on/off times for an aerator according to the input.
* There are 3 selections possible.
* 1 is on for 1 minute and off for 10.
* 2 is on for 1 minute and off for 7.
* 3 is on for 1 minute and off for 5.
* The LED will be illuminated while the relay is active.
*/
const int timerpin1 = 8;
const int timerpin2 = 9;
const int timerpin3 = 10;
const int relaypin = 2;
const int ledpin = 11;
int timerpinState1 = 0;
int timerpinState2 = 0;
int timerpinState3 = 0;
#define CHANGE_TIME_DELAY 5000ul //5-sec off-time before applying new settings
const unsigned long
culAeratorOnTimes[] =
{
0ul, //000 - aerator off
60000ul, //001 - on 1 minute (60000mS)
60000ul, //010 - on 1 minute (60000mS)
0ul, //011 - "not recognized"; always off
60000ul, //100 - on 1 minute (60000mS)
0ul, //101 - "not recognized"; always off
0ul, //110 - "not recognized"; always off
0ul //111 - "not recognized"; always off
};
const unsigned long
culAeratorOffTimes[] =
{
0ul, //000 - aerator off
600000ul, //001 - off 10 minutes (600000mS)
420000ul, //010 - off 7 minutes (420000mS)
0ul, //011 - "not recognized"; always off
300000ul, //100 - off 5 minutes (420000mS)
0ul, //101 - "not recognized"; always off
0ul, //110 - "not recognized"; always off
0ul //111 - "not recognized"; always off
};
void setup()
{
pinMode( timerpin1, INPUT_PULLUP );
pinMode( timerpin2, INPUT_PULLUP );
pinMode( timerpin3, INPUT_PULLUP );
pinMode( relaypin, OUTPUT );
pinMode( ledpin, OUTPUT );
}//setup
//state machine state names
#define INIT 0
#define AERATOR_ON 1
#define AERATOR_OFF 2
#define CHANGE_TIME 3
//
void loop()
{
byte
sw;
static unsigned long
timeAeratorOn,
timeAeratorOff,
timeAerator;
static byte
oldSwitches = 0,
stateAerator = INIT;
unsigned long
timeNow;
timeNow = millis();
switch( stateAerator )
{
case INIT:
sw = ReadSwitches();
timeAeratorOn = culAeratorOnTimes[sw];
timeAeratorOff = culAeratorOffTimes[sw];
//if pattern is not recognized (i.e. both on and off times are zero) we just wait in this state
//aerator will remain off
if( timeAeratorOn > 0 && timeAeratorOff > 0 )
{
//valid times...turn on the aerator and start timing its run-time
digitalWrite( relaypin, HIGH );
digitalWrite( ledpin, HIGH );
timeAerator = timeNow;
oldSwitches = sw; //save a copy of current switches so we can compare later for change
stateAerator = AERATOR_ON;
}//if
break;
case AERATOR_ON:
if( timeNow - timeAerator >= timeAeratorOn )
{
//on-time is done; turn off the aerator and time the off-time
digitalWrite( relaypin, LOW );
digitalWrite( ledpin, LOW );
timeAerator = timeNow;
stateAerator = AERATOR_OFF;
}//if
break;
case AERATOR_OFF:
if( timeNow - timeAerator >= timeAeratorOff )
{
//off-time is done; turn the aerator back on and set up to time it
digitalWrite( relaypin, HIGH );
digitalWrite( ledpin, HIGH );
timeAerator = timeNow;
stateAerator = AERATOR_ON;
}//if
break;
case CHANGE_TIME:
//wait for pause time then go back to INIT to read switches, get new times and re-start
if( timeNow - timeAerator >= CHANGE_TIME_DELAY )
stateAerator = INIT;
break;
}//switch
//each time through the loop we check to see if the switches have changed
if( ReadSwitches() != oldSwitches )
{
//if switches have changed, shut the aerator off, pause and then re-start via CHANGE_TIME state
digitalWrite( relaypin, LOW );
digitalWrite( ledpin, LOW );
timeAerator = timeNow;
stateAerator = CHANGE_TIME;
}//if
}//loop
byte ReadSwitches( void )
{
byte
switchStates;
//this will set switchStates to a value from 0 (all switches open) to 7 (all switches closed)
//this will be used as an index into the on/off tables. If a switch combo is not recognized,
//its table entry for on/off will be zero.
switchStates = (digitalRead(timerpin1) == LOW)?0x01:0x00; //if timerpin1 low, OR stateSwitches with 0x01, else 0x00
switchStates |= (digitalRead(timerpin2) == LOW)?0x02:0x00; //if timerpin1 low, OR stateSwitches with 0x02, else 0x00
switchStates |= (digitalRead(timerpin3) == LOW)?0x04:0x00; //if timerpin1 low, OR stateSwitches with 0x04, else 0x00
return switchStates;
}//ReadSwitches