#include <mechButton.h>
// 1. Define a robust class inheriting from mechButton
class CounterButton : public mechButton {
public:
// Pass the pin to the parent mechButton constructor
CounterButton(int inPin) : mechButton(inPin) {
longPressMs = 600; // Hold down for 600ms to start scrolling
repeatIntervalMs = 100; // Scroll every 100ms
isPressed = false;
longPressTriggered = false;
pressTime = 0;
lastRepeatTime = 0;
callbackAction = NULL;
}
void setActionCallback(void (*func)(void)) { callbackAction = func; }
void setLongPressDuration(unsigned long ms) { longPressMs = ms; }
void setRepeatInterval(unsigned long ms) { repeatIntervalMs = ms; }
// This is our main engine. Put this in your Arduino loop() function!
void update() {
// trueFalse() returns false when pressed (Active LOW)
bool currentlyPressed = !trueFalse();
// Detect state transition: Just pressed down
if (currentlyPressed && !isPressed) {
isPressed = true;
longPressTriggered = false;
pressTime = millis();
// Fire immediately on the very first press down
if (callbackAction) callbackAction();
}
// Detect state transition: Just released
else if (!currentlyPressed && isPressed) {
isPressed = false;
}
// Handle the continuous hold (Auto-repeat logic)
if (isPressed) {
unsigned long currentMillis = millis();
unsigned long heldDuration = currentMillis - pressTime;
if (!longPressTriggered) {
// Check if we crossed into long-press territory
if (heldDuration >= longPressMs) {
longPressTriggered = true;
lastRepeatTime = currentMillis;
if (callbackAction) callbackAction();
}
} else {
// We are actively long-pressing, trigger repeatedly based on the interval
if (currentMillis - lastRepeatTime >= repeatIntervalMs) {
lastRepeatTime = currentMillis;
if (callbackAction) callbackAction();
}
}
}
}
private:
unsigned long longPressMs;
unsigned long repeatIntervalMs;
unsigned long pressTime;
unsigned long lastRepeatTime;
bool isPressed;
bool longPressTriggered;
void (*callbackAction)(void);
};
// 2. Setup global variables and buttons
int globalCounter = 0;
CounterButton btnUp(2); // Pin 2 increments
CounterButton btnDown(3); // Pin 3 decrements
void setup() {
Serial.begin(9600);
// Assign the callback functions
btnUp.setActionCallback(incrementCounter);
btnDown.setActionCallback(decrementCounter);
Serial.print("Initial Counter: ");
Serial.println(globalCounter);
}
void loop() {
idle(); // Required by mechButton to debounce in the background
btnUp.update(); // Handles all timing, clicks, and repeats for Up button
btnDown.update(); // Handles all timing, clicks, and repeats for Down button
}
// 3. Define the counter modification actions
void incrementCounter() {
globalCounter++;
printCounter();
}
void decrementCounter() {
globalCounter--;
printCounter();
}
void printCounter() {
Serial.print("Counter: ");
Serial.println(globalCounter);
}