APA102C LED strip at 28 MHz clock

I recently received 1m of APA102C led strip with 144 leds per meter. I want to use the strip for rotary POV display so I cut the strip in half and tested the performance with a STM32L476RGT nucleo board. The results of the tests are surprising and very promising for my application.

The APA102C LEDs are very similar to WS2812 (or “NeoPixels”). They are RGB, individually addressable and take an 8-bit value for setting each color. However, the key difference between said two is the additional CLOCK line on the APA102C strip. The clock line makes setting values much easier, more flexible and also much faster. Instead of trying to write a code to match the timing for WS2812 LEDs, clock on APA102C LEDs can be set to almost anything.

Data protocol

A diagram explaining how to transmit data is shown bellow.

APA102C data protocol

APA102C data protocol

The LEDs take 8 bit values for PWM dimming for each color and a 5 bit value for analog dimming of all the colors at once (setting the LED drive current). There were some miseries what’s the purpose of end bytes and they were solved on this blog. It turned out that each LED in a chain inverts the clock and thus delays it for a half of a period. This enables the shift-register in the LEDs to work correctly. The downside of this simple solution is that the end of the transmission requires some additional clock cycles (number of LEDs in a string divided by 2).

APA102C strip

LEDs have data/clock input and output. The image below shows how the LEDs are wired in a chain.

APA102C strip

APA102C strip

Electrical connection of the strip

Two APA102C LED strips

Two APA102C LED strips

The strips take 5 V and about 8 A/m maximum current (for the 144 LEDS/m). I placed some decoupling capacitors next to strip connectors because there are none on the strip. 10 uF and 100 nF combo should decouple any high frequency noise nicely and keep the 5 V rail clean for other components. Data and clock are directly connected to the MCU.


At first I generated source code with STM32CubeMX and then I wrote a short code that generates an array of bytes to be sent. The total transmission with 72 LEDs has 296 bytes.

I tested with various clocks. The problems started occurring at 30 MHz when the last LEDs started flickering. 28 MHz seemed like a limit for 72 leds in a chain. At 40 MHz clock only the first ten lighted up, later ten flickered and the rest was turned off. I couldn’t test much further since the STM32 I was using ran on 84 MHz maximum internal clock. With 28 MHz clock on LEDs and 296 * 8 = 2368 bits to send the maximum theoretically possible refresh rate is astonishing 11.8 kHz. Almost twice as my design requirement for the POV project.


Last LED (72th) flickering at 30 MHz

LEDs flickering at 40 MHz

I also tested the maximum refresh rate I could get from my STM32 Nucleo board. Each loop, the MCU generated a new data array with a slightly different color setting for all LEDs. The result was a color fading effect that ran at once again astonishing 6.5 kHz. Also note that DMA could be implemented to make computing data arrays and transmitting data to the LEDs run parallel. With such implementation the refresh rate could come very near the absolute theoretically possible value (11.8 kHz).


  1. Tom says:

    I like your test you did here…
    Have you tied to add a capacitor at the end of the line?
    I have the feeling the the supply voltage is in trouble at the end if the line…
    if your are still working on that let me know if it helps 🙂

    • Gal says:


      I added huge low ESR tantalum capacitor at the end of the line and it didn’t make any difference.