// 3 Button Toggle by Epic Amplification
// Radio Buttons!
const int rly1 = 3; // LED pin number
const int btn1 = PB0;
const int rly2 = 4;
const int btn2 = PB1;
const int rly3 = 5;
const int btn3 = PB2;
char bstate1 = 0;
char bstate2 = 0;
char bstate3 = 0;
unsigned long bcount1 = 0; // button debounce timer. Replicate as necessary.
unsigned long bcount2 = 0;
unsigned long bcount3 = 0;
// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check
// Routines by Paul__B of Arduino Forum
boolean timeout(unsigned long *marker, unsigned long interval) {
if (millis() - *marker >= interval) {
*marker += interval; // move on ready for next interval
return true;
}
else return false;
}
// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
switch (*butnstate) { // Odd states if was pressed, >= 2 if debounce in progress
case 0: // Button up so far,
if (button == HIGH) return false; // Nothing happening!
else {
*butnstate = 2; // record that is now pressed
*marker = millis(); // note when was pressed
return false; // and move on
}
case 1: // Button down so far,
if (button == LOW) return false; // Nothing happening!
else {
*butnstate = 3; // record that is now released
*marker = millis(); // note when was released
return false; // and move on
}
case 2: // Button was up, now down.
if (button == HIGH) {
*butnstate = 0; // no, not debounced; revert the state
return false; // False alarm!
}
else {
if (millis() - *marker >= interval) {
*butnstate = 1; // jackpot! update the state
return true; // because we have the desired event!
}
else
return false; // not done yet; just move on
}
case 3: // Button was down, now up.
if (button == LOW) {
*butnstate = 1; // no, not debounced; revert the state
return false; // False alarm!
}
else {
if (millis() - *marker >= interval) {
*butnstate = 0; // Debounced; update the state
return false; // but it is not the event we want
}
else
return false; // not done yet; just move on
}
default: // Error; recover anyway
{
*butnstate = 0;
return false; // Definitely false!
}
}
}
void setup()
{
pinMode(rly1, OUTPUT);
pinMode(btn1, INPUT_PULLUP);
pinMode(rly2, OUTPUT);
pinMode(btn2, INPUT_PULLUP);
pinMode(rly3, OUTPUT);
pinMode(btn3, INPUT_PULLUP);
digitalWrite (rly1, HIGH);
digitalWrite (rly2, LOW);
digitalWrite (rly3, LOW);
}
void loop(){
// Select LED if button debounced
if (butndown(digitalRead(btn3), &bcount3, &bstate3, 2UL )) {
digitalWrite (rly1, LOW);
digitalWrite (rly2, LOW);
digitalWrite (rly3, HIGH);
}
// Select LED if button debounced
if (butndown(digitalRead(btn2), &bcount2, &bstate2, 2UL )) {
digitalWrite (rly1, LOW);
digitalWrite (rly2, HIGH);
digitalWrite (rly3, LOW);
}
// Select LED if button debounced
if (butndown(digitalRead(btn1), &bcount1, &bstate1, 2UL )) {
digitalWrite (rly1, HIGH);
digitalWrite (rly2, LOW);
digitalWrite (rly3, LOW);
}
}