DIY Surface Dial

Microsoft's Surface line of hardware has some nice computers and accessories. Among the accessories there's the Surface Dial - a Bluetooth knob that can do things like volume control, scrolling, undo/redo and some other functions in certain applications, mostly artist-oriented. For some reason the physical form of the Surface Dial appeals to me, but since its price is not exactly in the impulse buy territory and I don't have a practical need for it, I never got one. But now I have made my own version of it. It's not as nice as the real one and it's missing some of the functionality, but it really does work as a Surface Dial in the software that supports it.

There are two aspects to this device, making the physical hardware and programming it so that Windows recognizes it as a Surface Dial.

From the hardware perspective, we need two things - a way of detecting the dial's rotation and a button. On the real Surface Dial the entire knob works as a button, but in my version, there's a separate button in the middle, made using a mechanical keyboard switch. As for the dial itself, instead of using an off-the-shelf rotary encoder, I made my own using small neodymium magnets and two Hall effect sensors. Its principle of operation is the same as with other incremental encoders, the sensors are oriented so that their signals have a phase difference. In theory we could get better resolution by using the full resolution of the sensors' output, instead of treating them as binary, but I haven't done that. The resolution I got is determined by the number of magnets (48).

I designed the case for the device in Fusion 360 and 3D printed it. The dial sits on a 6806 ZZ bearing and has a very satisfying feel. Here's what it looked like during assembly.

For the microcontroller I chose the Adafruit QT Py RP2040, it's small and uses the RP2040 chip from Raspberry Pi (it has a similar form factor to Seeed Studio's XIAO RP2040).

Since we're talking about Microsoft, I half-expected the Surface Dial's protocol to be some proprietary nonsense that would require reverse engineering to replicate. Imagine my surprise when I found out that it's actually standard HID and there's proper documentation for it. All you have to do is put the right stuff in the HID report descriptor and it works similarly to a regular USB mouse or keyboard.

I put all the code and 3D-printable files on GitHub, along with a list of components used and instructions how to put them together.

1 comment:

  1. Hey, your blog's awesome and you're really inventive!
    Also I love how you casually just drop two or three finished original prototypes in a single blog entry, lol.
    Found you from github, your mouse designs are very cool!