Link to Macropad firmware repository: https://github.com/2004Island/macropad-circuitpython
After working on the firmware for a while, I have got the macropad to work! Progress was pretty quick getting the lighting to work on the board. I had all the neopixels responding to keypresses according to the kdl config file after less than a week of work, and it was really motivating to see the description language I hacked together actually work surprisingly well.
Afterwards I moved on to the most integral part of any macropad: the OLED display. I was quickly able to get text working on this display as Adafruit’s ssd1306 library provides a very straight-forward function to print text. I wanted to add a way of rendering full images, which led me to look through the source code of all the framebuffer and ssd1306 drivers to create a simple pbm codec that could write to the framebuffer.
From the basic event handler I used when testing on my laptop, it took a little bit of reworking KDL to implement more complex key events for all the features the board had that I couldn’t really test on my numpad, such as a display and neopixels. I settled on a structure where the key pressed and released methods of the ‘interpreter’ returns lists for all the actions organized by their type. Currently they return a tuple structured as follows:
(changed_state, led_update, display_command, press_sequence, type_str, errors)
This allows KDL to be very portable, as the project using it needs only to implement the set list of commands that the interpreter can return for a key event.
Press_sequence and type_str commands were separated to differentiate between two distinct forms of key pressing: Shortcuts and typing. Type_str types each character one by one as you would expect, but press_sequence holds each key until the very last one is typed. This subtle distinction makes it possible to do shortcuts like CTRL ALT t
to open a bash terminal in Ubuntu, which has been particularly helpful for me.
I had gotten to this point after several weeks of working on the firmware and starting a new quarter at college, and progress was going well. I just needed to implement the usb keyboard functionality, and it would be mostly complete. Instead, I started to notice the limitations of CircuitPython. Only a few debug print statements would slow down the code noticeably, and I2C communication with the display was even more egregious, holding up the one core that CicruitPython would let me use. After a basic test of the SSD1306 in MicroPython made CircuitPython look embarrassingly slow, I knew I wanted to switch. The only problem was that MicroPython doesn’t have a USB HID library, so I would have to figure out how to write my own using C and either compile it into an mpy module, or compile it into MicroPython itself. I spent about 3 months working on this problem, which I will probably talk more about in another post, but it ended up not working out. I really want to revisit this tangent later, as I think if I took some time to familiarize myself with the TinyUSB library I used it would work.
In the end, I came back to the CircuitPython based firmware, and finished implementing the keyboard functionality. This is where I am now. The firmware currently works, and I am now working on polishing it. The CircuitPython speed problems aren’t really an issue, the macropad feels surprisingly snappy, but it still bugs me to have so much performance still on the table.
>> Home