// Reference: https://wokwi.com/projects/318885209198035539
// Switch usage tutorial with debounce and interrupt by DiskDoctor
// credit to Michael Margolis 'Arduino Cookbook' for debounce routine
// starred comments '*' are required for using debounce on a button
// preferred method for switch is to set button to HIGH with internal pull-up resistor
// preferred method is to use interrupt for switch so it may be pressed any time
// 'Wild' prefix for non-debounced usage as comparison, not needed in program
// note: interrupts on digital pins restricted: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
// digital interrupts available...uno:2,3 mega:2,3,18,19
// notice debounced button only triggers ONCE but non-debounced maybe multiple or unreliable state
// GREEN is good with debounce. Notice single message and short LED
// RED is unstable without debounce. Notice multiple messages and longer LED from multiples can lead to instability
// each button uses distinct interrupt
// internal pullup resistors used for buttons so no 5v necessary only GND
// 220 Ohm resistors used for LEDs, including pin 13 that has onboard LED but NO internal resistor
#define inputPin 2 // which input pin is connected to button *
const int debounceDelay = 10; // milliseconds to wait until button input stable *
#define inputWildpin 3 // which input ping is connect to button NOT debounced
#define LED 12 // The pin the button-LED is connected to
#define LEDWild 13 // The pin used for second non-debounced connected LED
void setup() {
// put your setup code here, to run once
Serial.begin(115200); // initializes serial monitor for troubleshooting and learning
Serial.println("Hi !");
delay(100);
pinMode(inputPin, INPUT_PULLUP); // make button pin mode input *
digitalWrite(inputPin, HIGH);
pinMode(LED, OUTPUT); // Declare the button-LED as an output
pinMode(inputWildpin, INPUT_PULLUP); // make second button pin mode input
digitalWrite(inputWildpin, HIGH);
pinMode(LEDWild, OUTPUT); // Declare the button-LED as an output- second comparison LED
attachInterrupt(digitalPinToInterrupt(inputWildpin), buttonPushed2, LOW); // assign interrupt to button, procedure to be run and set state to LOW when pushed
attachInterrupt(digitalPinToInterrupt(inputPin), buttonPushed, LOW); // assign interrupt to button, procedure to be run and set state to LOW when pushed *
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("[loop] while waiting for button"); // normal program goes here
delay(1000); // pause to read serial monitor output
}
void buttonPushed() { // detect and debounce button push using assigned interrupt *
if (debounce(inputPin)) { // calls debounce procedure *
Serial.println("Debounce Button Pushed"); // shows button pushed on serial monitor
digitalWrite(LED, HIGH); // Turn the button-LED on for feedback
Serial.println(" something done when button is pushed"); // normal program code for action when button pressed
Serial.println(""); // blank line for neatness
delay(1000); // delay to read serial monitor and see LED
digitalWrite(LED, LOW); // Turn the button-LED back off
}
}
void buttonPushed2() { // detect second button push using assigned interrupt
Serial.print('x');delay(50);
if (digitalRead(inputPin)) { // does NOT call debounce procedure
Serial.println("@@ Non-debounced Button Pushed @@"); // shows button pushed on serial monitor
digitalWrite(LEDWild, HIGH); // Turn the button-LED on for feedback
Serial.println(" something done when non-debounced button is pushed"); // normal program code for action when button pressed
Serial.println(""); // blank line for neatness
delay(1000); // delay to read serial monitor and see LED
digitalWrite(LEDWild, LOW); // Turn the button-LED back off
}
}
// ***************************************
// ** Debounce pin **
// ** Entire procedure required **
// ** outside of setup or loop **
// ** usually at end **
// ***************************************
// debounce returns true if the switch in the given pin is closed and stable
boolean debounce(int pin)
{
boolean state;
boolean previousState;
previousState = digitalRead(pin); // store switch state
for (int counter = 0; counter < debounceDelay; counter++)
{
delay(1); // wait for 1 millisecond
state = digitalRead(pin); // read the pin
if ( state != previousState)
{
counter = 0; // reset the counter if the state changes
previousState = state; // and save the current state
}
}
// here when the switch state has been stable longer than the debounce period
return state;
}