// BUTTONS : 1 to 16
// reliable debounce
// buttons info : state, fronts down & up, toggle
// multiple buttons can be pressed at a time
#define DELAY_TIMER_BTN B00000001 // Button on A0
#define PROG_SEL_BTN B00000010 // Button on A1
#define START_BTN B00000100 // Button on A2
#define runEvery( n ) for ( static unsigned long lasttime; millis() - lasttime > ( unsigned long )( n ); lasttime = millis() )
unsigned long prevmillis; // for debounce period
uint8_t inputaPrevious; // previous reading of buttons
uint8_t inputaPrvState; // Button previous state
uint8_t inputaActState; // Button actual state (pressed, no pressed)
uint8_t inputaAcToggle; // Actual Toggle
uint8_t inputaActualOn; // down front
uint8_t inputaActualOf; // up front
void setup() { // pullups on pins A0,A1,A2
PORTC |= B00000111; // A3, A4, A5 as output
DDRC |= B00111000;
Serial.begin(115200); //
Serial.println(F("go ! press a button")); //
} //
void isButtonPressed() {
static unsigned int counter;
// Serial.print(counter); Serial.print(" ");
counter++;
// unsigned long now = millis(); // or use global "now"
// if (now - prevmillis < 25) return; // too soon to even look again
// prevmillis = now; // 25 ms debounce delay reached
uint8_t inputaNewInput = ~PINC & B00000111; // 0 when pressed, internal pullup on pins A0, A1, A2
// this section reacts immediatley to a new different reading
inputaActualOn = inputaNewInput & ~inputaPrevious; // calculate PRESSED transitioning bits
inputaActualOf = ~inputaNewInput & inputaPrevious;
inputaAcToggle ^= inputaActualOn; // apply TOGGLE
if (inputaActualOn & DELAY_TIMER_BTN) {Serial.print(counter); Serial.println(F(" DELAY pressed ")); }
if (inputaActualOn & PROG_SEL_BTN) {Serial.print(counter); Serial.println(F(" PROG pressed ")); }
if (inputaActualOn & START_BTN) {Serial.print(counter); Serial.println(F(" START pressed ")); }
if (inputaActualOf & DELAY_TIMER_BTN){Serial.print(counter); Serial.println(F(" released DELAY")); }
if (inputaActualOf & PROG_SEL_BTN) {Serial.print(counter); Serial.println(F(" released PROG")); }
if (inputaActualOf & START_BTN) {Serial.print(counter); Serial.println(F(" released START")); }
digitalWrite(A5, inputaAcToggle & START_BTN); // display red led toggle START/STOP
// this section below develops the idea of a stable press (same for 2 readings)
uint8_t staBits = ~(inputaNewInput ^ inputaPrevious);
inputaActState &= ~staBits; // knock out the old stable bit readings
inputaActState |= inputaNewInput & staBits; // and jam the stable readings in there
digitalWrite(A4, inputaActState & (PROG_SEL_BTN | DELAY_TIMER_BTN)); // one or both, green led ON
// and could be used with for a fussier actOn / actOff / actTog
// by basing them on stable state readings
uint8_t fussyActOn = inputaActState & ~inputaPrevious;
uint8_t fussyActOff = ~inputaActState & inputaPrevious;
if (fussyActOn & DELAY_TIMER_BTN) {Serial.print(counter); Serial.println(F(" verified fussy DELAY"));}
if (fussyActOff & DELAY_TIMER_BTN) {Serial.print(counter); Serial.println(F(" released fussy DELAY"));}
// always...
inputaPrevious = inputaNewInput; // bump along the history
inputaPrvState = inputaActState; // bump along the history
}
void loop() { //
runEvery( 25 ) { isButtonPressed(); } //
} //