Making a Bloom Filter Keyboard
The original idea
Both of us have an interest in building and tinkering, and at the beginning of the pandemic, Shae convinced Maryanne to subscribe to get all kinds of gadgets through ADABOX with Adafruit. While we both had random cool hardware that came with useful tutorials and clear instructions, we wanted to see what else we could do with the components.
In Spring 2021, Shae wrote Bloohm to help show process status for running tests using an Adafruit neotrellis he'd gotten in one of the early ADABOXs. At the time, both of us had Moonlander keyboards with RGB LEDs under the keys.
Moonlanders also have open-source firmware, so we tried to figure out how to display the same RGB process status on our keyboards with zero success (the feature requests for the ZSA fork of QMK have languished for years at this point).
More recently, Maryanne started a job which required writing a lot of tests, and she wanted to utilize Bloohm after buying her own Adafruit neotrellis. She also wanted to learn Rust, so she rewrote the host side of Bloohm but in Rust as Bloomrs. When she bought a Keyboardio.io Model 100, she did some investigation and found that the Model 100 had its own open source firmware that seemed significantly more approachable. Shae likes buying keyboards and thought the Bloom keyboard was still a great project and thus bought a Model 100 specifically for this project (yes, really).
Once we both had Model 100s, it was time to do some hacking and figure out how to set RGB LEDs with serial port commands!
Getting started with Arduino IDE/CLI, Chrysalis, and Kaleidoscope
Chrysalis is the main entry point for working with the Model 100; we only found out about Kaleidoscope from another Model 100 owner, Joe Ardent. Once we dug into the firmware source, there were still a number of pain points with Kaleidoscope, where documentation is either missing or incomplete.
When we got started flashing our own firmware on the Model 100, there was a lot of trial and error. Both of us were working with Chrysalis at the same time as the Arduino IDE, and it turns out that you can't send new instructions on the serial port or flash the keyboard while Chrysalis is open (there is no feedback to indicate that they exclusively use the same serial port).
The docs also say to hold the PROG button to get the keyboard into upload mode, but they don't say when to release it. It's safe to release the key once the firmware starts uploading (the first column of key LEDs will start cycling green). If you keep holding the PROG button down after uploading new firmware, the keyboard will not exit that mode (the LED on the PROG button will stay red), and you'll have to unplug and replug in your keyboard.
There's a shell script in Kaleidoscope for testing that sends serial port commands to the keyboard from the host. You will likely need to change the usb device filename to match the output from running $ ls -otr /dev/tty*
.
It ended up being too hard to figure out how to configure the Arduino GUI to point to a locally modified git repo; we ended up using the Arduino CLI.
Writing the code
Joe Ardent pointed us a deprecated plugin called LEDControl, demonstrating that it was possible to write LED colors to the keyboard from the host.
The LEDControl plugin is now a core plugin, but its methods are no longer exposed by default (you can see exposed methods by running $ ./focus-send help
).
We isolated a small plugin called LEDBrightnessConfig which utilized LEDControl methods and also had an exposed method led.brightness
in the default Model 100 firmware. We hacked up the plugin to figure out how input gets parsed by the firmware.
Maryanne then figured out how to add a whole new plugin as a directory, which is not covered in the Kaleidoscope tutorials. The Kaleidoscope tutorial only covers modifying the .ino
file directly, rather than library type plugins. With a plugin scaffold, Shae ugly hacked some of the old LEDControl code into the new plugin... which compiled but did nothing (no output running $ ./focus-send led.at
). Maryanne debugged the C++ to figure out which methods we actually needed, and we could finally both get and set LEDs on a key-by-key basis with $ ./focus-send led.at
.
We've added two in-progress plugins to our fork of Kaleidoscope for just exposing led.at
, as well as the Bloom keyboard functionality.
Next steps
We still need to do some cleanup on the plugins and add documentation and helpful comments. We have not configured the plugin to work as its own LED mode yet. It will write to the colors set by the active LED mode, but that mode may immediately write back over the key at any time. Keys will absolutely be overwritten by animation modes like DigitalRain, Chase, or Breathe.