Streaming Video to Teensy 4 with Fadecandy Server - 10k LEDs at 60FPS

I’m in the process of adding the Teensy 4 as a USB device in Fadecandy Server, and have some great results to show. Fadecandy Server easily handles pushing pixels for a 128x64 display at 60FPS to the Teensy 4, while the Teensy 4 is refreshing a HUB75 panel using the SmartLED Shield.

A little background: “Fadecandy is a tool for creating interactive light art using addressable LED lighting” designed by Micah Elizabeth Scott (scanlime), and was made to drive WS2811 “Neopixel” addressable LEDs over USB with higher color depth and smoother interpolation than they normally have. I’m a fan of the high quality fades and colors that can be made with Fadecandy, and don’t know of a better open-source cross-platform tool for driving LEDs over USB. The Fadecandy Controller design was based on the Teensy 3.0, and could handle up to 512 WS2811 pixels per controller, scaling to much larger installations with multiple controllers. I ported the Fadecandy Controller firmware to drive HUB75 panels with the SmartMatrix Library on larger Teensy 3 models, and used it for displays as large as 64x32 (2048 pixels), with the Full Speed USB bandwidth being the limiting factor for frame update rate. The Teensy 4 has High Speed USB with a lot more bandwidth (one benchmark I saw said 3.5MB/s from PC to Teensy), so I was excited to see how large of a display could be refreshed with Fadecandy Server driving the Teensy 4.

I added Teensy 4 support specifically to drive HUB75 panels or APA102 LEDs using the SmartLED Shield for Teensy 4, but the modifications I’m making to Fadecandy Server can be used for other applications. I believe Paul’s OctoWS2811 library update for Teensy 4 supports driving more than 8 strips of LEDs in parallel, and may only be limited by RAM and the number of pins on the Teensy 4, so some of the pieces are in place for a “Fadecandy Controller 2.0” if anyone wants to work on that.

Some technical details: I ended up just using the Teensy USB Serial driver and writing the framebuffer to the serial port using fstream. I originally wanted to use the efficient custom USB driver that Micah wrote for the microcontroller family used on the Teensy 3, but it seemed like too much work to port that to the Teensy 4, and would probably involve modifying Teensyduino which I didn’t want to do. I then wanted to use libusb to write data to the USB Serial device, but at least on the Mac the default serial port driver was claiming the device and libusb couldn’t get access. Writing to a COM port seemed like a last resort, as Fadecandy elegantly identifies USB devices by their serial number so hot swapping devices works really well, and using COM ports by name would likely break that. I then found libusbp which can return the port name of a device given its serial number, which seemed like a roundabout but decent way to identify the device by serial number and connect via port name.

The code isn’t ready to share yet as it’s been hacked together over a 24 hour session. If anyone wants to help out with some of the remaining pieces that aren’t in my area of expertise, I’d be happy to put it up on GitHub before it’s 100% polished and ready to go. Specifically I could use help with compiling in libusbp (Fadecandy uses CMake), and making sure things work on other platforms (I only tested on MacOS Catalina). Please let me know!

1 Like