modifier keys and led indicators for em
This commit is contained in:
parent
f806133f9c
commit
c7de79c4e5
1 changed files with 126 additions and 47 deletions
173
smol_gkos.ino
173
smol_gkos.ino
|
@ -37,6 +37,10 @@ int button_timers[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|||
// - toggle a modifier
|
||||
enum ActionType { PrintCharacter, PressKey, ToggleModifier };
|
||||
|
||||
const char button_characters[6] = { 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
const char button_characters_shifted[6] = { 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
const char button_characters_symbol[6] = { '1', '2', '3', '4', '5', '6' };
|
||||
|
||||
/*
|
||||
backspace, space (keep those two first since they overlap with the rest )
|
||||
g, k, o, s, w, native
|
||||
|
@ -63,7 +67,29 @@ const int chord_targets[32] = {
|
|||
'o', 'p', 'q', 'r',
|
||||
's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z',
|
||||
' ', ' ', ' ', ' '
|
||||
0, 0, 0, 0
|
||||
};
|
||||
const int chord_targets_shifted[32] = {
|
||||
KEY_BACKSPACE, KEY_LEFT, KEY_LEFT, KEY_HOME,
|
||||
KEY_SPACE, KEY_RIGHT, KEY_RIGHT, KEY_END,
|
||||
'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R',
|
||||
'S', 'T', 'U', 'V',
|
||||
'W', 'X', 'Y', 'Z',
|
||||
0, 0, 0, 0
|
||||
};
|
||||
// TODO: check that all the symbols work
|
||||
// TODO: match symbols to keypresses in the keyboard layout
|
||||
const int chord_targets_symbol[32] = {
|
||||
KEY_BACKSPACE, KEY_LEFT, KEY_LEFT, KEY_HOME,
|
||||
KEY_SPACE, KEY_RIGHT, KEY_RIGHT, KEY_END,
|
||||
'0', '7', '8', '9',
|
||||
'#', '@', '½', '&',
|
||||
'+', '%', '=', '^',
|
||||
'*', '$', '€', '£',
|
||||
'(', '[', '<', '{',
|
||||
')', ']', '>', '}'
|
||||
};
|
||||
const byte chord_target_types[32] = {
|
||||
1, 1, 1, 1,
|
||||
|
@ -92,6 +118,12 @@ const int special_action_targets[22] = {
|
|||
KEY_ESC, Modifier::Control, Modifier::Alt, KEY_DELETE, KEY_INSERT,
|
||||
KEY_TAB, KEY_ENTER
|
||||
};
|
||||
const int special_action_targets_symbol[22] = {
|
||||
'_', '\`', 0, '\"', ';', '|', '~', ':', 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
const byte special_action_target_types[22] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1
|
||||
};
|
||||
|
@ -101,6 +133,14 @@ byte key_pressed_total = 0;
|
|||
bool chord_used = false;
|
||||
bool chorded_pressed = false;
|
||||
|
||||
bool mod_shift = false;
|
||||
bool mod_shift_lock = false;
|
||||
bool mod_symbol = false;
|
||||
bool mod_symbol_lock = false;
|
||||
// TODO: control and alt modifiers
|
||||
bool mod_control = false;
|
||||
bool mod_alt = false;
|
||||
|
||||
void setup() {
|
||||
pinMode(PIN_A, INPUT_PULLUP);
|
||||
pinMode(PIN_B, INPUT_PULLUP);
|
||||
|
@ -144,7 +184,10 @@ void loop() {
|
|||
if (b < 6) {
|
||||
key_pressed &= ~(1 << b);
|
||||
// gkos key was released, check if it completed a chord
|
||||
key_released(b);
|
||||
// clear temporary modifiers if a keypress was completed
|
||||
if (key_released(b))
|
||||
mod_shift = mod_symbol = mod_control = mod_alt = false;
|
||||
update_leds();
|
||||
if (key_pressed == 0) {
|
||||
key_pressed_total = 0;
|
||||
// clear flags
|
||||
|
@ -158,7 +201,10 @@ void loop() {
|
|||
}
|
||||
}
|
||||
|
||||
void key_released(byte key) {
|
||||
// returns true if a keypress was completed
|
||||
bool key_released(byte key) {
|
||||
int target = 0;
|
||||
|
||||
/*
|
||||
SPECIALS
|
||||
*/
|
||||
|
@ -175,20 +221,52 @@ void key_released(byte key) {
|
|||
if (is_special && !chord_used) {
|
||||
// only register a special keypress when all keys have been released
|
||||
if (key_pressed != 0)
|
||||
return;
|
||||
return false;
|
||||
|
||||
target = special_action_targets[special];
|
||||
if (mod_shift || mod_shift_lock || mod_symbol || mod_symbol_lock) {
|
||||
if (special_action_targets_symbol[special] != 0)
|
||||
target = special_action_targets_symbol[special];
|
||||
}
|
||||
|
||||
switch (special_action_target_types[special]) {
|
||||
case ActionType::PrintCharacter:
|
||||
Keyboard.print((char)special_action_targets[special]);
|
||||
return;
|
||||
Keyboard.print((char)target);
|
||||
return true;
|
||||
case ActionType::PressKey:
|
||||
Keyboard.press(special_action_targets[special]);
|
||||
Keyboard.release(special_action_targets[special]);
|
||||
return;
|
||||
Keyboard.press(target);
|
||||
Keyboard.release(target);
|
||||
return true;
|
||||
case ActionType::ToggleModifier:
|
||||
// TODO
|
||||
return;
|
||||
switch (target) {
|
||||
case Modifier::Shift:
|
||||
mod_symbol = mod_symbol_lock = false;
|
||||
if (mod_shift_lock) {
|
||||
mod_shift_lock = false;
|
||||
} else if (mod_shift) {
|
||||
mod_shift = false;
|
||||
mod_shift_lock = true;
|
||||
} else {
|
||||
mod_shift = true;
|
||||
}
|
||||
return false;
|
||||
case Modifier::SymbolShift:
|
||||
mod_shift = mod_shift_lock = mod_symbol_lock = false;
|
||||
mod_symbol = !mod_symbol;
|
||||
return false;
|
||||
case Modifier::Keyset:
|
||||
mod_shift = mod_shift_lock = mod_symbol = false;
|
||||
mod_symbol_lock = !mod_symbol_lock;
|
||||
return false;
|
||||
case Modifier::Control:
|
||||
mod_control = !mod_control;
|
||||
return false;
|
||||
case Modifier::Alt:
|
||||
mod_alt = !mod_alt;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -209,63 +287,64 @@ void key_released(byte key) {
|
|||
// chord on its own
|
||||
if (!chorded_pressed && key_pressed == 0 &&
|
||||
key_pressed_total == chords[chord]) {
|
||||
target = chord_targets[chord * 4];
|
||||
if (mod_shift || mod_shift_lock)
|
||||
target = chord_targets_shifted[chord * 4];
|
||||
else if (mod_symbol || mod_symbol_lock)
|
||||
target = chord_targets_symbol[chord * 4];
|
||||
|
||||
switch (chord_target_types[chord * 4]) {
|
||||
case ActionType::PrintCharacter:
|
||||
Keyboard.print((char)chord_targets[chord * 4]);
|
||||
return;
|
||||
Keyboard.print((char)target);
|
||||
return true;
|
||||
case ActionType::PressKey:
|
||||
Keyboard.press(chord_targets[chord * 4]);
|
||||
Keyboard.release(chord_targets[chord * 4]);
|
||||
return;
|
||||
Keyboard.press(target);
|
||||
Keyboard.release(target);
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// keys that can be chorded with
|
||||
for (byte b = 0; b < 3; b++) {
|
||||
if (key == chord_buttons[chord * 3 + b]) {
|
||||
Serial.print(chord);
|
||||
Serial.println(" pressed");
|
||||
target = chord_targets[chord * 4 + 1 + b];
|
||||
if (mod_shift || mod_shift_lock)
|
||||
target = chord_targets_shifted[chord * 4 + 1 + b];
|
||||
else if (mod_symbol || mod_symbol_lock)
|
||||
target = chord_targets_symbol[chord * 4 + 1 + b];
|
||||
|
||||
// erase key from total so you can hold the chord down for
|
||||
// multiple chorded keypresses
|
||||
key_pressed_total &= ~(1 << key);
|
||||
chorded_pressed = true;
|
||||
switch (chord_target_types[chord * 4 + 1 + b]) {
|
||||
case ActionType::PrintCharacter:
|
||||
Keyboard.print((char)chord_targets[chord * 4 + 1 + b]);
|
||||
return;
|
||||
Keyboard.print((char)target);
|
||||
return true;
|
||||
case ActionType::PressKey:
|
||||
Keyboard.press(chord_targets[chord * 4 + 1 + b]);
|
||||
Keyboard.release(chord_targets[chord * 4 + 1 + b]);
|
||||
return;
|
||||
Keyboard.press(target);
|
||||
Keyboard.release(target);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
REGULAR KEYS
|
||||
*/
|
||||
switch (key) {
|
||||
case Button::A:
|
||||
Keyboard.print('a');
|
||||
return;
|
||||
case Button::B:
|
||||
Keyboard.print('b');
|
||||
return;
|
||||
case Button::C:
|
||||
Keyboard.print('c');
|
||||
return;
|
||||
case Button::D:
|
||||
Keyboard.print('d');
|
||||
return;
|
||||
case Button::E:
|
||||
Keyboard.print('e');
|
||||
return;
|
||||
case Button::F:
|
||||
Keyboard.print('f');
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
if (mod_shift || mod_shift_lock)
|
||||
Keyboard.print(button_characters_shifted[key]);
|
||||
else if (mod_symbol || mod_symbol_lock)
|
||||
Keyboard.print(button_characters_symbol[key]);
|
||||
else
|
||||
Keyboard.print(button_characters[key]);
|
||||
return true;
|
||||
}
|
||||
|
||||
void update_leds() {
|
||||
digitalWrite(PIN_LED1, mod_shift || mod_shift_lock);
|
||||
digitalWrite(PIN_LED2, mod_symbol || mod_symbol_lock);
|
||||
digitalWrite(PIN_LED3, mod_control || mod_alt);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue