/*
State change detection (edge detection)
(with debouncing, LED toggling, and active-LOW input using INPUT_PULLUP)
https://wokwi.com/projects/391482018625678337
modified from https://wokwi.com/projects/391475222059330561
Often, you don't need to know the state of a digital input all the time, but
you just need to know when the input changes from one state to another.
For example, you want to know when a button goes from OFF to ON. This is called
state change detection, or edge detection.
This example shows how to:
1) detect when a button or button changes from off to on and on to off.
2) debounce an input with millis()
3) toggle a LED based on its state
The circuit:
- pushbutton attached to pin 2 and GND
- LED attached from pin 13 to ground through 220 ohm resistor (or use the
built-in LED on most Arduino boards)
created 27 Sep 2005
modified 30 Aug 2011
by Tom Igoe
modified 04 Mar 2024 by DaveX for https://forum.arduino.cc/t/state-change-detection-edge-detection-for-pushbuttons/1231632/10
This example code is in the public domain.
Based on:
https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection/
*/
// this constant won't change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to
// Variables will change:
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
uint32_t lastChangeMillis = 0; // previous time of change for debouncing
uint32_t debounceInterval = 50;
void setup() {
// initialize the button pin as a input with an internal pullup resistor:
pinMode(buttonPin, INPUT_PULLUP);
// initialize the LED as an output:
pinMode(ledPin, OUTPUT);
// initialize serial communication:
Serial.begin(115200);
}
void loop() {
// read the pushbutton input pin:
buttonState = digitalRead(buttonPin);
uint32_t currentMillis = millis(); // save the current time
// compare the buttonState to its previous state
if (buttonState != lastButtonState ) { // the state has changed
if (currentMillis - lastChangeMillis >= debounceInterval) { // limit rate using time stamps
lastChangeMillis = currentMillis; // record this change
// Check for rising or falling edge
if (buttonState == LOW) {
// if the current state is LOW then the input is FALLING edge
Serial.print("LOW ");
toggleLed(ledPin);
} else {
// if the current state is HIGH then the input is RISING edge
Serial.print("HIGH ");
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
}
}
}
void toggleLed(byte pin){
if (digitalRead(pin) == LOW) { // toggle the LED as needed
digitalWrite(pin, HIGH);
Serial.print("on ");
} else {
digitalWrite(pin, LOW);
Serial.print("off ");
}
}