Skip to content

Instantly share code, notes, and snippets.

@pbrdmn
Last active December 16, 2022 09:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pbrdmn/ad6a53a064057658a2a4f19d895c0077 to your computer and use it in GitHub Desktop.
Save pbrdmn/ad6a53a064057658a2a4f19d895c0077 to your computer and use it in GitHub Desktop.
Hex Banana - Demonstrating tap/hold behaviour with on/off debouncing.
/*
Hex Banana
Demonstrating tap/hold behaviour with on/off debouncing.
*/
#include "Keyboard.h"
#define DEBOUNCE_TIME 50
#define HOLD_TIME 300
#define TIMEOUT 2000
#define NUM_KEYS 8
int pins[] = { 7, 8, 9, 10, 16, 14, 15, 18, };
char taps[] = { '1', '2', '3', '4', '5', '6', '7', '8' };
char holds[] = { '9', 'a', 'b', 'c', 'd', 'e', 'f', '0' };
bool prevVal[] = { LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW };
int timePressed[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
int now = 0;
boolean readSwitch(int i) {
// return quickly if debouncing
if (timePressed[i] + DEBOUNCE_TIME > now) return prevVal[i];
// read new button value
bool val = digitalRead(pins[i]);
// if state change
if (val != prevVal[i]) {
if (val == LOW) {
// record when press started
timePressed[i] = now;
} else {
// calculate press duration
int duration = now - timePressed[i];
// handle button press for duration
if (duration < DEBOUNCE_TIME) {
// ignore noise
} else if (duration < HOLD_TIME) {
// handle tap
Keyboard.write(taps[i]);
} else if (duration < TIMEOUT) {
// handle hold
Keyboard.write(holds[i]);
} else {
// held too long
}
}
prevVal[i] = val;
}
// Clock Rollover - millis rolls over every 49 days or so
if (timePressed[i] > now) {
timePressed[i] = 0;
}
// Return pin val
return prevVal[i];
}
void setup() {
for (int i = 0; i < NUM_KEYS; i++) {
pinMode(pins[i], INPUT_PULLUP);
}
Keyboard.begin();
}
void loop() {
now = millis();
for (int i = 0; i < NUM_KEYS; i++) {
readSwitch(i);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment