Created
May 15, 2022 21:03
-
-
Save JosephCatrambone/0df3d9be6a73cfd5b2ae5b924efe3fab to your computer and use it in GitHub Desktop.
TinyPICO BlueTooth BLE Morse Keyboard
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 <BleKeyboard.h> | |
#include <TinyPICO.h> | |
TinyPICO tinypico = TinyPICO(); | |
BleKeyboard keyboard; // keyboard("Name", "manufacturer", battery_level_100) | |
// a .- | |
// b -... | |
// c -.-. | |
// d -.. | |
// e . | |
// f ..-. | |
// g -.. | |
// h .... | |
// i .. | |
// j .--- | |
// k -.- | |
// l .-.. | |
// m -- | |
// n -. | |
// o --- | |
// p .--. | |
// q --.- | |
// r .-. | |
// s ... | |
// t - | |
// u ..- | |
// v ...- | |
// w .-- | |
// x -..- | |
// y -.-- | |
// z --.. | |
// 1 .---- | |
// 2 ..--- | |
// 3 ...-- | |
// 4 ....- | |
// 5 ..... | |
// 6 -.... | |
// 7 --... | |
// 8 ---.. | |
// 9 ----. | |
// 0 ----- | |
// . .-.-.- | |
// , --..-- | |
// ? ..--.. | |
// ! -.-.-- | |
// ' .----. | |
// " .-..-. | |
// ( -.--. | |
// ) -.--.- | |
// & .-... | |
// : ---... | |
// ; -.-.-. | |
// / -..-. | |
// _ ..--.- | |
// = -...- | |
// + .-.-. | |
// - -....- | |
// $ ...-..- | |
// @ .--.-. | |
// RETURN .-.- | |
// ERR ........ | |
// Pins indicate the physical device pins, not the GPIO numbers. | |
// IDX values are their position in the assorted arrays, like justPressed. | |
const byte DOT_PIN = 14; // The one nearest the antenna on the tinypico. | |
const byte DOT_IDX = 0; | |
const byte DASH_PIN = 15; | |
const byte DASH_IDX = 1; | |
const byte SUBMIT_PIN = 27; | |
const byte SUBMIT_IDX = 2; | |
const byte COMMAND_PIN = 26; | |
const byte COMMAND_IDX = 3; | |
const byte NUM_PINS = 4; | |
const uint8_t MORSE_TREE[] = { //char? | |
' ', | |
// . - | |
'e', 't', | |
//.. .- -. -- | |
'i', 'a', 'n', 'm', | |
//... ..- .-. .-- -.. -.- --. --- | |
's', 'u', 'r', 'w', 'd', 'k', 'g', 'o', | |
//.... ...- ..-. ..-- .-.. .-.- .--. .--- -... -..- -.-. -.-- --.. --.- ---. ---- | |
'h', 'v', 'f', ' ', 'l', '\n', 'p', 'j', 'b', 'x', 'c', 'y', 'z', 'q', ' ', ' ', | |
// ..... ....- ...-. ...-- ..-.. ..-.- ..--. ..--- .-... .-..- .-.-. .-.-- .--.. .--.- .---. .---- -.... -...- -..-. -..-- -.-.. -.-.- -.--. -.--- --... --..- --.-. --.-- ---.. ---.- ----. ----- | |
'5', '4', ' ', '3', ' ', ' ', ' ', '2', '&', ' ', '+', ' ', ' ', ' ', ' ', '1', '6', '=', '/', ' ', ' ', ' ', '(', ' ', '7', ' ', ' ', ' ', '8', ' ', '9', '0', | |
// ...... .....- ....-. ....-- ...-.. ...-.- ...--. ...--- ..-... ..-..- ..-.-. ..-.-- ..--.. ..--.- ..---. ..---- .-.... .-...- .-..-. .-..-- .-.-.. .-.-.- .-.--. .-.--- .--... .--..- .--.-. .--.-- .---.. .---.- .----. .----- | |
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '$', ' ', ' ', '?', '_', ' ', ' ', ' ', ' ', '"', ' ', ' ', '.', ' ', ' ', ' ', ' ', '@', ' ', ' ', ' ', '\'', ' ', | |
// -..... -....- -...-. -...-- -..-.. -..-.- -..--. -..--- -.-... -.-..- -.-.-. -.-.-- -.--.. -.--.- -.---. -.---- --.... --...- --..-. --..-- --.-.. --.-.- --.--. --.--- ---... ---..- ---.-. ---.-- ----.. ----.- -----. ------ | |
' ', '-', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ';', '!', ' ', ')', ' ', ' ', ' ', ' ', ' ', ',', ' ', ' ', ' ', ' ', ':', ' ', ' ', ' ', ' ', ' ', ' ', ' ', | |
}; // Start at space, then most down the binary tree. The left subtree of a binary tree is at position (2*n)+1. The right is at 2*(n+1) | |
const uint8_t COMMAND_TREE[] = { | |
KEY_BACKSPACE, | |
KEY_LEFT_ARROW, KEY_RIGHT_ARROW, | |
KEY_DOWN_ARROW, ' ', ' ', KEY_UP_ARROW, | |
's', 'u', 'r', 'w', 'd', 'k', 'g', 'o', | |
'h', 'v', 'f', ' ', 'l', ' ', 'p', 'j', 'b', 'x', 'c', 'y', 'z', 'q', ' ', ' ' | |
}; // TODO: Pad this out with the remaining items in the tree so we don't access out of bounds. | |
const byte MORSE_TREE_LIMIT = 128; // Must be less than this, not equal to. | |
const byte keyboardPins[] = {DOT_PIN, DASH_PIN, SUBMIT_PIN, COMMAND_PIN}; | |
bool justPressed[] = {false, false, false, false}; | |
bool justReleased[] = {false, false, false, false}; | |
bool pressed[] = {false, false, false, false}; | |
bool anyKeyPressed = false; | |
int morseCursor = 0; // Where in the morse tree we are. | |
void setup() { | |
Serial.begin(115200); | |
keyboard.begin(); | |
pinMode(DOT_PIN, INPUT_PULLUP); // Input, output, or INPUT_PULLUP | |
pinMode(DASH_PIN, INPUT_PULLUP); // pinMode(x, INPUT); digitalWrite(x, HIGH); is no longer necessary w/ new arduinos. | |
pinMode(SUBMIT_PIN, INPUT_PULLUP); | |
pinMode(COMMAND_PIN, INPUT_PULLUP); | |
// Do we want an output pin for digitalWrite debugs? | |
tinypico.DotStar_SetPower(true); | |
} | |
void readInputState() { | |
anyKeyPressed = false; | |
for(byte i=0; i < NUM_PINS; i++) { | |
bool activeThisFrame = (digitalRead(keyboardPins[i]) == LOW); | |
justReleased[i] = !activeThisFrame && pressed[i]; // This _was_ pressed last frame, so it's just released. | |
justPressed[i] = activeThisFrame && !pressed[i]; | |
pressed[i] = activeThisFrame; | |
anyKeyPressed = anyKeyPressed || activeThisFrame; | |
} | |
} | |
void disconnectedLoop() { | |
// Cycle the DotStar LED colour every 25 milliseconds | |
tinypico.DotStar_CycleColor(25); | |
// You can set the DotStar LED colour directly using r,g,b values | |
// tp.DotStar_SetPixelColor( 255, 128, 0 ); | |
// You can set the DotStar LED colour directly using a uint32_t value | |
// tp.DotStar_SetPixelColor( 0xFFC900 ); | |
// You can clear the DotStar LED too | |
// To power down the DotStar LED for deep sleep you call this | |
} | |
void connectedLoop() { | |
// Disengage LED. | |
tinypico.DotStar_Clear(); // Clear first, | |
tinypico.DotStar_SetPower( false ); // Then power down the LED when connected to save power. | |
// Check for tapped 'keys'. If the 'submit' key is just _released_ then we send the key. | |
if(justReleased[SUBMIT_IDX]) { | |
Serial.write(MORSE_TREE[morseCursor]); // Write, rather than print, because this is a uint8 instead of a char. | |
// Send the key. | |
keyboard.press(MORSE_TREE[morseCursor]); // Or perhaps keyboard.print? | |
morseCursor = 0; | |
delay(10); | |
keyboard.releaseAll(); | |
} | |
if(justReleased[COMMAND_IDX]) { | |
keyboard.press(COMMAND_TREE[morseCursor]); | |
bool wasShift = (COMMAND_TREE[morseCursor] == KEY_LEFT_SHIFT); | |
morseCursor = 0; | |
delay(10); | |
if(!wasShift) { | |
keyboard.releaseAll(); | |
} | |
} | |
if(justReleased[DOT_IDX]) { // Move 'left' in the tree. | |
morseCursor = (2*morseCursor)+1; | |
delay(10); | |
} | |
if(justReleased[DASH_IDX]) { // Move 'right'. | |
morseCursor = 2*(morseCursor+1); | |
delay(10); | |
} | |
if(morseCursor >= MORSE_TREE_LIMIT) { | |
morseCursor = 0; | |
delay(20); | |
} | |
/* | |
keyboard.print("TEST!"); | |
keyboard.write(KEY_RETURN); | |
keyboard.press(KEY_LEFT_SHIFT); | |
keyboard.press(KEY_LEFT_CTRL); | |
keyboard.press(KEY_LEFT_ALT); | |
keyboard.press(KEY_DELETE); | |
keyboard.releaseAll(); | |
*/ | |
} | |
void loop() { | |
readInputState(); | |
if(keyboard.isConnected()) { | |
connectedLoop(); | |
} else { | |
disconnectedLoop(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment