Close

Synchronizing the Halves

A project log for PolyKybd (Displays In Your Keycaps)

Freedom at your fingertip.

thpollthpoll 03/28/2023 at 09:070 Comments

Finishing the second hardware prototype turned out to be more involved than expected! I had some troubles (with noise I think) on the signal lines, which went away when I removed the pull-up resistors which I had on the SPI pins (I shouldn't have used them in the first place, as it is not I2C but at some point these solved a problem with floating pins when I was using the STM407F MCU and they just stayed - well, until now).

Once a while, there is still a glitch, which I need to investigate. The strange thing is that also without refresh, I can see some pixel light up one a while. My best guess so far is that I unintentionally introduce some capacitance or resistance due to my soldered together flex-cables (the pitch is only 0.5mm so it is possible that two neighbor lines almost touch each other) and these cause some troubles. That problem would go away if I could get the customized displays with the longer flex cables... but I cannot prove it for now.

Needed Software Changes: Since I have two identical boards for my "test keyboard setup", I started using the eeprom to store which side is the actual left and right side(with `#define EE_HANDS` and make handwired/polykb/wave:default:left` `...right`), but that is not needed as the is a master detection with ChibiOS and it just sets the master to the side with the connected USB cable (just connect the able to the 'correct' side).

Additionally, I had to double the key matrix and num of RGB LEDs as if everything runs on one side (turns out that actually happens - the master just receives the keypress from the other side and runs the logic!). So in the end this is what I changed:

rules.mk:

SPLIT_KEYBOARD = yes

config.h:

#define RGBLED_NUM 72
#define DRIVER_LED_TOTAL RGBLED_NUM
#define RGB_MATRIX_SPLIT { 36, 36 }
#define SERIAL_USART_TX_PIN GP5
#define SPLIT_TRANSPORT_MIRROR
#define SPLIT_LAYER_STATE_ENABLE
#define SPLIT_LED_STATE_ENABLE
#define SPLIT_MODS_ENABLE
#define SPLIT_OLED_ENABLE
//and also define a new LAYOUT to have both sides in one:
#define SPLIT_LAYOUT

( ... My first few connection tests failed, however after changing a couple of things back and forth I got some basic input working, however, just for one the master (left side) and !some! key on the slave (right side):

Again, it took me some time to think about it, but after the realization that only the master really executes the logic it was clear that all my static helpers were never updates on the other side (and some initial mistakes when adding the second side to the layout).

The solution to this was to use the housekeeping task and check for changes (as we already configured QMK to sync status changes like modifiers and status LEDs) and then perform the needed updates. As I can do the same on the master the display update now moved from the matrix processing to the housekeeping as well, which should be an improvement for the scan rate!

To also get the language change propagated (which are no QMK layers), I had to add a rpc callback which is triggered by the master to send that information together with the display brightness:

The `user_sync_poly_data_handler` task is executed on the the `slave` side, which just sets the static variables and then asks for a refresh of the displays which will be done in the housekeeping task.

There are still open software issues I need to address at some point (RGB matrix lighting not working correctly at the moment, fade in and out after timeout has some side effects, code cleanup - yes it's messy at the moment, the OLED display update could be faster, ...) but for now you can find the work-in-progress code here: https://github.com/thpoll83/qmk_firmware/tree/PolyKeyboard

And here a small video I posted on Twitter: https://twitter.com/thpoll2/status/1591026041434226688?s=20&t=j8DVR1XFWFR__iBi13svhw

Discussions