Streaming frames over USB


#1

Does the firmware support streaming frames over USB?

I can set single frames, but there is a minimum 20ms delay between calls. For POV applications there is a flickering effect (seems to turn the leds off during frame transistions).

I would like to send a stream of frames, and have the firmware set them as fast as I send them.

This would maybe require a special streaming mode that keeps the USB port open? It would allow treating the blinkstick like a graphics pipeline, with the client managing effects like blinking, morphing, etc. A configurable vsync would be nice, too …


#2

There’s a very good chance I don’t have the foggiest idea what I’m talking about here, but

as I understand it the 20ms wait exists because the Blinkstick can only receive commands, or send them, it can’t do both at once. The 20ms is how long it takes to communicate with the LEDs before returning for more commands.


#3

I have not looked at the firmware code yet, but I suspect you are right - the call stack is stateless. This is perfect for notifications (which is the primary use case for Blinkstick), but not for frame streaming.

For streaming, a firmware session mode would have to be implemented that keeps the USB port open upon connect(), and allows a continual stream of frames to be received and set until close() is received.

The AT chip is pretty fast and can maintain fairly high USB speeds and LED framerates. Is it the reinitialisation of the call stack for every command that is slow?

I don’t mind looking at the firmware and writing the session code, but someone with an AT flasher would have to test it (usual Github workflow).


#4

Streaming won’t work. 20 ms timeout exists for BlinkStick to send data to LEDs from RAM. It must be precisely timed otherwise LEDs will go into reset and mess up the transmission. When data is sent to LEDs, all USB communication is disabled to avoid that too.


#6

I just created a pull request in blinkstick-node that provides stateless 60fps streaming examples that can be easily adapted to any POV application. For use with Flex and Pro (see code comments) on Windows, Linux and Mac.

The 20ms timeout recommended for the BlickStick stateless callstack is actually very close to 60fps already, and I was able to push it to a stable 16ms (1000ms/60).

The result of this experiment is that the BlinkStick firmware and the WS281x circuitry proves to already handle POV streaming speeds!

The caveat is the quality of the physical LEDs users might attach to the BlinkStick. Some brands of LEDs (like on my cheap discount strip) are not able to switch colours fast enough, resulting in blur above a given framerate. This is equivalent to pixel response times on displays and varies by make and model.

Please see the examples (based on flex_stream.js) for a demonstration.

CPU usage is very low, even at 60fps which leaves plenty of room for real POV applications.

Tested with 8 LEDs at 60fps/16ms, resulting in some colour blur. So, lower framerates can be preferable. 30fps/32ms looked great and is still POV.

Future optimizations in the firmware may further improve fps, but 60fps is already too fast for many current LED brands’ color switching response times.


#7

Added to the pull request a CPU meter example (Desktop PC case lighting mod) based on flex_stream.

Also included a clean exit that turns off the LEDs, and an improved stream buffer for the base flex_stream.


#8

Also added an ambilight example (Desktop monitor ambient lighting mod) based on flex_stream.

Also refactored flex_stream as a module and added frame morphing.


#9

Added some simulations (fireplace, aurora, etc).


#10

Added flex stream webserver.
Added image notifiers.


#11

Added streaming support for RGB matrix displays.
Sizes of up to 8x8 (64 LEDs)
Assumes normal rasterization.


#12

Migrated development to NPM.


#13

Very good work Dominic! :+1: