From 7d7084801a958b0e3541364ecbb8d5ec63ccb28f Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Mon, 16 May 2022 23:08:33 +0200 Subject: [PATCH] shorten signals to one char each; add binary tree keyboard --- rotary-kb.py | 12 +-- src/main.cpp | 9 +- treeboard/.gitignore | 1 + treeboard/Cargo.lock | 192 ++++++++++++++++++++++++++++++++++++++++++ treeboard/Cargo.toml | 10 +++ treeboard/src/main.rs | 166 ++++++++++++++++++++++++++++++++++++ 6 files changed, 380 insertions(+), 10 deletions(-) create mode 100644 treeboard/.gitignore create mode 100644 treeboard/Cargo.lock create mode 100644 treeboard/Cargo.toml create mode 100644 treeboard/src/main.rs diff --git a/rotary-kb.py b/rotary-kb.py index a5bd91f..55e85b4 100755 --- a/rotary-kb.py +++ b/rotary-kb.py @@ -7,7 +7,7 @@ from pynput import mouse, keyboard PORT = "/dev/ttyACM1" keys = list(" abcdefghijklmnopqrstuvwxyz") + [keyboard.Key.enter, keyboard.Key.backspace] -keys_display = " abcdefghijklmnopqrstuvwxyz\\<" +keys_display = "_abcdefghijklmnopqrstuvwxyz⏎<" kb = keyboard.Controller() arduino = serial.Serial(port=PORT, baudrate=9600, timeout=.1) @@ -34,15 +34,15 @@ def print_state(): print_state() while True: - event = arduino.readline().decode("utf-8").replace("\r\n", "") - if event == "cw": + event = arduino.read().decode("utf-8") + if event == "r": pos = (pos + 1) % len(keys) - elif event == "ccw": + elif event == "l": pos = (pos - 1 + len(keys)) % len(keys) - elif event == "down": + elif event == "d": kb.press(keys[pos]) active_btn = pos - elif event == "up": + elif event == "u": kb.release(keys[active_btn]) active_btn = -1 diff --git a/src/main.cpp b/src/main.cpp index e919e36..e6ea5ae 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,24 +25,25 @@ void loop() { int a = digitalRead(PIN_A); if (a != prev_a){ // Means the knob is rotating if (digitalRead(PIN_B) != a) { // Means pin A changed first - rotating clockwise - Serial.println("cw"); + Serial.print("r"); } else {// Otherwise B changed first - counter clockwise - Serial.println("ccw"); + Serial.print("l"); } } int btn = digitalRead(PIN_BTN); if (btn != prev_btn) { if (btn) { - Serial.println("up"); + Serial.print("u"); } else { - Serial.println("down"); + Serial.print("d"); } } prev_btn = btn; prev_a = a; + delay(5); } // void debug_signal() { diff --git a/treeboard/.gitignore b/treeboard/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/treeboard/.gitignore @@ -0,0 +1 @@ +/target diff --git a/treeboard/Cargo.lock b/treeboard/Cargo.lock new file mode 100644 index 0000000..03fe3bd --- /dev/null +++ b/treeboard/Cargo.lock @@ -0,0 +1,192 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "core-foundation" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + +[[package]] +name = "core-graphics" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f15b3cb55687886a6b66953123621e5a1529a91a01666d646fb64baa13f900f0" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "enigo" +version = "0.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce8d7672e87b3155fd5e8a9226276da5c833e15bc879c7b98a78f743b67814" +dependencies = [ + "core-graphics", + "libc", + "objc", + "pkg-config", + "unicode-segmentation", + "winapi", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "ioctl-rs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "pkg-config" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "serial" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86" +dependencies = [ + "serial-core", + "serial-unix", + "serial-windows", +] + +[[package]] +name = "serial-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581" +dependencies = [ + "libc", +] + +[[package]] +name = "serial-unix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7" +dependencies = [ + "ioctl-rs", + "libc", + "serial-core", + "termios", +] + +[[package]] +name = "serial-windows" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162" +dependencies = [ + "libc", + "serial-core", +] + +[[package]] +name = "termios" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" +dependencies = [ + "libc", +] + +[[package]] +name = "treeboard" +version = "0.1.0" +dependencies = [ + "enigo", + "serial", +] + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/treeboard/Cargo.toml b/treeboard/Cargo.toml new file mode 100644 index 0000000..5e80cfc --- /dev/null +++ b/treeboard/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "treeboard" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +enigo = "0.0.14" +serial = "0.4.0" \ No newline at end of file diff --git a/treeboard/src/main.rs b/treeboard/src/main.rs new file mode 100644 index 0000000..67fa903 --- /dev/null +++ b/treeboard/src/main.rs @@ -0,0 +1,166 @@ +use std::io::Read; +use enigo::*; + + +fn main() { + let port = "/dev/ttyACM1"; + println!("Connecting to arduino on port {}...", port); + let connection = serial::open(port); + if connection.is_err() { + println!("Connection failed {}", connection.err().unwrap()); + return; + } + + let mut connection = connection.unwrap(); + let mut board = Treeboard::new(); + board.print(); + loop { + let mut recieved = [0; 1]; + if let Ok(_count) = connection.read(&mut recieved) { + let data = String::from_utf8(recieved.into()).unwrap(); + match data.chars().next().unwrap() { + 'r' => board.right(), + 'l' => board.left(), + 'd' => board.press(), + 'u' => board.release(), + _ => () + } + } + } +} + +struct Treeboard { + input: Enigo, + pressed: bool, + keys: Vec, + pos: usize, +} + +struct KeyNode { + name: String, + key: Key, + right: usize, + left: usize, +} + +impl KeyNode { + fn new(name: &str, key: Key, right: usize, left: usize) -> Self { + Self { + name: name.to_owned(), + key, right, left, + } + } +} + + +impl Treeboard { + fn new() -> Self { + let keys = vec![ + KeyNode::new("_", Key::Space, 1, 2), + + KeyNode::new("E", Key::Layout('e'), 3, 4), + KeyNode::new("A", Key::Layout('a'), 5, 6), + + KeyNode::new("R", Key::Layout('r'), 7, 8), + KeyNode::new("I", Key::Layout('i'), 9, 10), + KeyNode::new("O", Key::Layout('o'), 11, 12), + KeyNode::new("T", Key::Layout('t'), 13, 14), + + KeyNode::new("N", Key::Layout('n'), 15, 16), + KeyNode::new("S", Key::Layout('s'), 17, 18), + KeyNode::new("L", Key::Layout('l'), 19, 20), + KeyNode::new("C", Key::Layout('c'), 21, 22), + KeyNode::new("U", Key::Layout('u'), 23, 24), + KeyNode::new("D", Key::Layout('d'), 25, 26), + KeyNode::new("P", Key::Layout('p'), 27, 28), + KeyNode::new("M", Key::Layout('m'), 29, 30), + + KeyNode::new("H", Key::Layout('h'), 0, 0), + KeyNode::new("G", Key::Layout('g'), 0, 0), + KeyNode::new("B", Key::Layout('b'), 0, 0), + KeyNode::new("F", Key::Layout('f'), 0, 0), + KeyNode::new("Y", Key::Layout('y'), 0, 0), + KeyNode::new("W", Key::Layout('w'), 0, 0), + KeyNode::new("K", Key::Layout('k'), 0, 0), + KeyNode::new("V", Key::Layout('v'), 0, 0), + KeyNode::new("X", Key::Layout('x'), 0, 0), + KeyNode::new("Z", Key::Layout('z'), 0, 0), + KeyNode::new("J", Key::Layout('j'), 0, 0), + KeyNode::new("Q", Key::Layout('q'), 0, 0), + KeyNode::new(",", Key::Layout(','), 0, 0), + KeyNode::new(".", Key::Layout('.'), 0, 0), + KeyNode::new("⏎", Key::Return, 0, 0), + KeyNode::new("<", Key::Backspace, 0, 0), + ]; + + Self { + input: Enigo::new(), + pressed: false, + keys, + pos: 0, + } + } + + fn print(&self) { + println!("\n\n\n\n"); + let mut depth = 4; + let mut row = Vec::new(); + row.push(0); + loop { + if depth != 0 { + print!(" "); + } + if depth > 1 { + for _ in 0..(2usize.pow(depth-1)-1) { + print!(" "); + } + } + let mut next_row = Vec::new(); + for k in row { + next_row.push(self.keys[k].left); + next_row.push(self.keys[k].right); + let name = &self.keys[k].name; + if k == self.pos { + print!("{})", name); + } + else { + print!("{} ", name); + } + for _ in 0..(2usize.pow(depth)-1) { + print!(" "); + } + } + println!(""); + row = next_row; + if depth == 0 { + break; + } + depth -= 1; + } + + } + + fn right(&mut self) { + self.move_to(self.keys[self.pos].right); + } + + fn left(&mut self) { + self.move_to(self.keys[self.pos].left); + } + + fn move_to(&mut self, new_pos: usize) { + if new_pos < self.keys.len() && !self.pressed { + self.pos = new_pos; + self.print() + } + } + + fn press(&mut self) { + self.input.key_down(self.keys[self.pos].key); + } + + fn release(&mut self) { + self.input.key_up(self.keys[self.pos].key); + self.move_to(0); + } +}