Hi all.
My projects include: 2 leds, A and B; 2 pushbuttons: X and Y.
It starts with ledA on and led B off. When you press X it turns off ledA and lits ledB, and if you press X again it turns B off and A on. (mode on/off)
If you press once the Y pushbutton, it will change the way X controls the leds: now when X is pressed A is off and B is on, and when it's released B is off and A is on. (mode hold)
If you press Y again, X will act again as in mode on/off.
I got it working perfectly so far, till I realized I needed a way to tell the user which mode was on without having to try the button.
So I deciced to make ledA blinking while "mode hold" was active.
And here comes the problem: if I use a millis function to blink the led it's going to mess with the timing of "on/off mode" and I have to keep X pressed for 1-2 sec to make ledA and B switch.
I hope I was clear, I'll add some code to show how I handled this project.
LOOP SECTION:
/* LOOP
******************************************************************* */
void loop() {
toggleMode(); //Y pressed
FSWpressed(); //B pressed
channelCtrl(); //led control
digitalWrite(led1, ledState1);
digitalWrite(led2, ledState2);
}
and the 3 functions I've used:
/* Toggle Mode - Pushbutton Y
******************************************************************* */
void toggleMode() {
/* read the state of the switch into a local variable: */
int reading = digitalRead(toggle);
/* check to see if you just pressed the button
(i.e. the input went from LOW to HIGH), and you've waited
long enough since the last press to ignore any noise:
If the switch changed, due to noise or pressing: */
if (reading != lastToggleState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
/* whatever the reading is at, it's been there for longer
than the debounce delay, so take it as the actual current state:
if the button state has changed:*/
if (reading != toggleState) {
toggleState = reading;
// only toggle if the new button state is HIGH
if (toggleState == HIGH)
tempState = !tempState; /* change mode */ //temp state is var that stores current mode
}
}
}
/* save the reading. Next time through the loop,
it'll be the lastButtonState: */
lastToggleState = reading;
}
/* Channel Switch - Footswitch X
******************************************************************* */
void FSWpressed() {
/* read the state of the switch into a local variable: */
int reading = digitalRead(Fswitch);
/* check to see if you just pressed the button
(i.e. the input went from LOW to HIGH), and you've waited
long enough since the last press to ignore any noise:
If the switch changed, due to noise or pressing:*/
if (reading != lastSwitchState) {
// reset the debouncing timer
lastDebounceTime2 = millis();
}
if ((millis() - lastDebounceTime2) > debounceDelay2) {
/* whatever the reading is at, it's been there for longer
than the debounce delay, so take it as the actual current state:
if the button state has changed: */
if (reading != switchState) {
switchState = reading;
/* check for tempState. 0: ON-OFF mode; 1: Temp mode */
if (tempState == 0) {
if (switchState == HIGH) {
channel = !channel; /* change channel ON */ //channel stores which led should be on
}
}
if (tempState == 1) {
if (switchState == HIGH) {
channel = 1;
} else {
channel = 0;
}
}
}
/* save the reading. Next time through the loop,
it'll be the lastButtonState: */
lastSwitchState = reading;
}
}
/* Channel Switch - Control leds and relay
******************************************************************* */
void channelCtrl() {
if (tempState == ){
switch (channel) {
case 0:
ledState1 = 1;
ledState2 = 0;
break;
case 1:
ledState1 = 0;
ledState2 = 1;
break;
}
}
This way it works but if I add the blinking led like this, on/off mode stops working smooth:
void channelCtrl() {
if (tempState == 0) {
switch (channel) {
case 0:
ledState1 = 1;
ledState2 = 0;
relayState = 0;
break;
case 1:
ledState1 = 0;
ledState2 = 1;
relayState = 1;
break;
}
}
if (tempState == 1) {
switch (channel) {
case 0:
ledState2 = 0;
relayState = 0;
// ledState1 = 1;
if (millis() - prevLedOn >= 100) {
// save the last time you blinked the LED
prevLedOn = millis();
ledState1 = !ledState1; //change led state
}
break;
case 1:
ledState1 = 0;
ledState2 = 1;
break;
}
}
}
Probably there were more easy ways to have the same results, but this the one who worked smoothest for me.