From c7de79c4e5416fd8174e995609ad9e96143e68cc Mon Sep 17 00:00:00 2001 From: mintey Date: Sun, 28 Feb 2021 21:17:48 +0200 Subject: [PATCH] modifier keys and led indicators for em --- smol_gkos.ino | 173 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 126 insertions(+), 47 deletions(-) diff --git a/smol_gkos.ino b/smol_gkos.ino index c14c4b8..6fd3864 100644 --- a/smol_gkos.ino +++ b/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); }