Sunday, March 12, 2023

The display, and the saga of the recalcitrant USB

I have been refactoring the display code quite extensively, as I mentioned before. Well so now I have support for an "adjustment knob" that acts as a USB HID device, and I'm using the Adafruit Rotary Trinkey for its compactness (even though any USB "volume and play/pause" product would work too).

The current thrown-together prototype of this setup looks like this:

The idea is that the little controller sits inline on the USB cord powering the RPi and also acts as its USB peripheral. This means that the USB-A socket on the RPi acts as both a Downward Facing Port (to connect to its USB HID peripheral) and an Upward Facing Port (to receive power). This is not "legal" except with USB-C and USB-PD, but luckily, the RPi just connects its +5V rail directly to the USB VBUS and so it doesn't know the difference.

Luckily, I say....

Now the problem was, when the whole thing is powered up all at once, the RPi would not connect properly to the USB peripheral. It would see it, and produce the correct device files in /dev/input/, but no Linux input events would show up. The only way to get things to work was to:

  • Turn on the RPi;then
  • Connect the USB HID peripheral.

As you might imagine, this is not the nicest UX. I tried and tried. I posted on forums. I debugged like the wind. Oh my gosh this soaked up so much freaking time. And eventually I realized, this is just not going to get solved. There are rumblings that this may be a problem with the SAMD series of processors and their hardware USB implementation, but this is not going to help anyone.

My first cut was to use a 555 timer to make a delayed power-on circuit. This was valuable simply because it taught me how to make 555 circuits; I had never done that before (imagine that!). Also, when setting the RC values for the delay, I ended up choosing "impossibly" high resistor values, meaning that I could not even measure the behavior of my circuit because my multimeter would interfere with it! Lesson learned; welcome to the real world. I ended up with something that would actually turn on the USB peripheral after about 10 seconds, using a reed relay:

This is great except -- it did not work. Why I have no idea. but it was time to cut my losses, and so I just added a switch to my "controller" module. The user can just turn it on after the display, and we can hope for the best.

The result, anyway, is that now we have something where all the settings are available using a multi-function knob. Check out this video on the bench:

and this one on a bumpy flight where my poor wife Melissa got airsick, but was a total trooper and continued to work as the test flight engineer while I kept the greasy side of the plane pointed downward:

This is probably as far as I'm going to go with the RPi 3A+ for my displays. I'm told that RPi CM4's are going to be available again soon. Compared to the heartache and pain of dealing with all this nonsense, I'm sure I could build a CM4 carrier board without too much trouble. Stay tuned for that. If / when I do, it will be super compact and wonderful!

No comments :

Post a Comment