sherzaad:
It seems to me using interrupt-on-change would make things so much simpler...
something like this maybe...
(compiles, NOT tested!)
/*
Momentary Rocker Position Function Pin 7:
1st click -Close Relay 1 ONLY
2nd click -Close Relay 2 ONLY
3rd click -Close Relay 1 & 2
4th click -Open Relay 1 & 2 (both lights off)
2 fast clicks -Open Relay 1 & 2 at any point in the loop (both lights off)
Latching Rocker Position Function Pin 6:
When HIGH -Close Relay 1 & 2
When LOW - Do nothing
*/
// Pin assignement WORKING FRONT LIGHTS
#define latchPin 6
#define togglePin 7
#define led1Pin 8
#define led2Pin 9
#define led3Pin 10
//timings
#define InPulse 300 //300ms
#define PulseInterval 1000 //1000ms
enum fcnMode {
OFF,
LED1,
LED2,
ALL,
NBSTATE
}; // OFF = 0 and NBSTATE=4
unsigned long previousMillis, interval, pulse;
uint8_t funcState = 0, input_7 = LOW;
// Use pcint ISR for each group (UNO)
ISR (PCINT0_vect) // handle pin change interrupt for D8 to D13 here
{
}
ISR (PCINT1_vect) // handle pin change interrupt for A0 to A5 here
{
}
ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
{
uint8_t input = digitalRead(togglePin);
if (input == LOW) {
//HIGH->LOW change. calculate interval time
interval = previousMillis - millis();
previousMillis = millis();
}
else {
//LOW->HIGH change. calculate pulse time (low instead of HIGH as using input pullups here)
pulse = previousMillis - millis();
previousMillis = millis();
}
//toggle swich was operated
if (pulse >= InPulse) {
if (interval < PulseInterval) {
//2 fast clicks - Open Relay 1 & 2 at any point in the loop (both lights off)
funcState = 0;
}
else {
//move along state machine
funcState = funcState % NBSTATE;
}
}
}
//Pin change interrupt for a pin, can be called multiple times
void pciSetup(byte pin)
{
*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}
void setup() {
//initialise serial comms
Serial.begin(115200);
// set pullups, if necessary
pinMode(latchPin, INPUT_PULLUP);
pinMode(togglePin, INPUT_PULLUP);
pinMode(led1Pin, OUTPUT);
pinMode(led2Pin, OUTPUT);
pinMode(led3Pin, OUTPUT);
//set up interrupt-on-change pins
//pciSetup(latchPin);
pciSetup(togglePin);
//initialise variable
previousMillis = millis();
}
void loop() {
Serial.print("Function : ");
Serial.println(funcState);
if (digitalRead(latchPin) == LOW) {
//LOW -Close Relay 1 & 2 (low instead of HIGH as using input pullups here)
funcState = 3;
}
//set mode
switch (funcState) {
//1st click -Close Relay 1 ONLY
case LED1:
digitalWrite(led1Pin, HIGH);
break;
//2nd click -Close Relay 2 ONLY
case LED2:
digitalWrite(led2Pin, HIGH);
break;
//3rd click -Close Relay 1 & 2
case ALL:
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, HIGH);
digitalWrite(led3Pin, HIGH);
break;
//4th click -Open Relay 1 & 2 (both lights off)
case OFF:
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, LOW);
digitalWrite(led3Pin, LOW);
break;
}
}
hope that helps....
I had no luck with this code.
Results are as follow.
Latching is firing from Pin6 when engaged. Somewhat unstable; will not fire everytime and seem to require a delay to reset.
Momentary state login at Pin 7 does not engage any relays.
See picture. Ignore the breadboard pushbutton and crimping cable colors. Ran out of colors for crimp and rocker terminal connections.

