Skip to content

Instantly share code, notes, and snippets.

@huytd
Created December 16, 2018 10:16
Show Gist options
  • Save huytd/8dabf762a868b86d2aa597b878e53df0 to your computer and use it in GitHub Desktop.
Save huytd/8dabf762a868b86d2aa597b878e53df0 to your computer and use it in GitHub Desktop.
/* Snacky2x2 Keyboard Firmware
By @huydotnet
You must select Keyboard from the "Tools > USB Type" menu
Change Log:
- v2: Fixes debounce problem by adding key state checking.
Reset the debounce timer when key state changed.
- v3: Snap the processing to every 1 millisecond.
- v4: Implement a different debouncing algorithm.
REGISTER_DELAY is a time before key can be registered
at each frame. REPEAT_DELAY is a time before a new frame
can be started.
*/
#include <Keyboard.h>
const byte ROWS = 2;
const byte COLS = 2;
const byte REGISTER_DELAY = 10;
const byte REPEAT_DELAY = 80;
int frameSkipCount = 0;
unsigned long lastFrame = 0;
char keys[ROWS][COLS] = {
{ 'A', 'B' },
{ 'C', 'D' }
};
byte rowPins[ROWS] = { 2, 21 };
byte colPins[COLS] = { 4, 23 };
int readKey() {
int keyCode = -1;
for (int i = 0; i < ROWS; i++) {
pinMode(rowPins[i], INPUT);
digitalWrite(rowPins[i], HIGH);
}
for (int i = 0; i < COLS; i++) {
pinMode(colPins[i], INPUT);
digitalWrite(colPins[i], HIGH);
}
for (int row = 0; row < ROWS; row++) {
pinMode(rowPins[row], OUTPUT);
digitalWrite(rowPins[row], LOW);
for (int col = 0; col < COLS; col++) {
if (!digitalRead(colPins[col])) {
keyCode = (col << 0) | (row << 1);
}
}
pinMode(rowPins[row], INPUT);
digitalWrite(rowPins[row], HIGH);
}
return keyCode;
}
void setup()
{
Serial.begin(9600);
}
void loop()
{
unsigned long timeNow = millis();
// read every 1 millisecond
if (timeNow != lastFrame) {
frameSkipCount++;
if (frameSkipCount == REGISTER_DELAY) {
// Begin process
int key = readKey();
if (key != -1) {
// if key is pressed
int c = (key >> 0) & 1;
int r = (key >> 1) & 1;
Keyboard.print(keys[r][c]);
} else {
frameSkipCount = 0;
}
}
if (frameSkipCount == REPEAT_DELAY) {
frameSkipCount = 0;
}
// record last key state and frame
lastFrame = timeNow;
}
}
@DmitryMyadzelets
Copy link

You can use INPUT_PULLUP mode as here: https://www.pjrc.com/teensy/td_digital.html.

It seems the readKey scan code returns last (by index) key pressed. What if many at once?

The encoding keyCode = (col << 0) | (row << 1); is fixed to your 4 keys configuration. Not sure if you want it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment