#include <Arduino.h>
#include <FunctionalInterrupt.h>
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define PRJ_NAME "interrupts Buttons" // Project Name
#define PRINT_DASHED_LINES printf("\r-------------------------------------------------------\n\r");
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifdef LED_BUILTIN
#define MY_LED LED_BUILTIN // LED_BUILTIN -> On Board Led GPIO pin 2 (D2)
#else
#define MY_LED 2 // On Board Led GPIO pin 2 (D2)
#endif
#define LED_ON HIGH
#define LED_OFF LOW
#define BUTTON_1 14
#define BUTTON_2 12
uint8_t CurrentBtn;
volatile bool FlagChangePinState;
volatile bool FlagLongPress;
// ==================================================
/////////////////////////////////////////////////////////////
class Button {
public:
Button(uint8_t reqPin) : PIN(reqPin) {
pinMode(PIN, INPUT_PULLUP);
};
void begin() {
// LOW -> to trigger the interrupt whenever the pin is low,
// CHANGE -> to trigger the interrupt whenever the pin changes value
// RISING -> to trigger when the pin goes from low to high,
// FALLING -> for when the pin goes from high to low.
// HIGH -> to trigger the interrupt whenever the pin is high.
attachInterrupt(PIN, std::bind(&Button::isr, this), FALLING );//
Serial.printf("-> Started button interrupt on pin %u -\n", PIN);
}
~Button() {
detachInterrupt(PIN);
}
void ARDUINO_ISR_ATTR isr() {
PressStartTime = millis();
pressed = true;
}
void checkPressed() {
if ( pressed ) {
if (millis() - PressStartTime < DEBOUNCE_DELAY_MS) {
return; // Ignore this interrupt due to bouncing
}
bool currentState = digitalRead(PIN);
if (currentState && LongPressTriggered) {
LongPressTriggered = false;
PressStartTime = millis();
pressed = false;
return;
}
CurrentBtn = PIN;
if (currentState == LOW && (millis() - PressStartTime > 1000)) {
// numberKeyPresses = numberKeyPresses + 1;
// Serial.printf("LONG PRESS on pin: %u - Has been pressed: %lu times\n", CurrentBtn, numberKeyPresses);
FlagLongPress = true;
LongPressTriggered = true;
pressed = false;
return;
}
if (currentState == HIGH && LongPressTriggered == false) {
// numberKeyPresses = numberKeyPresses + 1;
// Serial.printf("CLICK on pin : %u - Has been pressed: %lu times\n", CurrentBtn, numberKeyPresses);
FlagChangePinState = true;
pressed = false;
}
//++++++++++++++++++++++++++++++++
}
}
private:
const uint8_t PIN;
// volatile uint32_t numberKeyPresses;
volatile bool pressed;
volatile bool LongPressTriggered;
volatile unsigned long PressStartTime = 0;
const uint16_t DEBOUNCE_DELAY_MS = 90; // 50ms debounce delay
};
/////////////////////////////////////////////////////////////
Button button1(BUTTON_1);
Button button2(BUTTON_2);
/////////////////////////////////////////////////////////////
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#define VERSION "alpha.0.1" // Project version
// 77777777777777777777777777777777777777777777777777777777
#define __FILENAME_NOEXT__ ({ \
const char* file = __FILE__; \
const char* slash = strrchr(file, '/'); \
if (!slash) slash = strrchr(file, '\\'); \
const char* name = slash ? slash + 1 : file; \
static char buf[64]; \
size_t len = 0; \
while (name[len] && name[len] != '.' && len < sizeof(buf) - 1) { \
buf[len] = name[len]; \
len++; \
} \
buf[len] = '\0'; \
buf; \
})
// 88888888888888888888888888888888888888888888888888888888
#include <string.h>
#define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ---------------------------------------------------------
// setup
// ---------------------------------------------------------
void setup() {
Serial.begin(115200);
delay(10); //
printf("\r\n--------------- Booting ESP ---------------------------\r\n");
printf("Arduino IDE : %d.%d.%d\r\n", ARDUINO / 10000, ARDUINO % 10000 / 100, ARDUINO % 100 / 10 ? ARDUINO % 100 : ARDUINO % 10);
printf("On Board : %s \r\n", ARDUINO_BOARD);
printf("Starting project : %s \r\n", PRJ_NAME);
printf("Author : Kernel Panic \r\n");
printf("Project Date : %s\r\n", (__DATE__ " - " __TIME__));
PRINT_DASHED_LINES;
button1.begin();
button2.begin();
pinMode(MY_LED, OUTPUT);
digitalWrite(MY_LED, LED_ON);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 7777777777777777777777777777777777777
printf("Sketch Name: %s\n", __FILENAME_NOEXT__);
printf("Build : %s | %s\n", __DATE__, __TIME__);
// 88888888888888888888888888888888888
printf(" Project : %s\n", __FILENAME__);
printf(" Version : %s\n", VERSION);
printf(" Build : %s | %s\n", __DATE__, __TIME__);
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
// ---------------------------------------------------------
// loop
// ---------------------------------------------------------
void loop() {
static int MyMode;
static int Number;
button1.checkPressed();
yield();
button2.checkPressed();
if (FlagChangePinState) {
FlagChangePinState = false;
// Serial.printf("\t Click => pin: %d \n", CurrentBtn);
// PRINT_DASHED_LINES;
// hardware switch
switch (CurrentBtn) {
case BUTTON_1:
MyMode = MyMode + 1;
// MyMode = constrain(MyMode, 0, 8);
MyMode = MyMode % 4;
Serial.printf("\t MyMode: %d \n", MyMode);
break;
case BUTTON_2:
MyMode = MyMode - 1;
MyMode = constrain(MyMode, 0, 8);
Serial.printf("\t MyMode: %d \n", MyMode);
break;
}
}
if (FlagLongPress) {
FlagLongPress = false;
// Serial.printf("\t Long Press => pin: %d \n", CurrentBtn);
// PRINT_DASHED_LINES;
// hardware switch
switch (CurrentBtn) {
case BUTTON_1:
Number = Number + 1;
Number = Number % 4;
Serial.printf("\t Number: %d \n", Number);
break;
case BUTTON_2:
Number = Number - 1;
Number = Number % 4;
Serial.printf("\t Number: %d \n", Number);
break;
}
}
yield();
}
/*********************************
END of this file
**********************************/