Created
March 27, 2017 21:20
-
-
Save rehael/a9ea6fc4653f07e82466504a261e5aae to your computer and use it in GitHub Desktop.
ProTrinketKeyboard in CM switch tester body
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ProTrinketKeyboard.h> // Ensure the library is installed | |
// Switches are connected from ground to these defined pins | |
const int P_CTRL = 4; | |
const int P_SHFT = 8; | |
const int P_UP = 12; | |
const int P_DN = 10; | |
const int P_LT = 9; | |
const int P_RT = 11; | |
// how many millis to wait before key repeats | |
const unsigned long keydelay1 = 1000; | |
// how many millis between key repeats | |
const unsigned long keydelay2 = 100; | |
// keystroke stabilization time - because switches chatter | |
const unsigned long hysteresis = 50; | |
// bitmap keystate | |
uint8_t keysstate = 0; | |
uint8_t prevstate = 0; | |
// repeater flag | |
uint8_t rep = 0; | |
// keycodes array, map for USB report_buffer | |
uint8_t keys[6] = {0,0,0,0,0,0}; | |
// array size pointer | |
uint8_t ksz = 0; | |
// mods flag | |
uint8_t mods = 0; | |
// time counters | |
unsigned long pmil; // previous millis() | |
unsigned long cmil; // current millis() | |
// bitmask flags | |
enum keys { | |
KRT = 1, KLT = 2, KDN = 4, KUP = 8, KSH = 16, KCT = 32 | |
}; | |
void setup() | |
{ | |
// Declare button pins as inputs | |
pinMode(P_CTRL, INPUT); | |
pinMode(P_SHFT, INPUT); | |
pinMode(P_UP, INPUT); | |
pinMode(P_DN, INPUT); | |
pinMode(P_LT, INPUT); | |
pinMode(P_RT, INPUT); | |
// setting input pins to high means turning on internal pull-up resistors | |
digitalWrite(P_CTRL, HIGH); | |
digitalWrite(P_SHFT, HIGH); | |
digitalWrite(P_UP, HIGH); | |
digitalWrite(P_DN, HIGH); | |
digitalWrite(P_LT, HIGH); | |
digitalWrite(P_RT, HIGH); | |
// remember, the buttons are active-low, they read LOW when they are not pressed | |
// initialize states | |
pmil = cmil = 0; | |
rep = prevstate = keysstate = mods = 0; | |
ksz = 0; | |
keys[0] = 0; | |
keys[1] = 0; | |
keys[2] = 0; | |
keys[3] = 0; | |
keys[4] = 0; | |
keys[5] = 0; | |
// start USB stuff | |
TrinketKeyboard.begin(); | |
} | |
// get bitmask of active keys | |
uint8_t getKeysState() { | |
return ( | |
((digitalRead(P_CTRL) == LOW) ? 0xff & KCT : 0) | | |
((digitalRead(P_SHFT) == LOW) ? 0xff & KSH : 0) | | |
((digitalRead(P_UP) == LOW) ? 0xff & KUP : 0) | | |
((digitalRead(P_DN) == LOW) ? 0xff & KDN : 0) | | |
((digitalRead(P_LT) == LOW) ? 0xff & KLT : 0) | | |
((digitalRead(P_RT) == LOW) ? 0xff & KRT : 0) | |
); | |
} | |
void sendKeys() { | |
/* | |
mods acting as mods | |
#define KEYCODE_MOD_RIGHT_CONTROL 0x10 | |
#define KEYCODE_MOD_RIGHT_SHIFT 0x20 | |
mods acting as keys | |
#define KEYCODE_RIGHT_CONTROL 0xE4 | |
#define KEYCODE_RIGHT_SHIFT 0xE5 | |
#define KEYCODE_ARROW_RIGHT 0x4F | |
#define KEYCODE_ARROW_LEFT 0x50 | |
#define KEYCODE_ARROW_DOWN 0x51 | |
#define KEYCODE_ARROW_UP 0x52 | |
*/ | |
mods = (keysstate & KCT ? KEYCODE_MOD_RIGHT_CONTROL : 0) | | |
(keysstate & KSH ? KEYCODE_MOD_RIGHT_SHIFT : 0); | |
ksz = 0; | |
if (keysstate & KUP) keys[ksz++] = KEYCODE_ARROW_UP; | |
if (keysstate & KDN) keys[ksz++] = KEYCODE_ARROW_DOWN; | |
if (keysstate & KLT) keys[ksz++] = KEYCODE_ARROW_LEFT; | |
if (keysstate & KRT) keys[ksz++] = KEYCODE_ARROW_RIGHT; | |
// workaround for a library bug not resetting the report_buffer array | |
for (int i = ksz; i < 6; i++) keys[i] = 0; | |
// FIXME: if no keys, only mods, rewrite mods to key push | |
// but first check if it's really needed, as DIView shows the presses just ok. | |
TrinketKeyboard.pressKeys(mods, keys, 6); | |
} | |
void loop() | |
{ | |
TrinketKeyboard.poll(); | |
// the poll function must be called at least once every 10 ms or cause a keystroke; | |
// if it is not, then the computer may think that the device | |
// has stopped working, and give errors | |
keysstate = getKeysState(); | |
cmil = millis(); | |
if ((keysstate != prevstate) && (cmil - pmil >= hysteresis)) { | |
sendKeys(); | |
pmil = cmil; | |
rep = 0; | |
prevstate = keysstate; | |
} | |
else { | |
switch (rep) { | |
case 1: | |
if (cmil - pmil >= keydelay1) { | |
rep = 2; | |
sendKeys(); | |
} | |
break; | |
case 2: | |
if (cmil - pmil >= keydelay2) { | |
pmil = cmil; | |
sendKeys(); | |
} | |
break; | |
default: // rep = 0 here | |
rep = 1; | |
pmil = cmil; | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment