Rotary knob emulating a Bluetooth keyboard, that lets you control the speakers volume from the comfort of your own sofa.
Made using Raspberry Pi Pico W, with code written in Rust using the Embassy framework.
Rotary knob emulating a Bluetooth keyboard, that lets you control the speakers volume from the comfort of your own sofa.
Made using Raspberry Pi Pico W, with code written in Rust using the Embassy framework.
I built it! I build an useful device using Raspberry Pi Pico!
It is a small box with a single knob sticking out of it. The knob can be used to control the volume of any device with Bluetooth support, be it Windows, Linux or even Android. No more taking that clunky keyboard to the couch while watching a movie on a pc.
I am really happy how the physical box turned out, I really was lucky to find a perfect one in my drawer. It looks decent, it isn’t very big, and all the electronics (except) the knob can just be taken out if needed.
Writing the code was also pretty easy, and fun, except for few small papercuts, and most importantly Bluetooth authentication. Getting that one to work properly was a nightmare, and it still isn’t perfect (it uses an workaround), which I belive is an inner problem of the Bluetooth library trouble.
Pressing the knob will now toggle volume mute on the connected device.
I also added the bluetooth authentication key storage to allow the device to reconnect more easily.
Finally I made sure knob rotations are ignored when the device is not connected, not to cause unexpected behavior after connecting.
The device is no use, if it is just a bunch of loose cables. By complete accident, while I was looking through my drawer today, I found a small, empty cardboard box, that ended up being perfect to contain the project. I cut out few strips of another cardboard, and settled the knob in them. Then I pieced them together with some string (so it can be disassembled if needed), cut a hole in the box for the knob, and tied it with some more rope.
In the end I connected all the wires to a small breadbord with the pico, and a battery basket, both of which were put in the cardboard box.
This gives us a nice box, out of which only the knob sticks out when closed, and does exactly what it was made for: lets me control the volume from something much smaller and less clunky, then a big keyboard.
Log in to leave a comment
After much work, we have a working rotary knob that can control the volume of the device it is connected to.
Rust embedded ecosystem is still pretty new, so I wasn’t able to find any library for making a HID device with Bluetooth LE. Instead, I had to manually write out the GATT services. Fortunately, it was easier than I thought, with only two being required for a working device. I also had to drop down to Windows (from my usual Linux) for a moment to generate a HID descriptor using the Waratah tool.
However, the biggest trouble, which took most of the time assigned to this devlog was getting the bluetooth device to connect and not get disconnected by OS or throw some error and disconnect itself. I spent probably another six hours not counted here, staring at logs, btmon, and searching about bluetooth pairing. So far, I haven’t managed to get a JustWorks pairing to work, and instead settled on a fake pin pairing. The device pretends it is displaying a pin to the user, and letting him confirm it, when actually it just automatically confirms it, and the user also does so on the device he intends to control. I believe the trouble with JustWorks authentication is caused by - guess it - trouble! - the BLE library I am using (pun intended). Another possibility is Linux causing problems or it might even be both.
I’m planning to open an issue on trouble github about this, and maybe the library can get fixed.
This project is not yet done.
I still need to implement proper pairing data storage, so the device can reconnect after being powered off, I need to connect knob press to mute, and I need to make a physical package for the device, so it is actually usable. The authentication without pin is also something I would love to get working.
The video showcases the knob being used with a phone because it was easier to record, but it works with a pc too obviously.
Log in to leave a comment
Knob rotation is fixed!
Now every turn is detected correctly, yay.
The solution?
Even more bit patterns.
Log in to leave a comment
Bluetooth stack is up!
This was mostly copy-paste work from the examples folder of trouble, the BT stack by Embassy, with some tweaks and few small things to figure out.
Below you can see a screenshot from the NRF Connect mobile app, which lets you discover and debug Bluetooth devices around, recognising my device.
I also spent some more time messing with the knob, to see how it works, however so far I didn’t manage to fix the every other rotation reporting.
Next comes the hard part which is figuring out how to make Pico appear as a HID device, get accepted by different OS’es (I read windows might have some additional requirements), and how to send keypresses.
Log in to leave a comment
The knob is working! (kinda)
I wrote the code to handle the input from the knob, and now it prints into debug log when rotated left or right. However for some reason it detects only every other rotation (you need to rotate it twice in on direction to get a print). This is to be fixed. I’m also considering using interrupts for this (for fun), but the Embassy documentation is pretty lacking, so I will leave this for later.
Log in to leave a comment