Measuring WS2812b Frame Rates with an Oscilloscope

As a part of trying to speed up the animation on my antenna, which uses 1800 addressable WS2812b-type LEDs, I’m trying a bunch of experiments. I wanted to figure out a reliable way to measure the actual frame rate I’m getting (i.e., updates per second).

My first, janky idea was just to measure things with a stopwatch, but that felt kind of primitive. I was pretty sure that I couldn’t use the clock on the controller, because I thought a lot of WS2812b libraries might be disabling interrupts and interfere with the real-time clock.

The idea I came up with was using an oscilloscope.

To do this I just found an unused pin, and pulsed it right before I called FastLED.show():

  ...

  digitalWrite(10, HIGH);
  delay(1);
  digitalWrite(10, LOW);
  
  FastLED.show();

That was the easiest thing ever. The oscilloscope did all the calculations for me and measured the frequency perfectly. Here you can see that with 1800 LEDs, I’m getting an actual refresh rate of 16.9 Hz.

(The WS2812b protocol takes 30μs per pixel, 1800 pixels should take about 54ms to send. As you can see from the screen grab, it actually took 59.18ms when you factor in all my other code).

Just to make sure I’m not insane, while still using the Feather M4, I modified the code to send 450 pixels instead of 1800:

Now I’m getting a frame rate above 61 Hz, which is very respectable.

Finally I tried the hardware that looks the best right now: Teensy 3.2 + OctoWS2811 using the FastLED library. Even pushing 450 pixels through all 8 strands, I get an even better frame rate of 72 Hz, which is almost exactly the theoretical limit of the WS2812b. If you want a 60 Hz refresh rate, you can put 550 LEDs on each strip for a total of 4400 pixels per Teensy 3.2.