Controlling WS2812 Tricolor LEDs (aka NeoPixels), Part 3

A look at pulse-width modulation and how it controls the brightness and color of LEDs.

8 Min Read
LEDs max 0028 featured image balls and leds
Image courtesy of Clive "Max" Maxfield

Hi there, and welcome to Part 3 of this soon-to-be-heralded mega-mini-series. In Part 1, we discussed the first vacuum tube diodes, moved on to their solid-state (semiconductor) descendants, and then progressed to their light-emitting cousins. In Part 2, we introduced the concepts of forward voltage drop (VF) and maximum forward current (IF), current-limiting resistors, and different ways to control discrete (individually packaged) LEDs using switches and microcontrollers (MCUs). Now it’s time to hold onto our hats because things are about to get exciting—only thrill-seekers should proceed beyond this point!

As we discussed in my previous column, and as illustrated in the upper part of the diagram below, one very common scenario is to connect the LED’s anode terminal to one of the microcontroller’s digital outputs and to connect its cathode to ground. In this case, driving the pin HIGH (let’s assume 5V) will turn the LED on, while driving the pin LOW (0V) will turn it off because there will be no electrical potential across its terminals.

LEDs max-0028-fig-01.png

An alternative arrangement, as illustrated in the lower part of the diagram above, is to connect the LED’s cathode terminal to one of the microcontroller’s digital outputs and to connect its anode to the positive power supply (assume 5V). In this case, driving the pin HIGH will turn the LED off, while driving the pin LOW (i.e., 0V) will turn it on.

The reason we are revisiting this topic here is that there’s a third way in which we can use the microcontroller to drive the LED, which is to use two of its pins. Just for giggles and grins, let’s assume we have two LEDs, one red and one yellow, both having the same forward voltage drop. Let’s further assume that we wish to have only one (or none) of these LEDs on at any particular time; that is, we never wish to have them both on together. And, just to tie one of our hands behind our backs (metaphorically speaking), let’s say that (a) we have only one current-limiting resistor and (b) the boss wants to see something working PDQ (“pretty darned quick”), as my dear old mom used to say. Taking all of this into account, we might come up with something like the following:

LEDs max-0028-fig-02.png

Remember that a LED will conduct electricity in only one direction, and that it will emit light only when it’s conducting. Thus, driving one of the microcontroller’s pins HIGH and the other LOW will light one of the LEDs while turning the other off. If both of the microcontroller’s pins are HIGH or LOW, then both LEDs will be off. Pretty nifty, eh?

Now, suppose we decide that we want to control the brightness of a LED. It is possible to do this by varying its supply voltage and current but—in addition to being complicated—the term “linear” is not one that we would apply to the result. A better approach is to turn the LED on and off very quickly using a technique known as pulse-width modulation (PWM).

Microcontrollers almost invariably include hard PWM functions associated with a selection of their pins. (By “hard” we mean these functions are implemented in the silicon, as opposed to realizing them in software in a process known as “bit banging.”) Different microcontroller PWMs have different numbers of bits. In the case of an Arduino Uno, for example, the PWMs are each 8-bits in size, which means they can represent 2^8 = 256 different values numbered from 0 to 255.

PWM finds all sorts of applications of which controlling the brightness of LEDs is only one. The way to visualize this is as an endless string of cycles, where each cycle is divided into 256 “time slices.” In the case of an Arduino, we use the analogWrite() command, which accepts two parameters: the first is the pin to be controlled, while the second is the PWM value ranging from 0 to 255.

LEDs max-0028-fig-03.png

The term “duty cycle” (aka “power cycle”) refers to the ratio of time a circuit is on compared with the time that circuit is off. This ratio is typically expressed as the percentage of on-time. In the case of our LED, a PWM value of 0 corresponds to a duty cycle of 0%, which means the LED is fully off. A PWM value of 85 corresponds to a duty cycle of 33%, which means the LED is on for 1/3 of the time. A PWM value of 170 corresponds to a duty cycle of 66%, which means the LED is on for 2/3 of the time. And a PWM value of 255 corresponds to a duty cycle of 100%, which means the LED is fully on.

It's important to realize that the cycle time is fast in the grand scheme of things. Depending on the microcontroller, the frequency of its PWM signals will be hundreds or thousands of hertz (cycles per second). This means that our biological eyes don’t perceive any flickering because the LED is turning on and off so quickly.

It’s possible to purchase a variety of bicolor (two-color) LEDs, but things really start to get fun when we move to tricolor (three-color) devices containing red, green, and blue (RGB) sub-LEDs.

LEDs max-0028-fig-04.png

The device illustrated above employs a common cathode, but common anode versions are also available. This type of tricolor LED will require three of our microcontroller’s pins to drive the three anodes, and each anode will require its own current-limiting resistor (these may need to be different values; check the datasheet for the forward voltage drops of each of the sub-LEDs).

When you were a kid playing at painting, your teachers told you that there are three primary colors: red, yellow, and blue (RYB). They may have mentioned that the reason these three hues are called “primary” is because they cannot be made with mixtures of other pigments. They will also have demonstrated how mixing red and yellow gives orange, mixing yellow and blue gives green, and so forth.

The way to think about this is that paints and pigments are “subtractive.” If you illuminate them with white light, which is composed of all the visible frequencies, they absorb some of these frequencies (subtracting them from the white light) while reflecting others, and it’s the reflected frequencies that we see. When we mix multiple pigments, they each subtract their own frequencies, and what we see is what’s left over. If we mix all of the subtractive primary colors together, they absorb all of the frequencies, and we end up with black.

In fact, any group of three (or more) colors can be used to define a “color space.” Printers use cyan, magenta, and yellow (CMY). If we mix all of these together, we do get black, but it’s a sort of “muddy” black, so printers also use a cunningly concocted crisp black pigment, which they abbreviate as ‘K’ (we can’t use ‘B’ because that could be confused with ‘B’ for blue). This is why we talk about a “CMYK” color palette in the context of printing.

LEDs max-0028-fig-05.png

By comparison, light is “additive,” which means that each new color adds something to the mix and adding all of the RGB light primaries results in white light. The way I like to visualize this is as shown above. In the case of paints and pigments, we start with a white space and subtract color components from this space. Contrariwise, in the case of light, I imagine starting in a dark room and then turning on different colored spotlights.

If you look closely at your color computer monitor—possibly with the aid of a magnifying glass—you’ll see that each pixel (“picture element”) is composed of RGB sub-pixels. Varying the brightness of the sub-pixels gives us the different colors. Without the aid of magnification, our eyes don’t have sufficient resolution to see the individual sub-pixels, so—as far as we’re concerned—all of their light mixes together. Exactly the same thing happens with our tricolor LED. Although the package itself is rather large, the sub-LEDs inside are mounted really close together, which means we perceive their light as being mixed together.

Take a look at the image below. If all we can do is turn each LED hard on or off, then this gives us 2^3 = 8 possible color combinations (including all off = black). By comparison, if we can use 8-bit PWMs to control the brightness of each sub-LED, then this gives us 2^8 x 2^8 x 2^8 = 2^24 = 16,777,216 possible color combinations, which is one of the reasons today’s computer screens and televisions look so awesome.

LEDs max-0028-fig-06.png

Once again, I’m afraid this is all we have time for in this column. However, we’ve now laid the foundation for what is to come. In my next column, we will finally start to wrestle with WS2812 Tricolor LEDs (aka NeoPixels). Until that frabjous day, as always, I welcome your comments, questions, and suggestions.

About the Author(s)

Clive 'Max' Maxfield

Clive "Max" Maxfield is a freelance technical consultant and writer. Max received his BSc in Control Engineering in 1980 from Sheffield Hallam University, England and began his career as a designer of central processing units (CPUs) for mainframe computers. Over the years, Max has designed everything from silicon chips to circuit boards and from brainwave amplifiers to Steampunk Prognostication Engines (don't ask). He has also been at the forefront of Electronic Design Automation (EDA) for more than 35 years.

Well-known throughout the embedded, electronics, semiconductor, and EDA industries, Max has presented papers at numerous technical conferences around the world, including North and South America, Europe, India, China, Korea, and Taiwan. He has given keynote presentations at the PCB West conference in the USA and the FPGA Forum in Norway. He's also been invited to give guest lectures at several universities in the US and at Oslo University in Norway. In 2001, Max "shared the stage" at a conference in Hawaii with former Speaker of the House, "Newt" Gingrich.

Max is the author and/or co-author of a number of books, including Designus Maximus Unleashed (banned in Alabama), Bebop to the Boolean Boogie (An Unconventional Guide to Electronics), EDA: Where Electronics Begins, FPGAs: Instant Access, and How Computers Do Math.

Sign up for the Design News Daily newsletter.

You May Also Like