CC Blog Design Solutions Research & Design Hub

The Analog Side of PWM LEDs

Written by Ed Nisley

Ed shows the surprising current waveforms drawn by what seems to be a trivially simple LED Mood Light. He explains how Neopixels work and presents the large current pulses produced by their PWM controllers.

  • How to understand how Neopixels work
  • How to use Neopixels for distributed PWM control
  • Why Neopixels may produce unexpected problems in your projects.
  • How to build a  mood light using four sections of high-density Neopixel strips
  • Adafruit Neopixel RGB LEDs
  • Worldsemi’s WS2812B LED Controller

Sophi’s most recent Burning Man installation featured a pair of Mythical Talking Unicorns outlined in rainbow hues produced by several hundred Adafruit Neopixel RGB LEDs, plus wireless radios and speakers, all powered by buck-mode voltage converters and AGM lead-acid batteries. She used battery protection circuits to prevent over-discharge, but discovered, just before packing the Unicorns in their shipping container, that the disconnect relays began chattering long before the battery voltage reached the lockout setpoint.

She removed the protection circuits and monitored the battery condition using open-chest Unicorn surgery out on the playa. After she returned, a pencil-and-paper session at Squidwrench showed the Neopixel strips would draw a peak current high enough to trigger the protection circuit, but with pulses so short that the relays didn’t lock out.

In this column I’ll explain how Neopixels work and show the surprising current pulses produced by their PWM controllers. It turns out that just a few Neopixels can overload a seemingly adequate power supply. Conversely, when you keep them well-fed, they can produce magical results.

Although an LED’s brightness depends more-or-less linearly on its forward current, the most power-efficient way to control the brightness uses pulse-width modulation to set the duty cycle. The LED conducts its rated forward current during the ON part of the cycle and is completely OFF during the remainder, with human vision integrating the flickers into an intensity proportional to the ON time.

As you’ve seen in previous columns, the Atmel ATmega microcontroller’s timer hardware can produce the PWM signals required for LED brightness control. Each Arduino board has only six PWM outputs and can therefore directly control only two independent red-green-blue LEDs. Beautifying a Unicorn doesn’t require much computation, but definitely requires LEDs of a different nature.

Adafruit Neopixel RGB LEDs use distributed brightness control, with a WS2812B PWM LED controller in each RGB LED package. The controller regulates the three LED currents to about 20 mA each and produces a 400 Hz PWM signal for each color based on the value of three byes received over a single-wire serial data connection. One Arduino can therefore set the color of each Neopixel separately, without the need to generate PWM timing pulses: a single digital output pin can control hundreds of RGB LEDs.


Advertise Here

Photo 1 shows an Adafruit Neopixel Jewel connected to a knockoff Arduino UNO controller, with a Tektronix Hall-effect probe measuring the Jewel’s supply current. Neopixels require a 5 V power supply, which, in this case, comes directly from the USB port near the top of the picture. In addition to the seven 5050-size RGB LEDs, the Jewel PCB includes four 1 µF ceramic capacitors across the power supply and a 470 Ω damping resistor on the data input line.

The code in Listing 1 sets each of the seven Neopixels to a different color. The WS2812B serial interface transmits data using a self-clocking 800 kHz NRZ format with tight timing requirements, so Adafruit’s Arduino library creates an in-RAM copy of the PWM values and sends the entire buffer to the Neopixel string in a single operation.

Listing 1
The Adafruit library routines manipulate an in-memory buffer of RGB data for the Neopixel string, then send the entire buffer in one operation. This routine sets the colors of the Jewel in Photo 1, with the value of MaxPWM limiting the brightness to prevent overexposing the image.

Adafruit_NeoPixel strip = Adafruit_NeoPixel(7, PIN, NEO_GRB + NEO_KHZ800);

byte MaxPWM = 16;

for (int i=1; i<7; i++)
  strip.setPixelColor(i,strip.Color((i&0x04) ? MaxPWM : 0,
                                    (i&0x02) ? MaxPWM : 0,
                                    (i&0x01) ? MaxPWM : 0));;

Each WS2812B controller stores the 3 bytes of PWM data required for its RGB LEDs from the first 24 bits it receives, then retransmits all subsequent bits to the next controller in series: the first Neopixel receives all the data and the last one gets only the final 24 bits. When the Arduino output pin goes low after sending the entire buffer, successive Neopixels propagate that signal down the string and all the controllers reset to await the next transmission. As a result, although the Arduino can control the colors of each Neopixel, it cannot address a Neopixel without sending all of the data for the packages preceding it in the string.

The Adafruit library routine handling the data transmission depends on truly gnarly assembly language hacks that I’m glad I didn’t have to figure out. However, because the Arduino does not refresh the Neopixels after sending the data, the PWM-controlled LEDs impose no further timing requirements on the user program.

The first line in Listing 1 defines a RAM buffer of 7 × 3 = 21 bytes for the PWM data used by the Neopixel Jewel in Photo 1, along with a handful of additional data that describes the string configuration. While two dozen bytes doesn’t sound like much, the ATmega328 has only 2 kB of RAM, with about half of that devoted to Arduino runtime routines and the rest available for user program data. A large-scale Neopixel project will require the 8 KB of RAM found in the Arduino Mega2650.

Adafruit offers Neopixels containing the usual RGB trio plus a separate white LED for better pastel colors. The SK6812 controller in that package uses the same serial NRZ data format as the WS2812B, but requires four data bytes in RAM for each RGBW Neopixel. The Adafruit library includes configuration options for that variation, as well as for older Neopixels with WS2811 controllers that used a 400 kHz data rate. The configuration options must match the actual hardware, because the PWM controllers do not provide any status or configuration outputs.

Now that you understand what makes Neopixels so attractive, I can explain why they may produce unexpected problems in your projects.

Photo 2 shows the current drawn by the first Neopixel on the Jewel PCB with its RGB LEDs set to PWM values of 128, 64, and 32, with a vertical scale of 10 mA/div. The 8 mA baseline shows that the seven WS2812B controllers each draw about 1 mA with their LEDs turned off. The size of the vertical steps shows this controller regulates its LED currents to 18 mA each, for a total of 55 mA including the controller current.

Photo 2
This current trace at 10 mA/div shows a single Jewel Neopixel set to RGB = (128,64,32). The internal WS2812B controller produces the nominal 400 Hz PWM frequency; this one runs at 388 Hz. The total LED current for this package is 55 mA, just under the nominal 20 mA/LED. Each controller draws about 1 mA, so the Jewel’s baseline current with all LEDs dark is 8 mA.

The red LED’s 128/255 PWM setting produces a 1.2 ms pulse, so the complete PWM period will be 2.4 ms. The 2.55 ms pulse repetition rate shows that the WS2812B controller imposes a 150 µs “dark” interval, even with the LEDs set to maximum brightness: PWM 255 produces 94% of the light you might expect.


Advertise Here

Note that the peak current depends only on the number of LEDs turned on, not their brightness. Although the average current varies directly with the average brightness, the power supply must provide the total current required by all the active LEDs in all the packages.

Because the internal oscillators in the WS2812B controllers aren’t synchronized, they operate at slightly different frequencies and their PWM pulses drift with respect to each other. The 40 mA spike (at 10 mA/div) in Photo 3 occurred when the two pulses from the separate Neopixels overlapped, and, after 2.5 ms, the same two LEDs produce a pair of 20 mA pulses.

Photo 3
The peak current for each of two Neopixels, both set to a dim red RGB = (16,0,0), will be 20 mA (10 mA/div). Because the WS2812B controller oscillators aren’t synchronized, the total current will be 40 mA when the PWM pulses overlap and 20 mA when they drift apart.

The WS2812B datasheet doesn’t give many details and, in particular, doesn’t specify the oscillator frequency tolerance, but you can depend on the lack of synchronization to produce wild variation in peak currents and waveform shapes.

Photo 4 shows the total current (at 100 mA/div) for the Jewel with all seven Neopixels set to a dim white: PWM 64 for all 21 RGB LEDs. Based on the measurements you’ve seen so far, that brightness should produce an average current of:

Photo 4
Setting all seven Neopixels to RGB = (64,64,64) produces a blocky current waveform (100 mA/div) when the WS2812B PWM waveforms don’t coincide. Narrow spikes occur when the current changes in several packages at nearly the same time.

The eyeballometric waveform average looks like 80 mA, which is definitely in the right ballpark. The pair of 180 mA peaks comes from three simultaneously active Neopixels and the minimum occurs when all 21 LEDs are off.

Even though each Neopixel draws 55 mA in 600 µs pulses, there’s only place where the current remains constant for that duration. Conversely, even though individual Neopixels draw only 1 mA for almost 2 ms, the total current drops to nearly zero in only two pulses of about 200 µs apiece.

When you look carefully, you’ll spot two downward spikes and one upward spike, each occurring when a pair of Neopixels changes state at almost the same time. If your design includes analog circuitry that depends on a quiet power supply, those spikes could indicate trouble ahead.

With the pulses from seven WS2812B controllers all drifting with respect to each other, you might expect the overall waveform to look pretty much like Photo 4 all the time. Photo 5, taken a few minutes before Photo 4, should convince you otherwise.

Photo 5 
The same Neopixel configuration as in Photo 4 draws 400 mA (100 mA/div) when all seven PWM waveforms overlap and drops to nearly zero in between. Each Neopixel contributes a 60 mA pulse with a width of 500 µs to the total current.

Unlike Photo 4, the 600 µs PWM pulses from all seven Neopixels now occur within 1 m. The 400 mA peaks show that all 21 LEDs turned on simultaneously and the broad floors indicates that they were all off for nearly 1.7 ms. Although the average value of that waveform hasn’t changed, because the LED brightness hasn’t changed, those large 400 Hz pulses put entirely different demands on the power supply than the relatively smooth and high-frequency waveform in Photo 4.

Nearly all of my Arduino projects draw power from a wall-wart supply and have discrete regulators, because Arduino on-board regulators have very little current available for external circuits. In addition, the analog circuitry you’ve seen in previous columns benefits from a separate power regulator to isolate low-level signals from the microcontroller’s digital noise. With that in mind, Photo 1 shows the second-worst way of powering a Neopixel string: directly from the Arduino’s VCC pin, with a USB port powering the whole thing.

The top trace in Photo 6 shows a Neopixel current waveform similar to Photo 5 with a vertical scale of 200 mA/div. The lower trace shows the voltage on the Arduino VCC pin at 200 mV/div, with AC coupling to remove the 5 V DC level. The supply voltage drops 250 mV when the Neopixels draw 350 mA, which could be due to ohmic losses between the power supply in the laptop and the Arduino header pins feeding the Jewel.

Photo 6
A Neopixel Jewel can draw nearly 400 mA (200 mA/div) from an Arduino UNO’s VCC pin and cause a severe voltage drop on the power supply. A program reading analog inputs or producing analog outputs will probably malfunction in mysterious ways

In round numbers, the total resistance is:

That resistance would be distributed along the supply and common wires, contacts, and conductors.

However, USB 2.0 ports limit the maximum output current to 500 mA, with a voltage between 5.25 V and 4.75 V at the port, so some of that voltage drop could occur inside the laptop, before the current reaches the cable.

Homework: Measure the supply voltage along the wiring of your own project, starting at the USB port and working outward, then determine what causes each voltage drop.


Advertise Here

The ADC in ATmega microcontrollers measures analog voltages in proportion to the reference voltage at the AREF pin. The default Arduino configuration connects AREF to VCC, so the value returned by the ADC circuitry will increase as AREF decreases along with the VCC voltage. If your project depends on accurate analog measurements, you must stabilize the AREF voltage, which means providing a stable VCC. In general, that requires powering the Arduino board from an external supply, not the USB port, to enable the on-board regulator.

What’s the worst way to power a bunch of Neopixels? A single Jewel requires far more peak current than an Arduino’s on-board regulator can deliver: overloading that regulator will produce immediate power-supply problems. Plan on using an off-board regulated power supply for even small, seemingly simple projects.

Adafruit offers Neopixel in strips with densities of 30, 60, and 144 Neopixels per meter, plus various sizes of LED rings and rectangular arrays. Alas, combining the one-wire simplicity of Neopixel control with the convenience of deploying large numbers of LEDs can produce disconcerting results, as Sophi discovered with the hundreds of Neopixels lighting up her Unicorns.

Pop Quiz: Compute the peak current required by 3 m of each Neopixel strip.

Bonus: Do the same for one 16 × 16 rectangular array.

Although it’s not on the scale of Sophi’s artwork, I recently built the Mood Light shown in Photo 7 using four sections of high-density Neopixel strip mounted around a 3-D printed hub, amid mirror-finished platters harvested from defunct hard drives. An Arduino Pro Mini in the base sends slowly varying sinusoidal intensities to the 12 Neopixels, with a maximum PWM value of 128 producing enough light for a dim room.

Photo 7
Mounting four high-density Neopixel strips on a 3-D printed structure, adding platters from discarded hard drives, and generating sine-wave intensity values with an Arduino Pro Mini controller produces a Mood Light with ever-changing colors. The twelve Neopixels require nearly 750 mA peak, even with their brightness turned down for a dark room.

As you’ve seen, the peak LED current can reach 750 mA, far more than the Pro Mini’s regulator can supply and, perhaps, more than you’d expect for a project involving “only a dozen LEDs.” The Neopixel power comes directly from a switching power supply wall wart rated at 5 V and 1 A, with a 680 µF capacitor on the power jack in the base. The Arduino board has only three connections: two power leads and the Neopixel data line.

That’s the compelling advantage Neopixels bring to projects like this: most of your design effort goes into the mechanical package, rather than complex PWM drivers or LED multiplexing.

Neopixels obviously aren’t the solution for all LED problems, but they can add a dash of color without a tangle of circuitry. That simplicity can happen only when you take care of the analog basics, so build the power supply first! 

S. Kravitz, “Loquacious and Lovely, Mythical Talking Unicorns,” 2015,
E. Nisley, “Hard Drive Platter Mood Light: First Light!,” 2015,
———, “Improved Arduino PWM MOSFET Gate Drive,” Circuit Cellar 290, 2014.
———, “Pulsed LED Characterization,” Circuit Cellar 278, 2013.
———, “Random LED Dots,” Circuit Cellar 302, 2015.
Worldsemi, “WS2812B Intelligent control LED integrated light source,”

Neopixel 144 RGB LED Strip and Neopixel Jewel
Adafruit Industries | |
WS2812B LED Controller
Worldsemi Co. | |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the May 2020 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
EE and Author at Poughkeepsie, NY | + posts

Ed Nisley is an EE and author in Poughkeepsie, NY. Contact him at [email protected] with “Circuit Cellar” in the subject line to avoid spam filters.

Supporting Companies


Upcoming Events

Copyright © 2021 KCK Media Corp.

The Analog Side of PWM LEDs

by Ed Nisley time to read: 11 min