Making Electronic Candles

Electronic candles are common in restaurants and bars these days, and they’re usually pretty low-fidelity representations of the behavior of real candles. It’s possible to make them with more complex behaviors, and it’s a good way to learn about programmable LEDs. What follows is an introduction to programmable LEDs, using electronic candle-making as an application through which to learn. In the process, you’ll learn a bit about how colors are reproduced using LEDs and computation, and hopefully a few things about diffusion and reflection as well.

What You Need to Know

In order to make the most of this tutorial, you should know what a microcontroller is, what the Arduino microcontroller programming environment is, and how to use it, at least at a beginning level. You should download and install the Arduino IDE on your computer to follow along with the programming below. The ITP Intro to Physical Computing Topics and Video Links offer helpful background if you’re new to electronics and microcontrollers.

Equipment You’ll Need

To follow along with this tutorial, you’ll need:

Solderless breadboard Hookup wires MKRZero
Solderless Breadboard hook-up wire Arduino microcontroller module
LED Ring microUSB cable
Programmable LED ring or module USB cable
  • an Arduino-compatible microcontroller. The MKRZero is used below, but everything you’ll see here works on all models.
  • a personal computer with the Arduino software installed.
  • a set of WorldSemi programmable LEDs, the WS2812/SK6812 types. You can buy these from many retailers. Adafruit’s NeoPixel line are all compatible, as are Arduino’s RGB Smart Pixel rings, SparkFun’s LilyPad Pixel Board Seeedstudio’s WS2812 offerings,  and many others.
  • A solderless breadboard, some jumper wires, and a USB cable to match your Arduino
  • Some material for diffusing and reflecting the light: paper, cloth, glass, plastic, whatever strikes your fancy.

Candle Flames and Artificial Sources

If you watch a candle flame over time, you’ll see many colors in it: pale yellow-orange in the tip, fading to orange towards the base, with hints of blue or green near the wick; perhaps an orange or reddish color at the top of the wax of the candle. All of these blend together in the flame, more so when you see them reflected through a frosted candle base or on a nearby surface. A slight breeze will change the mixture of the colors and the rhythm of their change. These colors are made of different wavelengths of light, determined by the material that’s burning and the material through which it’s refracted or off of which it’s reflected. Re-creating this feeling using artificial light sources requires multiple sources mixed together. It can be done by controlling the color and intensity of multiple light-emitting diodes, or  LEDs, using a microcontroller, a tiny, simple computer used to control physical devices.

Turning On The LEDs

To get started, download and install the Arduino microcontroller integrated development environment (IDE) on your computer. Also download the Adafruit NeoPixel library, and the ColorConverter Library (download here). The libraries will download into .zip files that you’ll install shortly. The IDE will download into a disk image that you should open and install the contents into your Applications directory.

Install the Arduino IDE, then launch it. When you’ve got it open, click the Sketch menu, then Include Library…, then Add .ZIP library. Select the NeoPixel library .zip file from your Downloads directory. It will be called The IDE will install the library from the .zip file when you select it.   Do the same with the ColorConverter library, which should be called These libraries give the Arduino IDE the additional functions it needs to control the NeoPixel programmable pixels, and to do color conversion math that you’ll learn about shortly.

Sketch menu of the Arduino IDE showing how to add a ZIP library
Sketch menu of the Arduino IDE

There are many different models of Arduino and compatible microcontroller boards. Any of them will work for this exercise, but the MKRZero model is shown below. If you’re using a MKRZero or other MKR-style Arduino with pins on either side, plug it into a solderless breadboard as shown here. Don’t leave it in the black foam in which it’s shipped. This foam is conductive foam, to protect the board during shipping, but it will damage the board if you power it while it’s in the foam. Once you’ve mounted it on a solderless breadboard, plug your board into your computer’s USB port.

MKRZero attached to the center of a breadboard
MKRZero on a breadboard

Now it’s time to light your first LED. Most Arduino and Arduino-compatible boards come with a built-in LED. The MKRZero is no exception. Click the File menu, then Examples, then 01. Basics, then Blink. This will open a new file that looks something like this (Click the copy button in the code header to copy this code):

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000); // wait for a second
  digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
  delay(1000); // wait for a second

Click the Tools menu, then click Board: and choose MKRZERO. If it’s not in the menu, choose the Boards Manager from that same menu and search for the MKRZero board and install it. When you’ve got the board selected, click the Tools menu again, then click P0rt: and choose the port with the name corresponding to your board. For example, the one shown below is called /dev/cu.usbmodem14141 (Arduino MKRZERO).

tools menu of the Arduino IDE showing how to select the port to your connected Arduino
tools menu of the Arduino IDE

When you’ve picked the right board and the right port, click the Upload button on the toolbar:

location of upload button on the Arduino tool bar in the upper left corner
upload button on the Arduino tool bar

The IDE will now compile your Blink program to a binary file,  transfer it to the Arduino, and start running it. You should see the builtin LED on your board blinking. Congratulations!

The LED Blinking on a MKRZero

Controlling a few LEDs at a time on an Arduino is simple. You attach one leg of the LED (the longer leg, called the anode) to one of the input-output (I/O) pins, attach the other leg (the shorter leg, or cathode) and apply voltage to the pin to turn the LED on. The digitalWrite() command does this. digitalWrite(pinNumber, HIGH) applies voltage, and digitalWrite(pinNumber, LOW) turns it off. Each LED is just one color, though. If you want to change the color of your light, you need multiple LEDs. To mix red, green, and blue into a range of colors, for example, you need three LEDs. Fortunately, you can buy components that have multiple LEDs in one package. A typical RGB LED might look like this:

Four LED components. The one on the right is an RGB LED and has 4 wires coming out of it. The others each have two wires.
Four LED components

Four LED components. The one on the right is an RGB LED. Note that it has four legs. It contains three LEDs in the one package. The long one is a common cathode. The three others are the anodes for the red, green, and blue LEDs in the package.

To control an RGB LED like the one shown on the right above, you need three I/O pins. The common cathode is attached to ground. As you can imagine, you run out of I/O pins fast if every LED needs its own pin. This is where programmable LEDs come in handy. Programmable LEDs are components containing an LED and a very limited processor to control them. They’re chained together so that you can control many of them from one I/O pin. Your microcontroller sends a series of electronic pulses on the I/O pin, and the string of programmable LEDs interprets the pulses to know which LED to turn on, and how bright. Each LED in the chain (for example, the ring shown above) gets its own address, and you send pulses indicating the address, then the levels for each color channel at that address. This communication is a form of serial communication, a common way that computers talk to each other. You can think of each LED as its own tiny computer, listening for messages from your master computer (your Arduino).

The programmable LEDs you’re using are a variant of WorldSemi’s WS2812 LEDs. They listen for a specific protocol set by the manufacturer, and you can send it from your microcontroller using the Adafruit NeoPixel library which you installed earlier. Disconnect your board from the computer (Always disconnect your microcontroller from power before changing the circuit!) Then connect your programmable LED ring to the board as shown in the image below, with the 5V input pin of the LEDs attached to the Arduino’s Vcc, the GND pin attached to ground, and the DI pin attached to digital pin 5:

MKRZero attached to a breadboard along with a programmable LED ring
MKRZero with programmable LED ring

The current available from the microcontroller’s Vcc pin isn’t much, but it’s enough to supply seven or eight programmable LEDs. You’ll be controlling the LEDs from pin 5 of the microcontroller. Now open a new file in the IDE, and enter the following program (Click the copy button in the code header to copy this code):

#include <Adafruit_NeoPixel.h>
const int neoPixelPin = 5;  // control pin
const int pixelCount = 8;    // number of pixels

// set up strip:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(pixelCount, neoPixelPin, NEO_GRB + NEO_KHZ800);

void setup() {
  strip.begin();    // initialize pixel strip
  strip.clear();    // turn all LEDs off

void loop() {
  int red = 255;   // set colors
  int green = 0;
  int blue = 0;

  // loop over all the pixels:
  for (int pixel = 0; pixel < pixelCount; pixel++) {
    strip.setPixelColor(pixel, red, green, blue);// set the color for this pixel
    delay(500);;    // refresh the strip

Upload this to your board. All the neoPixels should turn red, as shown in the video below:

Programmable LEDs turning on red, one at a time

This program contains the basic elements of any program for controlling neoPixel programmable LEDs:

  1. Include the library
  2. Set the I/O pin to control them from
  3. Set the number of programmable LEDs you plan to control
  4. Establish the group of LEDs as a set (strip in this case) and set its parameters
  5. Initialize the set of LEDs in the setup() function
  6. In the main loop, use strip.setPixelColor() to change the color of any given LED. Each channel’s brightness ranges from 0-255.
  7. refresh the whole set of LEDs with

Although the LEDs you’re using are likely just RGB LEDs, they’re not your only option. Programmable LEDs come in other options.  RGB+white and white-white-amber (WWA), which have a cool white, a warm white, and an amber LED, are available as well.  And the NeoPixel library isn’t your only option for programming them. More experienced coders may want to look at the FastLED library, or the light_WS2812 library. Most of the libraries will follow the same pattern of control shown above.

The magic in creating movement, color change, and animation lies in how you time the changes between colors of each given LED.  Play around with these parameters in the previous program and try a few variations of your own, to see what you can do. Try making your LED fade from orange (which is a combination of red and green and blue, like 191, 104, 38) to a yellow (something like 205, 206, 36). Try writing a program to turn each of the LEDs in the ring a different color found in the candle flame.

Note: the RGB color scheme used to set colors in web pages is identical to the scheme you use to set colors for these LEDs. Red, green, and blue are often encoded as hexadecimal numbers, so a string like 205, 206, 36 would be 0xCD 0xCE 0x24, usually written as #CDCE24 in HTML.

Color Rendering With LEDs

Now that you can control your LEDs, it’s time to think about the colors in those candles again. How can you make the best fade from red to orange to yellow, with ocasional flashes of blue or green?

LEDs emit different colors depending on the material from which they’re made. LEDs are made from materials like gallium arsenide, silicon carbide, gallium indium nitride, and others, mixed together in different ratios. Electronics Tutorials has a nice chart showing the common materials for different colors. What this means is that to recreate the flame colors, you need to find LEDs that produce the right wavelengths as the materials in your original candle, or you need to find LEDs that can mix together to give more or less the colors you want.  You can enhance the look by using reflectors and diffusers that highlight the colors you want, but you can’t reflect a color that’s not there to begin with. So the color range of your sources is important. In fact, artificial sources are rated by their color rendering index (CRI), which is a measure of how well a given light source renders the colors of an object.

Most LED sources re-create a wide color spectrum by combining color sources that are spread across the color spectrum like the ones you have here: red, green and blue. Some sources will include a white LED as well.  Some specialty sources will include more than just these colors. For example, white LED lights commonly come in multiple variants of white to support fading the color temperature of the light. Color temperature refers to the warmth or coolness of a light source. The Kelvin scale for color temperature ranges from 1,500k– 2,000k for warm reddish sources to 2,500k– 3,000k for amber and yellowish sources to 3,000– 4,000k for so-called “natural” white sources (analogous to incandescent light blulbs) to 4,000k– 6,500k for cool blue whites and 6,500k and higher for sky blues. The higher the Kelvin temperature, the cooler the hue.

The ability to render a wide range of colors is a competitive advantage for lighting manufacturers. For example, ETC Theatre Lighting makes sources with seven LED colors, to create as wide a range of color rendering as possible. They know that stage lighting designers are used to working with a range of color, from the subtle warm glow of an incandescent source as it fades out to the harsh greenish-white glare of an arc lamp, and they design their lights to re-create these conditions.

Color Models

When you think about mixing colors, you need a way to organize the colors so you can think about how to move from one color to another. Rune Madsen has an excellent chapter on color models and color spaces in his book Programming Design Systems which I’ll borrow from here.  A color model is a representation of the color spectrum in multiple dimensions, depending on the parameters that you have to represent the spectrum. For example the RGB color model represents the color spectrum on three axes: red, green blue. This is the most commonly used model for lighting and for computer screens, which are made of lighting pixels. See Madsen’s interactive model for RGB to visualize this. Printers often use a CMYK color model, in which color is represented on four axes, cyan, magenta, yellow, and black, for the ink colors often used in printing.

The RGB color model makes sense when you’re mixing red, green, and blue sources to make a color, but it can be challenging when you want to describe the changing hues of a source like a candle. For example, fading from yellow to orange to red and back requires you to mix red, green, and blue simultaneously to stay in the red-to-orange-to-yellow range. When changing between different hues, the Hue-Saturation-Intensity (HSI) is easier to work with. The HSI model maps hue on a color cylinder. Saturation of the color is mapped from no saturation (white) at the center of the circle to full saturation at the edge, and intensity, or brightness, is mapped in a third dimension.HSI is a variation on another model, Hue-Saturation-Lightness (HSL). The Hue-Saturation-Value (HSV) color model is also similar, but the height of the cylinder is intensity of color, not intensity. When you’re thinking about changing colors of light, you often describe what you want using an HSL color model, as the description of the candle above does.

When your light sources have RGB controls but you want to describe your program using HSI, you have to convert from one to the other. This is what computers are good for. To convert between HSI and RGB, you could do the math yourself, or use a color conversion calculator, or you could use the ColorConverter library which you installed earlier. This library does the math for you on the Arduino.

Here’s an example that uses the ColorConverter library fades from red to orange. Note how it requires changing only one number, the hue, even though that results in a change to red, green, and blue simultaneously. The code can also be found in this gitHub repository:

#include <Adafruit_NeoPixel.h>
#include <ColorConverter.h>

const int neoPixelPin = 5;   // control pin
const int pixelCount = 8;    // number of pixels
int change = 1;              // increment to change hue by

// set up strip:
Adafruit_NeoPixel strip = Adafruit_NeoPixel(pixelCount, neoPixelPin, NEO_GRB + NEO_KHZ800);
ColorConverter converter;

int h = 10;         // hue
int s = 100;        // saturation
int i = 100;        // intensity

void setup() {
  strip.begin();    // initialize pixel strip
  strip.clear();    // turn all LEDs off;     // update strip

void loop() {
  // create a single color from hue, sat, intensity:
  RGBColor color = converter.HSItoRGB(h, s, i);

  // loop over all the pixels:
  for (int pixel = 0; pixel < pixelCount; pixel++) {
    strip.setPixelColor(pixel,,,;    // set the color for this pixel;   // update the strip

  // increment hue to fade from red (0) to reddish orange (15) and back:
  h = h + change;
  if (h < 0 || h > 15) {
    change = -change;

The HSI color space makes it much easier to change individual colors across a range of hues without having to work out the color mixing to RGB yourself.

A ring of programmable LEDs fading from red to orange

Try modifying the program above to create different hues, and then write your own program to fade between them.

Reflection, Refraction, Diffusion and Design

Making a light is more than just turning on and off the LEDs. It’s about the surfaces through which the light is refracted, and off which it’s reflected. What makes any light interesting, in the end, is what it illuminates, and how it does it. There are a few constraints that can be useful in thinking about this:

  • Pick your  color palette and work with it. A color palette sets the mood. Rainbow color scrolling is not a design choice, it’s a default program for programmable LEDs. If you’re not confident, start with a tool like to make a color scheme.
  • Don’t show the source: diffuse it, reflect it, or redirect it in some way or another. Notice how the videos above do not show the LEDs themselves, only their reflection off paper. This is much more pleasing to the eye than looking at the sources directly.
  • Draw attention to the light on the subject, not the light itself

A Few Examples

The first two videos belows give you some ideas for what’s possible with programmable LEDs. The first video shows one of these programmable pixel rings inside a hand-crafted tea candle holder made from glazed ceramic. The glaze of the ceramic makes a nice reflection.

Video by Denise Hand.

Video by Denise Hand

In the next two videos, notice how the bristles of the paint brush blur the light and spread it out so that, in the second video, you don’t notice the LEDs at all, only the candle flame shape that it forms. Strong lines in a diffusion spread the light perpendicular to the direction of the lines, so the bristles in these videos help to spread the light here horizontally, blurring the distinction between one pixel and the next.

Video by Hayeon Hwang

Video by Hayeon Hwang

The video below uses dichroic filters,  thin films which selectively pass a small range of colors of light while reflecting other colors. The contrast of the deep purple light passed through the filter and reflected off the wall with the bright white light in the center creates drama.

Video by Hayeon Hwang

In this candle, a thick sheet of paper with holes blocks most (though not all) of the light, and allows some through to be further diffused by a lightweight silk material. The combination creates a sense of depth, and the light coming through the silk feels ephemeral compared the the more solid light of the inner polka-dot cylinder. This soft, out-of-focus bokeh light is a popular photographic trope.

Video by Hayeon Hwang

Here’s a candle that uses a wooden holder with holes, and creates a nice movement through variable changes in the LEDs. Since they change at varying speeds, the candle feels more “flickery”  and lively than some of the other candles:

Video by Rushali Paratey