From a91ba5a9d7ced85277ad60f1dbf381192f5c5ed8 Mon Sep 17 00:00:00 2001 From: sanine Date: Thu, 19 Oct 2023 20:12:24 -0500 Subject: update --- 12key-arduino/12key-arduino.ino | 164 +++++++++------------------------------- 12key-arduino/Button.h | 123 ------------------------------ 12key-arduino/Keypad.h | 143 +++++++++++++++++++++++++++++++++++ 12key-arduino/Mode.h | 9 +++ 12key-arduino/ModeKeyboard.h | 131 ++++++++++++++++++++++++++++++++ 12key-arduino/ModeMenu.h | 13 ++++ 12key-arduino/ModeMouse.h | 81 ++++++++++++++++++++ 12key-arduino/ModeNav.h | 28 +++++++ 12key-arduino/keys | 95 +++++++++++++++++++++++ 12key-arduino/pins.h | 2 + 10 files changed, 538 insertions(+), 251 deletions(-) delete mode 100644 12key-arduino/Button.h create mode 100644 12key-arduino/Keypad.h create mode 100644 12key-arduino/Mode.h create mode 100644 12key-arduino/ModeKeyboard.h create mode 100644 12key-arduino/ModeMenu.h create mode 100644 12key-arduino/ModeMouse.h create mode 100644 12key-arduino/ModeNav.h create mode 100644 12key-arduino/keys diff --git a/12key-arduino/12key-arduino.ino b/12key-arduino/12key-arduino.ino index dc1210f..b239c17 100644 --- a/12key-arduino/12key-arduino.ino +++ b/12key-arduino/12key-arduino.ino @@ -1,120 +1,39 @@ #include -#include "pins.h" - -class Button { - protected: - unsigned int m_mask; - unsigned int m_debounceTime; - bool m_debouncing; - unsigned long m_debounceEnd; - bool m_pressed; - - void startDebounce() { - m_debouncing = true; - m_debounceEnd = millis() + m_debounceTime; - } - - public: - static unsigned int state; - Button(unsigned int index, unsigned int debounceTime=4) { - m_mask = 1 << index; - m_debounceTime = debounceTime; - m_debouncing = false; - m_pressed = false; - } - - void update(unsigned int pins) { - if (m_debouncing) { - if (millis() > m_debounceEnd) { - /* done debouncing, continue */ - m_debouncing = false; - } - else { - /* still debouncing, ignore changes */ - return; - } - } - - if ((m_mask & pins)) { - /* pressed */ - if (m_pressed) { - /* already marked */ - } - else { - /* update state */ - m_pressed = true; - state = state | m_mask; - startDebounce(); - } - } - else { - /* released */ - if (!m_pressed) { - /* already marked, ignore */ - } - else { - /* update state */ - m_pressed = false; - state = state & ~m_mask; - startDebounce(); - } - } - } +#include "Keypad.h" +#include "Mode.h" +#include "ModeMenu.h" +#include "ModeMouse.h" +#include "ModeKeyboard.h" +#include "ModeNav.h" + +Mode *modes[] = { + new ModeMenu(), + new ModeMouse(), + new ModeKeyboard(), + new ModeNav(), }; -unsigned int Button::state = 0; +Mode **Mode::modes; -Button buttons[] = { - Button(0), - Button(1), - Button(2), - Button(3), - Button(4), - Button(5), - Button(6), - Button(7), - Button(8), - Button(9), - Button(10), - Button(11), -}; +Mode *currentMode; -/* pin bitmask order: xxxx 1234 5678 9*0# */ -unsigned int ReadPins() { - byte col1 = 1 - digitalRead(COL_1); - byte col2 = 1 - digitalRead(COL_2); - byte col3 = 1 - digitalRead(COL_3); - byte row1 = 1 - digitalRead(ROW_1); - byte row2 = 1 - digitalRead(ROW_2); - byte row3 = 1 - digitalRead(ROW_3); - byte row4 = 1 - digitalRead(ROW_4); - - #define BUILD_ROW(row, c1, c2, c3) \ - ( ((row & c1) << 2) | ((row & c2) << 1) | (row & c3) ) - - byte row1_buttons = BUILD_ROW(row1, col1, col2, col3); - byte row2_buttons = BUILD_ROW(row2, col1, col2, col3); - byte row3_buttons = BUILD_ROW(row3, col1, col2, col3); - byte row4_buttons = BUILD_ROW(row4, col1, col2, col3); - - return 0 | - (row1_buttons << 9) | - (row2_buttons << 6) | - (row3_buttons << 3) | - (row4_buttons << 0); +void streamf(Stream& s, const char *fmt, ...) { + static char buf[128]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, 128, fmt, args); + va_end(args); + s.print(buf); } -void setup() { - pinMode(COL_1, INPUT_PULLUP); - pinMode(COL_2, INPUT_PULLUP); - pinMode(COL_3, INPUT_PULLUP); - - pinMode(ROW_1, INPUT_PULLUP); - pinMode(ROW_2, INPUT_PULLUP); - pinMode(ROW_3, INPUT_PULLUP); - pinMode(ROW_4, INPUT_PULLUP); +void setup() { + Mouse.begin(); + Keypad::Setup(); Serial.begin(115200); + + Mode::modes = modes; + currentMode = Mode::modes[0]; } @@ -126,26 +45,15 @@ void PrintPin(unsigned int pins, int index, const char *msg) { void loop() { - unsigned int pins = ReadPins(); - for (int i=0; i<12; i++) { - buttons[i].update(pins); - } + Keypad::Update(); + + if (Keypad::state != 0) { + Mode *next = currentMode->update(Keypad::state); + if (next != NULL) { + currentMode = next; + currentMode->reset(); + } - if (Button::state != 0) { - Serial.print("buttons: "); - PrintPin(Button::state, 11, "1"); - PrintPin(Button::state, 10, "2"); - PrintPin(Button::state, 9, "3"); - PrintPin(Button::state, 8, "4"); - PrintPin(Button::state, 7, "5"); - PrintPin(Button::state, 6, "6"); - PrintPin(Button::state, 5, "7"); - PrintPin(Button::state, 4, "8"); - PrintPin(Button::state, 3, "9"); - PrintPin(Button::state, 2, "*"); - PrintPin(Button::state, 1, "0"); - PrintPin(Button::state, 0, "#"); - Serial.println(); - Button::state = 0; + Keypad::state = 0; } } diff --git a/12key-arduino/Button.h b/12key-arduino/Button.h deleted file mode 100644 index c67086b..0000000 --- a/12key-arduino/Button.h +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include -#include "pins.h" - -class Button { - protected: - unsigned int m_mask; - unsigned int m_debounceTime; - bool m_debouncing; - unsigned long m_debounceEnd; - bool m_pressed; - - static buttons[12]; - - void startDebounce() { - m_debouncing = true; - m_debounceEnd = millis() + m_debounceTime; - } - - public: - static unsigned int state; - static void Setup() { - pinMode(COL_1, INPUT_PULLUP); - pinMode(COL_2, INPUT_PULLUP); - pinMode(COL_3, INPUT_PULLUP); - - pinMode(ROW_1, INPUT_PULLUP); - pinMode(ROW_2, INPUT_PULLUP); - pinMode(ROW_3, INPUT_PULLUP); - pinMode(ROW_4, INPUT_PULLUP); - } - - static void UpdateAll() { - byte col1 = 1 - digitalRead(COL_1); - byte col2 = 1 - digitalRead(COL_2); - byte col3 = 1 - digitalRead(COL_3); - - byte row1 = 1 - digitalRead(ROW_1); - byte row2 = 1 - digitalRead(ROW_2); - byte row3 = 1 - digitalRead(ROW_3); - byte row4 = 1 - digitalRead(ROW_4); - - #define BUILD_ROW(row, c1, c2, c3) \ - ( ((row & c1) << 2) | ((row & c2) << 1) | (row & c3) ) - - byte row1_buttons = BUILD_ROW(row1, col1, col2, col3); - byte row2_buttons = BUILD_ROW(row2, col1, col2, col3); - byte row3_buttons = BUILD_ROW(row3, col1, col2, col3); - byte row4_buttons = BUILD_ROW(row4, col1, col2, col3); - - unsigned int pins = 0 | - (row1_buttons << 9) | - (row2_buttons << 6) | - (row3_buttons << 3) | - (row4_buttons << 0); - - for (int i=0; i<12; i++) { - buttons[i].update(pins); - } - } - - Button(unsigned int index, unsigned int debounceTime=4) { - m_mask = 1 << index; - m_debounceTime = debounceTime; - m_debouncing = false; - m_pressed = false; - } - - void update(unsigned int pins) { - if (m_debouncing) { - if (millis() > m_debounceEnd) { - /* done debouncing, continue */ - m_debouncing = false; - } - else { - /* still debouncing, ignore changes */ - return; - } - } - - if ((m_mask & pins)) { - /* pressed */ - if (m_pressed) { - /* already marked */ - } - else { - /* update state */ - m_pressed = true; - state = state | m_mask; - startDebounce(); - } - } - else { - /* released */ - if (!m_pressed) { - /* already marked, ignore */ - } - else { - /* update state */ - m_pressed = false; - state = state & ~m_mask; - startDebounce(); - } - } - } -}; -unsigned int Button::state = 0; - -Button Button::buttons[12] = { - Button(0), - Button(1), - Button(2), - Button(3), - Button(4), - Button(5), - Button(6), - Button(7), - Button(8), - Button(9), - Button(10), - Button(11), -}; diff --git a/12key-arduino/Keypad.h b/12key-arduino/Keypad.h new file mode 100644 index 0000000..f056348 --- /dev/null +++ b/12key-arduino/Keypad.h @@ -0,0 +1,143 @@ +#pragma once + +#include +#include "pins.h" + + +#define DEFAULT_DEBOUNCE_TIME 25 + + +#define KEY_1 0x800 +#define KEY_2 0x400 +#define KEY_3 0x200 +#define KEY_4 0x100 +#define KEY_5 0x080 +#define KEY_6 0x040 +#define KEY_7 0x020 +#define KEY_8 0x010 +#define KEY_9 0x008 +#define KEY_STAR 0x004 +#define KEY_0 0x002 +#define KEY_HASH 0x001 + + +class Keypad { + protected: + unsigned int m_mask; + unsigned int m_debounceTime; + bool m_debouncing; + unsigned long m_debounceEnd; + bool m_pressed; + + static Keypad buttons[12]; + + void startDebounce() { + m_debouncing = true; + m_debounceEnd = millis() + m_debounceTime; + } + + public: + static unsigned int state; + static void Setup() { + pinMode(LED, OUTPUT); + + pinMode(COL_1, INPUT_PULLUP); + pinMode(COL_2, INPUT_PULLUP); + pinMode(COL_3, INPUT_PULLUP); + + pinMode(ROW_1, INPUT_PULLUP); + pinMode(ROW_2, INPUT_PULLUP); + pinMode(ROW_3, INPUT_PULLUP); + pinMode(ROW_4, INPUT_PULLUP); + } + + static void Update() { + byte col1 = 1 - digitalRead(COL_1); + byte col2 = 1 - digitalRead(COL_2); + byte col3 = 1 - digitalRead(COL_3); + + byte row1 = 1 - digitalRead(ROW_1); + byte row2 = 1 - digitalRead(ROW_2); + byte row3 = 1 - digitalRead(ROW_3); + byte row4 = 1 - digitalRead(ROW_4); + + #define BUILD_ROW(row, c1, c2, c3) \ + ( ((row & c1) << 2) | ((row & c2) << 1) | (row & c3) ) + + byte row1_buttons = BUILD_ROW(row1, col1, col2, col3); + byte row2_buttons = BUILD_ROW(row2, col1, col2, col3); + byte row3_buttons = BUILD_ROW(row3, col1, col2, col3); + byte row4_buttons = BUILD_ROW(row4, col1, col2, col3); + + unsigned int pins = 0 | + (row1_buttons << 9) | + (row2_buttons << 6) | + (row3_buttons << 3) | + (row4_buttons << 0); + + for (int i=0; i<12; i++) { + buttons[i].update(pins); + } + } + + Keypad(unsigned int index, unsigned int debounceTime=DEFAULT_DEBOUNCE_TIME) { + m_mask = 1 << index; + m_debounceTime = debounceTime; + m_debouncing = false; + m_pressed = false; + } + + void update(unsigned int pins) { + if (m_debouncing) { + if (millis() > m_debounceEnd) { + /* done debouncing, continue */ + m_debouncing = false; + } + else { + /* still debouncing, ignore changes */ + return; + } + } + + if ((m_mask & pins)) { + /* pressed */ + if (m_pressed) { + /* already marked */ + } + else { + /* update state */ + m_pressed = true; + state = state | m_mask; + startDebounce(); + } + } + else { + /* released */ + if (!m_pressed) { + /* already marked, ignore */ + } + else { + /* update state */ + m_pressed = false; + state = state & ~m_mask; + startDebounce(); + } + } + } +}; +unsigned int Keypad::state = 0; + +Keypad Keypad::buttons[12] = { + Keypad(0), + Keypad(1), + Keypad(2), + Keypad(3), + Keypad(4), + Keypad(5), + Keypad(6), + Keypad(7), + Keypad(8), + Keypad(9), + Keypad(10), + Keypad(11), +}; diff --git a/12key-arduino/Mode.h b/12key-arduino/Mode.h new file mode 100644 index 0000000..83a1224 --- /dev/null +++ b/12key-arduino/Mode.h @@ -0,0 +1,9 @@ +#pragma once + + +class Mode { + public: + static Mode **modes; + virtual Mode * update(unsigned int keys) = 0; + virtual void reset() = 0; +}; diff --git a/12key-arduino/ModeKeyboard.h b/12key-arduino/ModeKeyboard.h new file mode 100644 index 0000000..b17f3f5 --- /dev/null +++ b/12key-arduino/ModeKeyboard.h @@ -0,0 +1,131 @@ +#pragma once + +#include +#include +#include "Mode.h" + +class ModeKeyboard : public Mode { + protected: + byte code; + bool stroke2; + bool special; + + bool control_hold; + bool super_hold; + bool alt_hold; + bool shift_hold; + + bool nextReset; + + public: + ModeKeyboard() { + reset(); + } + + void reset() { + stroke2 = false; + special = false; + nextReset = false; + digitalWrite(LED, 1); + } + + Mode * update(unsigned int keys) { + digitalWrite(LED, 1); + if (keys & KEY_STAR) return Mode::modes[0]; + + if (keys & KEY_HASH) { + if (nextReset) { + /* hash was pressed twice, reset */ + reset(); + return NULL; + } + nextReset = true; + if (!special) { + special = true; + } + return NULL; + } + nextReset = false; + + if (special) { + stroke2 = false; + special = false; + handleSpecial(keys); + return NULL; + } + + if (!stroke2) { + digitalWrite(LED, 0); + code = 10 * keyToNumber(keys); + stroke2 = true; + } + else { + stroke2 = false; + code += keyToNumber(keys); + transmitCode(code); + if (control_hold) { + Keyboard.release(KEY_LEFT_CTRL); + control_hold = false; + } + if (alt_hold) { + Keyboard.release(KEY_LEFT_ALT); + alt_hold = false; + } + if (super_hold) { + Keyboard.release(KEY_LEFT_GUI); + super_hold = false; + } + if (shift_hold) { + Keyboard.release(KEY_LEFT_SHIFT); + shift_hold = false; + } + } + + return NULL; + } + + + byte keyToNumber(unsigned int keys) { + if (keys & KEY_0) return 0; + if (keys & KEY_1) return 1; + if (keys & KEY_2) return 2; + if (keys & KEY_3) return 3; + if (keys & KEY_4) return 4; + if (keys & KEY_5) return 5; + if (keys & KEY_6) return 6; + if (keys & KEY_7) return 7; + if (keys & KEY_8) return 8; + if (keys & KEY_9) return 9; + return 0; + } + + + void transmitCode(byte code) { + if (code == 99) Keyboard.write(KEY_BACKSPACE); + else if (code == 98) Keyboard.write(KEY_TAB); + else if (code == 97) Keyboard.write(KEY_ESC); + else if (code == 96) Keyboard.write(KEY_RETURN); + else if (code == 95) Keyboard.write(KEY_TAB); + else Keyboard.write(code + 32); + } + + + void handleSpecial(unsigned int keys) { + if (keys & KEY_4) { + Keyboard.press(KEY_LEFT_SHIFT); + shift_hold = true; + } + if (keys & KEY_7) { + Keyboard.press(KEY_LEFT_CTRL); + control_hold = true; + } + if (keys & KEY_8) { + Keyboard.press(KEY_LEFT_GUI); + super_hold = true; + } + if (keys & KEY_9) { + Keyboard.press(KEY_LEFT_ALT); + alt_hold = true; + } + } +}; diff --git a/12key-arduino/ModeMenu.h b/12key-arduino/ModeMenu.h new file mode 100644 index 0000000..7203b30 --- /dev/null +++ b/12key-arduino/ModeMenu.h @@ -0,0 +1,13 @@ +#include +#include "Mode.h" + + +class ModeMenu : public Mode { + void reset() {} + Mode * update(unsigned int keys) { + if (keys & KEY_1) return Mode::modes[1]; + if (keys & KEY_2) return Mode::modes[2]; + if (keys & KEY_3) return Mode::modes[3]; + return NULL; + } +}; diff --git a/12key-arduino/ModeMouse.h b/12key-arduino/ModeMouse.h new file mode 100644 index 0000000..c68a70c --- /dev/null +++ b/12key-arduino/ModeMouse.h @@ -0,0 +1,81 @@ +#pragma once + +#include +#include "Mode.h" + + +#define STEP_SIZE 3 + +#define MOVE_KEYS (KEY_2 | KEY_4 | KEY_6 | KEY_8 | KEY_3 | KEY_9) +#define CLICK_KEYS (KEY_1 | KEY_7) + + +class ModeMouse : public Mode { + public: + MouseMode() { + m_setStep = false; + m_step = 2; + } + + + void reset() {} + + + Mode * update(unsigned int keys) { + if (keys & KEY_STAR) return Mode::modes[0]; + + if (keys & KEY_HASH) { + if (!m_setStep) { + m_setStep = true; + m_step = 1; + } + else { + m_step *= 2; + } + return NULL; + } + + m_setStep = false; + + if (keys & MOVE_KEYS) + move(keys); + else if (keys & CLICK_KEYS) + click(keys); + + return NULL; + } + + + void move(unsigned int keys) { + /* movement */ + if (keys & KEY_2) { + for (int i=0; i +#include "Mode.h" + + +class ModeNav : public Mode { + public: + void reset() {} + + Mode * update(unsigned int keys) { + if (keys & KEY_STAR) return Mode::modes[0]; + + /* arrow keys */ + if (keys & KEY_2) Keyboard.write(KEY_UP_ARROW); + if (keys & KEY_4) Keyboard.write(KEY_LEFT_ARROW); + if (keys & KEY_5) Keyboard.write(KEY_DOWN_ARROW); + if (keys & KEY_6) Keyboard.write(KEY_RIGHT_ARROW); + + if (keys & KEY_7) Keyboard.write(KEY_ESC); + if (keys & KEY_8) Keyboard.write(KEY_TAB); + if (keys & KEY_9) Keyboard.write(KEY_RETURN); + + if (keys & KEY_0) Keyboard.write(KEY_BACKSPACE); + + return NULL; + } +}; diff --git a/12key-arduino/keys b/12key-arduino/keys new file mode 100644 index 0000000..ad01402 --- /dev/null +++ b/12key-arduino/keys @@ -0,0 +1,95 @@ +0 +1 ! +2 " +3 # +4 $ +5 % +6 & +7 ' +8 ( +9 ) +10 * +11 + +12 , +13 - +14 . +15 / +16 0 +17 1 +18 2 +19 3 +20 4 +21 5 +22 6 +23 7 +24 8 +25 9 +26 : +27 ; +28 < +29 = +30 > +31 ? +32 @ +33 A +34 B +35 C +36 D +37 E +38 F +39 G +40 H +41 I +42 J +43 K +44 L +45 M +46 N +47 O +48 P +49 Q +50 R +51 S +52 T +53 U +54 V +55 W +56 X +57 Y +58 Z +59 [ +60 \ +61 ] +62 ^ +63 _ +64 ` +65 a +66 b +67 c +68 d +69 e +70 f +71 g +72 h +73 i +74 j +75 k +76 l +77 m +78 n +79 o +80 p +81 q +82 r +83 s +84 t +85 u +86 v +87 w +88 x +89 y +90 z +91 { +92 | +93 } + diff --git a/12key-arduino/pins.h b/12key-arduino/pins.h index 78eb7f2..9a92f30 100644 --- a/12key-arduino/pins.h +++ b/12key-arduino/pins.h @@ -1,5 +1,7 @@ #pragma once +#define LED 17 + #define COL_1 A1 #define COL_2 A3 #define COL_3 15 -- cgit v1.2.1