Skip to content

Instantly share code, notes, and snippets.

@johannespetzold
Last active June 6, 2018 06:01
Show Gist options
  • Save johannespetzold/d80fce91a2cf7665aefa1f502f29e561 to your computer and use it in GitHub Desktop.
Save johannespetzold/d80fce91a2cf7665aefa1f502f29e561 to your computer and use it in GitHub Desktop.
#include "Keyboard.h"
// columns are outputs, rows are inputs
uint8_t colPins[] = { 15, 14, 16, 10, 3, 4 };
uint8_t rowPins[] = { 5, 6, 7, 8, 9 };
#define NUMCOLS sizeof(colPins)
#define NUMROWS sizeof(rowPins)
#define NUMKEYS (NUMCOLS * NUMROWS)
uint8_t keymap[][NUMKEYS] = {
{
KEY_ESC, 'q', 'w', 'e', 'r', 't',
KEY_TAB, 'a', 's', 'd', 'f', 'g',
0, 'z', 'x', 'c', 'v', 'b',
KEY_LEFT_GUI, ' ', KEY_DOWN_ARROW, KEY_UP_ARROW, 1, KEY_LEFT_SHIFT,
KEY_LEFT_ALT, KEY_LEFT_CTRL
},
{
KEY_ESC, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_TAB, '1', '2', '3', '4', '5',
0, 'z', 'x', 'c', 'v', 'b',
KEY_LEFT_GUI, ' ', KEY_PAGE_DOWN, KEY_PAGE_UP, 1, KEY_LEFT_SHIFT,
KEY_LEFT_ALT, KEY_LEFT_CTRL
},
};
#define NUMLAYERS (sizeof(keymap) / sizeof(keymap[0]))
void setup() {
Keyboard.begin();
Serial.begin(2000000);
// pinMode(17, OUTPUT);
for (uint8_t i = 0; i < NUMCOLS; i++) {
uint8_t pin = colPins[i];
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
}
for (uint8_t i = 0; i < NUMROWS; i++) {
uint8_t pin = rowPins[i];
pinMode(pin, INPUT_PULLUP);
}
}
uint8_t keyState[NUMKEYS];
uint8_t activeLayer;
bool keyStateValid[NUMKEYS];
uint8_t debounceTimers[NUMKEYS];
#define DEBOUNCE_TIMER_DELAY_MICROS 2000
#define DEBOUNCE_TIMER_RESOLUTION_MICROS 16
#define DEBOUNCE_TIMER_DELAY (DEBOUNCE_TIMER_DELAY_MICROS / DEBOUNCE_TIMER_RESOLUTION_MICROS)
void pressKey(uint8_t keyCode) {
if (keyCode < NUMLAYERS) {
activeLayer = keyCode;
} else {
Keyboard.press(keyCode);
}
}
void releaseKey(uint8_t keyCode) {
if (keyCode < NUMLAYERS) {
activeLayer = 0;
} else {
Keyboard.release(keyCode);
}
}
void onKeyStateChanged(uint8_t key) {
uint8_t code = keymap[activeLayer][key];
if (keyState[key] == LOW) {
pressKey(code);
} else {
releaseKey(code);
}
}
void setKeyState(uint8_t key, uint8_t state) {
uint8_t now = micros() / DEBOUNCE_TIMER_RESOLUTION_MICROS;
uint8_t expired = now - DEBOUNCE_TIMER_DELAY;
if (!keyStateValid[key]) {
keyState[key] = state;
debounceTimers[key] = expired;
keyStateValid[key] = true;
return;
}
if (int8_t(debounceTimers[key] - expired) > 0) {
return;
}
if (state == keyState[key]) {
debounceTimers[key] = expired;
return;
}
keyState[key] = state;
debounceTimers[key] = now;
onKeyStateChanged(key);
}
void scanColumn(uint8_t col) {
uint8_t colPin = colPins[col];
digitalWrite(colPin, LOW);
for (uint8_t row = 0, key = col; row < NUMROWS; row++, key += NUMCOLS) {
uint8_t rowPin = rowPins[row];
uint8_t keyState = digitalRead(rowPin);
setKeyState(key, keyState);
}
digitalWrite(colPin, HIGH);
}
void loop() {
for (uint8_t col = 0; col < NUMCOLS; col++) {
scanColumn(col);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment