zmk
zmk copied to clipboard
Pimoroni PIM447 trackball support
I wrote a Zephyr driver for the famous Pimoroni PIM447 trackball and added the necessary glue on top of the "mouse-pr" development branch. This glue will likely change in the future since mouse support in ZMK is not stabilized yet; I actually open this pull-request to let other users play with this driver.
Note: thanks to a neat trick, small displacements are very precise whereas large displacements are quite fast; it never feels choppy at all. This has been successfully tested with the Zephirum, but it should work with any ZMK keyboard.
Huh, this looks sweet! You might as well PR this into the main mousekeys branch. Also, could you please record a GIF or a video?
Huh, this looks sweet! You might as well PR this into the main mousekeys branch. Also, could you please record a GIF or a video?
Of course, here it is (the link will expire after 190 days): https://webmshare.com/play/ew0rP
Huh, this looks sweet! You might as well PR this into the main mousekeys branch. Also, could you please record a GIF or a video?
Of course, here it is (the link will expire after 190 days): https://webmshare.com/play/ew0rP
Excellent! So running everything in a dedicated thread (and not a workqueue) is indeed the answer! Nevertheless, I still think power consumption needs to be taken into account. Are you on the ZMK Discord? I'd love to have an architecture discussion over there.
Are you on the ZMK Discord? I'd love to have an architecture discussion over there.
Sadly I don't have enough time to be useful in this regard. Sorry.
@cdc-mkb do you have an example shield and keymap configuration? I coudn't find a repository for the zephirium where the trackball driver was used. I'd like to use a trackball with my zmk setup, but even when using your fork I am a bit lost on how to implement it in a keymap.
@grasegger you can take a look at my configuration here: https://github.com/cdc-mkb/zmk/commit/b2a172b219b0de95e3ca2de39d680a4ab7db270c Be careful: you only need to adjust your .conf and .overlay files, there is no need to change anything in the .keymap file (my configuration also uses the "macro" WIP feature, that's why the .keymap is modified here but this is not related to the PIM447 trackball driver).
@grasegger you can take a look at my configuration here: cdc-mkb@b2a172b Be careful: you only need to adjust your .conf and .overlay files, there is no need to change anything in the .keymap file (my configuration also uses the "macro" WIP feature, that's why the .keymap is modified here but this is not related to the PIM447 trackball driver).
Thanks - that helped a lot.
There is no possibility to rebind the actions of the trackball to e.g. scroll, if I see that correctly?
@grasegger you are right, this is not implemented yet. Using this tiny trackball to scroll on documents/webpages is a feature (in QMK) I like a lot, so I'll surely add this feature to this pull request soon.
@cdc-mkb One last questions, since I don't have the hardware to test here yet: Would it be possible to support two trackballs on two split keeb halfs? One for scrolling, one for cursor movements, and with different bindings (left click, right click)? Is there any way I can help? I know a bit of C/C++, but never worked with firmware.
@cdc-mkb One last questions, since I don't have the hardware to test here yet: Would it be possible to support two trackballs on two split keeb halfs? One for scrolling, one for cursor movements, and with different bindings (left click, right click)? Is there any way I can help? I know a bit of C/C++, but never worked with firmware.
@grasegger So far I assumed only one trackball is used, but I'm pretty sure it should be technically feasible to make a driver that works for several trackballs at the same time. I didn't think about this use case so far, so feel free to send me ideas, patches, ... for review if you wish.
Anyway, I added a couple of new features to this PIM447 driver for ZMK, for instance it it now possible to use it as a mouse pointer and as mouse wheels (the mode can be changed dynamically). It is also possible to place the breakout board in any position thanks invert/swap transformation on axes. See https://github.com/cdc-mkb/zmk/commit/45e1ae7f29abf37dd96387983107370e28e9560c for information on how to use these new features.
@krikun98 @cdc-mkb Any idea of how badly it would affect battery life? I really would like to use this trackball but a little bit concened about how much it will drain.
New version:
- it is now possible to use mouse emulation key behaviors (ex. &mkp, &mwh) and the trackball at the same time
- the trackball key behaviors support (&pim447*) has been reworked; it was buggy and clumsy.
@krikun98 @cdc-mkb Any idea of how badly it would affect battery life? I really would like to use this trackball but a little bit concened about how much it will drain.
@wizar I have no idea since I'm only using the USB HID. Pimoroni hasn't replied to my question about the INT signal so far :( (https://forums.pimoroni.com/t/pim447-trackball-how-to-get-a-clean-int-signal/17968)
@cdc-mkb Can you take a look at my shield config? Keys are working, but the trackball isn't.
SDA is connected to pin 006 (D0) and SCL to pin 008 (D1)
https://github.com/grasegger/keyboard-layout/tree/anna/config/boards/shields/anna
I tried adding &i2c0 { compatible = "nordic,nrf-twi"; sda-pin = <0>; scl-pin = <1>; };
to the board/nice_nano.overlay
@grasegger My reply here: https://github.com/grasegger/keyboard-layout/pull/1
Hey @cdc-mkb,
I'm trying to build a custom shield with pimoroni support off of your branch, but it fails because it doesn't recognize the flag CONFIG_ZMK_TRACKBALL_PIM447... can you point me in the right direction for what needs to be fixed? I'm completely new to ZMK still, so I'd appreciate the help :)
Here's the line that fails in the Github Action: https://github.com/genkobar/zmk-config/runs/4342798400?check_suite_focus=true#step:9:35
Thansk for working on this feature support!
A github thread I managed to find with some potentially helpful info on interrupt pin / usage:
https://github.com/pimoroni/trackball-python/issues/5
Thanks! I just managed to build a PMW3360 based trackball, just replacing the driver in this PR by that implemented in nrf sdk (which cannot be used directly in zmk unfortunately due to the license issue). I'm now trying to modify it to irq based.
@cdc-mkb Sadly I can't get it working the the n!nv2 I have. After I tried it on my on board without luck I connected the wires to the kyria, which has dedicated sda, scl, vcc and gnd on the pcb.
I played around with the config a bit and stumbled upon Check these unsatisfied dependencies: I2C
which I worked around with a CONFIG_I2C
, after that I got no errors or warnings regarding the 447 anymore. Sadly neither via usb nor bluetooth the cursor moves or scrolls.
https://github.com/grasegger/keyboard-layout/tree/main/nice_nano_v2/kyria
@cdc-mkb the documentation is different from the Kconfig you wrote
should be CONFIG_ZMK_TRACKBALL_PIM447=y
instead of CONFIG_ZMK_PIM447_TRACKBALL=y
@grasegger I made it work with a nano (https://github.com/devenv/zmk-config/tree/trackball)... For some time (like 10 seconds), then it fails on this error and stops working:
<err> i2c_nrfx_twi: Error 195952642 occurred for message 0
<err> trackball_pim447: Sensor reg read byte failed
<err> PIM447: Failed to fetch TRACKBALL_PIM447 sample
hi regarding the INT pin, it looks like you need to init the trackball with a special i2c write for it to work. At least there is an example here : https://github.com/pimoroni/pimoroni-pico/blob/3ce347799b74b81bc18611867dea202e6e1f875f/drivers/trackball/trackball.cpp#L89
I am tinkering with a Pimoroni atm. Would love to see this on ZMK. Just found out that there is a new firmware for it which fixes the interrupt issue! See the OP post on their forum: https://forums.pimoroni.com/t/pim447-trackball-how-to-get-a-clean-int-signal/17968/10 Hope this gives some new life into this PR!
Question to anyone who has this up and running:
Does moving the trackball around feel a bit... "stiff", or is it just my keeb/me? Moving the trackball in circles generates a cursor movement that feels like discrete up/down/left/right movements, rather than the cursor moving diagonally (i.e., both axes updating simultaneously). Reading through the pim447 app loop, I see all 3 axes states (x, y, button) being set within the same mouse report, so I'm wondering if I'm observing a HW limitation (which would be quite discouraging) or something that still needs to be improved in SW.
For reference, I have this up on a nice!nano v2 (driving a Corne shield, if it matters), connected over USB to a Windows 10 host.
P.S. Thanks a ton to @cdc-mkb for getting this effort this far.