diff options
author | Thomas Bracht Laumann Jespersen <t@laumann.xyz> | 2021-01-31 22:30:32 +0100 |
---|---|---|
committer | Thomas Bracht Laumann Jespersen <t@laumann.xyz> | 2021-01-31 22:30:32 +0100 |
commit | 535a6ec36adf90a9d8d77d0fa51be00c3e052e32 (patch) | |
tree | 13ca0c621176190f02ceb05bbbce74777f2e3b65 | |
parent | bf31daa4e2c234e5f9473cf0b4cb474dc6c22fd6 (diff) |
Thanks to some electrical engineering assistance from a good friend, the
2×2 button keyboard is now a reality.
-rw-r--r-- | dactylino.cpp | 124 | ||||
-rwxr-xr-x | t/test.py | 5 |
2 files changed, 94 insertions, 35 deletions
diff --git a/dactylino.cpp b/dactylino.cpp index 31e217e..82cb9f6 100644 --- a/dactylino.cpp +++ b/dactylino.cpp @@ -27,49 +27,107 @@ * to the Arduino UNO board. */ -const unsigned int LED_PIN = 13; -const unsigned int BUTTON_PIN = 7; -const unsigned int PAUSE = 500; /* ms */ +/** + * 1. Set COL to INPUT_PULLUP mode (it reads HIGH by default) + * 2. But diode on the row (direction?) [Leave it out for now...] + * 3. Program Row to be LOW and OUTPUT, everything else an input + * 4. Then column 1 should read LOW when button is pressed (LOW) + * + * - In sequence, set one row to OUTPUT and LOW, all other rows to INPUT + * - check each column + * - Any column reading LOW is pressed + * - set row back to INPUT and move to next row + */ -int last_state = HIGH; -int current_state; -int counter = 0; +#define DEBOUNCE_TIME 10 -void setup() { - Serial.begin(9600); - pinMode(LED_PIN, OUTPUT); - pinMode(BUTTON_PIN, INPUT_PULLUP); -} +const byte ROWS = 2; +const byte COLS = 2; +const byte TOTAL_KEYS = ROWS * COLS; -void loop() { +const byte row_pins[ROWS] = {2, 3}; +const byte col_pins[COLS] = {6, 7}; - current_state = digitalRead(BUTTON_PIN); +// All the letters you need +const char letters[TOTAL_KEYS] = {'A', 'B', 'C', 'D'}; - if (last_state == HIGH && current_state == LOW) { - digitalWrite(LED_PIN, HIGH); - } +void setup() { + byte i; + Serial.begin(9600); - if (last_state == LOW && current_state == HIGH) { - digitalWrite(LED_PIN, LOW); - Serial.print("Click: "); - Serial.print(++counter); - Serial.println(); - } + for (i = 0; i < COLS; i++) + pinMode(col_pins[i], INPUT_PULLUP); + for (i = 0; i < ROWS; i++) + pinMode(row_pins[i], INPUT); +} - last_state = current_state; +/** + * Need structure to track key state: last known key setting and last time it + * toggled its state + */ +unsigned long last_key_time[TOTAL_KEYS]; - /* - digitalWrite(LED_PIN, HIGH); - delay(PAUSE); - digitalWrite(LED_PIN, LOW); - delay(PAUSE); +/** + * TODO Expand this to an array-back bitmap (only really relevant when we move + * beyond 32 keys) + */ +unsigned char last_key_setting = 0; + +/* TODO Remove the counter, just for debugging */ +unsigned long counter = 0; - counter = (counter + 1) % 10; - Serial.print("."); - if (counter == 0) - Serial.println(""); - */ +void loop() { + bool pressed; + bool last; + byte row, col, k; + + unsigned long now; /* For debouncing */ + + now = millis(); + k = 0; + for (row = 0; row < ROWS; row++) { + /* Set pin to output, and set it LOW */ + pinMode(row_pins[row], OUTPUT); + digitalWrite(row_pins[row], LOW); + + /* Scan all columns */ + for (col = 0; col < COLS; col++) { + if (now - last_key_time[k] < DEBOUNCE_TIME) { + k++; + continue; + } + + /* Read the key */ + pressed = digitalRead(col_pins[col]) == LOW; + last = (last_key_setting & (1 << k)) != 0; + + /* Check the k'th bit */ + if (pressed != last) { + /* Changed */ + last_key_time[k] = now; + /* Toggle the bit */ + last_key_setting ^= (1 << k); + + if (pressed) { + //Serial.print("Key pressed: ("); + //Serial.print("") + } else { + Serial.println(letters[k]); + // Serial.print("Key released: ("); + // Serial.print("row="); + // Serial.print(row); + // Serial.print(",col="); + // Serial.print(col); + // Serial.println(")"); + } + } + + /* Consider next key */ + k++; + } + pinMode(row_pins[row], INPUT); + } } // Declared weak in Arduino.h to allow user redefinitions. @@ -5,9 +5,10 @@ import serial def main(): with serial.Serial('/dev/ttyACM0', 9600, timeout=10) as ser: while True: - b = ser.read() + b = ser.readline() if b: - print(b) + #print(b) + print(b.decode('ascii').strip()) if __name__ == '__main__': main() |