Hacking a Candleflicker LED

Let’s reverse-engineer a LED, pedantic mode.

Lately, cheap electronic candles seem to be everywhere. I never paid much attention to them until recently it came to my attention that they actually use a special type of light emitting diode with integrated “candleflicker” controller. Now this is something different – who doesn’t like obscure LEDs? Half an hour later I had managed to score a bag of candleflicker-LEDs from the chinese manufacturer.

Very nice, you can not do that with real candles. But the interesting part is of course: How do they work? Considering that they literally sell for a few cents a piece, there can not be very expensive electronics involved. This raises another question: Are these cheap LEDs really worse than all the self-made microcontroller based LED-candles around the web?

Image

The construction is relatively simple. The standard 5 mm LED package contains a small LED-Chip and a slightly larger integrated circuit. The controller chip is connected to both the positive and the negative leads. A third bond wire is connected to the anode of the LED chip, while the cathode is connected to the negative lead.

Evil Mad Scientist looked at very similar LEDs a while ago. They showed that they are “musical” by translating brightness variations to sound. They also showed that they can be used to control another LED. This is based on the fact that the LED draws more current when it is turned on by the controller. A second LED connected in series shows a very similar brightness modulation. Alternatively, the voltage drop across a series resistor is modulated in the same way as the LED brightness.

circuitI used this to extract the “control signal” to the LED and capture it with a logic analyzer, as shown in the circuit diagram. The variable resistor has to be adjusted so that it is large enough for the logical analyzer to see a current increase as ‘one’, but still allow the LED to function properly.

led_long
The diagram above shows about a minute of LED brightness variation sampled at 1MHz. It is obvious that there are periods where the LED is fully turned on and there are intervals when the LED is modulated in some way. It is never off for a longer period. The makes sense, because a real candle is at maximum brightness most of the time, interrupted by short periods of “flicker”.

led details
A closer look reveals that the signal is pulse width modulated. This means that we are looking at a digital circuit, no weird analog trickery.

Curiously the frequency of the signal is around 440Hz, the concert pitch standard. Coincidence? Or did the designer lift the oscillator from a music playing circuit? (So there is some truth to the rumor of these LEDs being musical). Each “frame” of equal brightness is exactly 32 cycles and lasts around 72 ms. This corresponds to 13-14 updates per second.

I coded a small program to identify the brightness value of each frame from the duty-cycle of the signal. The program reads a raw stream of samples and outputs a series of floating point numbers, one for each subsequent frame.

Time Series

Plotting the brightness data versus time reveals some insights: The brightness variation is random, discrete, and not distributed evenly. There seem to be 16 brightness levels, of which the lowest 4 are rarely being used. Only 13 of 3600 samples are found here.

probability

Plotting the histogram reveals the full picture: Only 12 brightness levels are used. Exactly half of the samples are at maximum brightness, while the remaining are almost equally distributed .

How could this be realized in hardware? It seems likely that there is a source of evenly distributed random numbers that are fed through a simple signal shaping function. To generate the observed distribution at least 12*2=24 discrete input levels are required. Half of them are mapped to 1. This is quite curious, since the random number generator will most likely generate a binary number. The most logical random number size would be 5 bit, 32 states. Mapping a 32 state discrete random  variable with a homogeneous distribution to 24 states without altering the distribution is not as simple as it seems. Let’s also not forget that this is a completely uncritical circuit and the design was most likely rushed. So the designer  picked the most simple solution or a hack of sorts.

The only simple way that comes to mind would be to simply discard unwanted values and try the next random value.  Unwanted values can be easily identified by a bitmask. Since this is a clocked circuit, only a finite number of attempts are possible until the next frame arrives. If the number of attempts is exceeded, we are stuck with an unwanted value. Remember the glitches above?

This is how an implementation in Ansi-C could look like:

    char attempts=0;
    char out;
    while(attempts++<MAX_ATTEMPTS) 
    { 
        out=RAND()&0x1f; 
        if ((out&0x0c)!=0) break; // rejected values are identified by bit 2 and 3=0 
    } 
    if (out>15) out=15; // map upper half of values to maximum brightness

Can we answer how many attempts are made? Statistically, a fraction of a=0.25 of the random numbers must be rejected and “rerolled”. The probably of rolling an invalid number after n attempts is a^n

   n=1      0.25
   n=2      0.0625
   n=3      0.015625
   n=4      0.003906

The fraction of “too low” brightness values is 13/3600=0.0036, which fits very well to n=4. So MAX_ATTEMPTS=4.

Note that a more simple solution would be to simply use the value from the last frame in case in invalid value is encountered. But this can be ruled out from the autocorrelation below. The most simple solution would probably have been to modify the PWM circuit. But this is not what was done here.

Good, with that out of the way, the last piece of the puzzle is the random number generator itself. A typical way of generating a random bitstream in digital circuits is to use linear feedback shift registers. LFSRs generate pseudorandom sequences of bits that repeat after a maximum of 2^x-1 clock cycles, where x is the number of bits, if a proper configuration is chosen. One characteristic of these sequences (and proper pseudorandom sequences in general) is that their autocorrelation function is one only at the origin and multiples of the sequence length and zero elsewhere.

Autocorrelation

I calculated the autocorrelation of the entire sequence of brightness values. No self similarity was found up to 3500 samples (only 1200 displayed above), meaning that the flickering sequence did not repeat for at least 4 minutes. Since at least 5 bit of random values are required per frame (even more considering the rejection mechanism above), the random sequence is at least 17500 bits long. This would require a LFSR with a length of at last 17, or a true hardware random number generator. In any case, it is interesting that as much care was taken  to not repeat the flicker sequence when designing this product.

To conclude with the questions from the beginning: The flicker LED circuit is far more complex than I anticipated (I had also not expected to spend 4 hours on this). Many of the microcontroller candle implementations only push a LFSR bit directly to the LED output. This commercial flicker-LED uses a more sophisticated PWM output and a brightness shaping algorithm. It seems that definitely some care went into the algorithm design and more than the absolute minimum of chip area was invested. A fraction of a cent well spent.

What is the best candle-algorithm? Can this be improved?

Edit: I finally got around emulating the LED. You can find an emulation of the LED behavior in ANSI-C here. It is written for AVR-Microcontrollers, but can easily be ported to other controllers. The github repository contains all the data and code I have written to reverse engineer the flicker-LED.

Edit 2: For reference, I added the specifications that came with the LED below. You can find several vendors sellings these on ebay and other auction sites by searching for “candle LED 5 mm” or “kerze LED 5 mm” (german).

Material: AlGaInP
Absolute Maximum Rating at Ta =25°C
Power Dissipation: 100 mW
Continuous Forward Current: 35 mA
Derating Linear From 50°C: 0.4 mA/°C
Reverse Voltage: 5V
Operating Temperature Range: -40°C to +80°C
Storage Temperature Range:-40°C to +80°C
Lead Soldering Temperature: 260°C for 5 Seconds
Super high intensity luminosity: 100-2,000 mcd
Current voltage: 1.9-3.8 V
Current electricity: 20 mA
Angles: 25-120 degrees

30 thoughts on “Hacking a Candleflicker LED

    • I believe that, if it is a hardware implementation and not a LFSR, then it is most likely some variation of this:

      http://en.wikipedia.org/wiki/Hardware_random_number_generator#Clock_drift

      Basically you use a slow RC-oscillator with a lot of clock jitter to gate the output of a fast oscillator. The LED already has a slow RC-oscillator for the main clock. The faster one could be a ring-oscillator.

      My understanding of avalanche diodes is that they need a relatively high bias above 5V, which is not available in this application.

      • The PRBS would be much smaller than having a second (slow) oscillator, It’s actually quite hard to make a very significantly noisy oscillator. In addition, it takes some care to ensure that the oscillators don’t inadvertently synchronize to each other.

      • With PRBS you are referring to an LFSR? Well, my line of thinking was that they already have a slow RC-oscillator, since the masterclock is 16*440Hz or a multiple. So they would merily have to add a fast ring oscillator and a latch.

  1. Here you can find my solution: http://bienonline.magix.net/public/avr-advent.html (it’s in German, Google translator can help). I use an array of random brightness values. There are more values for higher brightness than for the lower ones. That makes filckering more realistic (You detected this fact already.). The avr-library has a random number generator. With this random number I select an array index for the next brightness value. So you can get an realistic candle flickering depending on the distribution of the brightness value in the array and a long range of random values without repeating them.
    Addionally I don’t switch directly from one brightness value to next. Instead I use a ramp with a random duration. The calculation of the duration is similar to that of the brightness.

  2. If the chip on your LED also has unbonded pads would be possible to further play with it and see what else it can do? To dissolve the LED package acetone (perhaps warmed up) could work.

  3. […] Interestingly, the APA102 started to flicker once I set the global brightness to 30 or below. To understand what was going on, I hooked up my scope to the power rails. When the LEDs are turning on, they draw significantly higher current which leads to a drop in voltage across the power rails. I previously used a similar method to investigate the inner workings of candle flicker LEDs. […]

  4. Absolutely awesome analysis! Saved me the work of video recording a live real candle, pixelating the frames, and developing an algorithm from that data!!! The project I am working on consists of an array of LED’s that are 8 columns of 4 leds arranged in a tube configuration. The task I have now is to translate the single LED brightness into 8 level meters and sync them into one simulated image instead of ending up with 8 independent patterns running autonomously. Meaning, if the flame moves off center of the tube to the right, left, forward, or back, the columns reflect that accurately.

    Your offering really helped that! THANK YOU!!!!

    • Glad this was of help.

      But I guess it could be possible to build a better algorithm than the one used in the candleflicker LEDs? Recording a real candle is actually an interesting idea – maybe a single photodetector is enough?

      • For a single LED, certainly. Probably could be done with a simple photocell and a Pro Mini ATMEGA328P (5v 16MHz). How sensitive and responsive would matter and I do not know either one, but if they were enough with both criteria, I suspect eight set up in a circle around a candle (for my application) would give me what I need as far as data. Then sample when it does that weird phenomenon where the candle flickers like an oscillation, and how it reacts to small puffs of air and also light wind. Say… generated from a small 120mm computer case fan.

        I’m on it!! :D

      • Good thinking :)

        I have to admit, I also got excited about this idea and started to do some crude experiments. Your set up sounds far more elaborate,though. I just connected a photodiode to an oscilloscope. I will put some data on the blog. There a lot of curious things going on. Turns out, candles are quite complex.

      • Agreed! I might do this with my fire pit also. Much more elaborate data analysis with that idea though. I’m good at recognizing patterns, but you seem better at the math than I. So, if you email me, I’ll send you the raw data from each of the 8 channels and the criteria I use. I’ll record video with my smartphones… one at slow motion (1/8th speed) and one in real time to sync with the data for visual confirmation of the fluctuations.

      • I am just writing up my finding. Turns out finding a good algorithm is pretty hard. The most pragmatic way might be just to play back the recordings :)

      • I thought so too, and when digitized down, the pattern would not take up too much of the resources of my platform. But I am intrigued at what you are working towards, which is a true random and realistic pattern generation in real time. Played back patterns are doomed to repeat themselves, and that is what I am trying to steer away from.

      • One more thing to consider, and I haven’t gone after this yet considering the limitations of my platform, but what about introducing Perlin Noise? It works fantastically for flash animations, but could it be scaled down for simple pixel level simulations like this? The Perlin Noise influence could play the role of wind influences with the candle’s flame. And I wonder how temperature effects the flame as well. Lots of research to do!

  5. I saw this really expensive but really cool looking LED matrix candle at the MOMA design store in NYC:

    I couldn’t tell if the candle flame was generated algorithmically or with video.

    There’s some pictures of the LED matrix candle circuit here:

    http://store.luminaire.com/lighting/my-new-flame

    I’m just guessing, but it looks like the square chip is a CPU, the two chips above it are to drive the LED matrix, and the 8-pin chip below the CPU could be a EEPROM or other serial memory storing video for the flame.

    • Yes, that is a really nice one, although quite expensive. Its a really great design. As far as I know this is based on a video that was taken from a real candle.

      There has been a similar maker-project a while ago: http://www.ognite.com

      I really wonder why not more makers are trying to build this? This could be the “wordclock” of the christmas season :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s