Flickering LED Candle




Introduction: Flickering LED Candle

Take a dollar-store "flickering" LED candle, add an AVR ATtiny13 and a little code, and you get an LED candle that looks almost real.

Step 1: Open Up the Candle Casing

A thumbnail seemed to be the best tool for this job. The casing isn't glued. There's just a friction-fit post that goes into a receiving hole in the cover. Work around the cover edge and the base part will begin to come loose. Don't get into a hurry because the wires connecting to the LED module inside are very fine and easy to break. We'll be re-using these wires, so be careful.

Step 2: Remove the LED Module

The LED, connected to its base, is friction-fit into the base of the plastic candle flame. Twist slightly and pull to remove. Make note of the wire colors, as they may be different from the unit I used. I'll be using "yellow" for the negative and "red" for the positive.

Step 3: Move the Cathode Wire

We won't be using the original circuit, which is a low-side switch that just flickers the LED off for a few milliseconds periodically. Carefully unsolder the yellow wire and move it to the LED cathode on the middle pin. The wire is really fine. Use a hot soldering iron to melt the original connection. Add a little fresh solder to the center pin. Then you can hold the wire against the center pin and reflow the solder joint easily.

Step 4: Program Your Chip

We'll be cutting off the unused pins of the ATtiny13, so be sure to program the chip before you do that! I use a USBtinyISP programmer and a SparkFun breakout board in a solderless breadboard. We're using the internal oscillator of the tiny13, so there's no need to burn any of the programming fuses. You can use the hex file provided or compile your own with the provided source code.

Some notes about the source code: I used a generic random number generator because the stdlib rand() function is almost twice as large. When you only have 1024 bytes of Flash memory, every byte counts! Also, the millisecond timer doesn't seem to line up with real wall-clock time. But since exact timing isn't really important in this application, I just eyeballed the timing. Purists might cringe, but I'm a pragmatist. :)

To program using the supplied hex file on a Linux system, use this command line:

avrdude -p attiny13 -P usb -c usbtiny -U flash:w:flicker.hex

WinAVR users will probably know the right incantation. I don't do Windows. :D

Update: flicker2.zip contains the second version of the code, featuring two flicker patterns (flicker-up and flicker-down), along with adding watchdog protection to reset the chip if the mainline code should freeze.

Step 5: Trim the Chip Legs

Since we're only using pins 4, 5 and 8, trim off the rest of the pins with a set of flush cutters.

Step 6: Make Some Connections

The red (positive) lead was cut in an earlier step. Now you will strip about 3/16 of an inch of insulation from each of the free ends of the red lead. Then tin the exposed wire. Tin the remaining pins on your tiny13 chip, too. This makes attaching the fine wires much easier, because you can hold the wire against the chip pin and reflow the solder joint with a hot soldering iron.

The red lead from the LED module connects to pin 5. The red lead from the battery goes to pin 8.

For the ground connection, use a fine-pointed needle-nose pliers to bend the pin in a "U". With a sharp utility knife, score the insulation of the yellow (negative) wire and pull it apart to expose a small section of bare wire. Place that section of bare wire in the "U" you just bent and solder carefully.

Step 7: Add Some Insulation

Vinyl electrical tape makes a good candidate for insulating the exposed leads. Cut a narrow strip and slip it between the chip body and the pins, then fold it over. Once insulated, fold the pins over the bottom of the chip.

Step 8: Test Your Circuit

Now is a good time to install the battery and check your work.

Step 9: Put It All Together

Re-insert the LED into the bottom of the plastic flame. Tuck the chip into the case where it won't wedge against the on-off switch. Finally, put the base of the candle back, seating the post on the bottom into the socket in the cover.

Step 10: Look! a Flickering Flame!

If everything has worked well, you now have a flickering "flame" atop your LED candle. Brag to your friends. The units I bought came 2 to a package, so you could easily demonstrate a before-and-after.



    • Tiny Home Contest

      Tiny Home Contest
    • Fix It! Contest

      Fix It! Contest
    • Water Contest

      Water Contest

    26 Discussions


    Does the same thing.

    The latest tea lights from Dollar Tree have eliminated the circuit board, but they still flicker. HOW? There is nothing but an LED, a CR2032 button cell and a switch. The plastic case is the same as in your photos.

    2 replies

    I think that the led has a built-in chip for flickering the light. Just as those multi-color-changing leds that does have a built-in chip too.

    Yes, that's it! Totally amazing, a little chip encased in the diode. Thank you for pointing this out.

    I wanted to use one of these with a solar panel out of a garden light and have a remote way of turning off several (like 100 at a time) of these....any ideas would be welcomed

    2 replies

    Replying to an old post I know, but what he said about the common PS.

    Then, wirelessly control the PS on the cheap by using a low cost RF transceiver pair from Sparkfun or Modern Device (check out the Arduino JeeNode!)

    hundreds of leds rock! just get a common power source and wire everything together and put a switch on the power unit

    Does the flame have a slow or fast flicker, or both? It's hard to tell from the video you uploaded. Is it possible to slow the flicker down, or make it flicker less often? (Of course, that maybe what "flicker2.zip" does in one of it's 2 patterns.) Could this circuit drive a warm white LED? (The amber LEDs used in most of the LED candles I've seen are amber or orange.) Of course if one could make up a whole group of these with orange and amber LEDs and put them into a group to make a glowing embers effect for a fire place. Thanks for a great Instructable! Viva LInux!

    2 replies

    The flicker speed is fixed in both patterns, but it's east to change the constants that govern the timing and make it flicker as fast/slow as you like. The circuit can easily drive a warm white LED. Your white/amber embers effect sounds nice, but I'd expect you'll need an awful lot of LEDs (and chips). That would probably be better accomplished with a chip with more I/O and a charlieplexed array of LEDs.

    Thanks, SolidSilver. I'm looking forward to making this. I don't have any experience with coding, but I'm sure that if I follow your directions it'll all work just fine.

    Step 4, learn Latin.  (Sorry, I don't know Latin well enough to teach you.)

    I just whacked this up on a breadboard using an ATtiny45 (pretty similar to the 13 you used, but lots more memory so I can do more eventually). I adjusted the Makefile for the device and the 8MHz internal clock and it flashed and works for a while. However, after a couple minutes, it seems to lock-up and the LED just stays at one brightness. Pulling the 5V briefly resets it and it runs for a while longer. This is my first time using AVR and also programming a microcontroller in C (I used asm on PICs before) but I'm wondering if the gcc is generating a leak of some sort that eventually causes something to fill-up/overflow/whatever and that's what locks the AVR up? Has anyone else seen any problems like this? Any tips/input/ideas? Anyway, this is a nice Instructable and one I've kept bookmarked for when I finally got my USBtiny built and working (aka earlier this morning ;) ) Mike

    6 replies

    How are you storing your timers?  What do you do if your time to wait is negative?

    Both millis() and micros() are unsigned long
    check for overflow.

    int moo;

    if (millis() - moo > DELAY)
       moo = millis();

    Will lock up on moo overflow.

    unsigned long moo;

    if (millis()  - moo > DELAY)
       moo = millis();
    } else {  if (moo > millis(){moo=millis();}}

    My code uses delay_us() from the AVR runtime libs.  My guess is that it properly checks for over/underflows, but I haven't actually audited the code. In any case, your point is well taken.  I learned this the hard way when I first started embedded coding (way back when on the 8051 family).

    I looked through the delay code while working on this project and didn't see any dynamic allocation, so I don't think there's much chance of a memory leak. It should have hit the tiny13 quicker than a 45, anyway, no? The only thing I can think of is that I didn't activate the watchdog timer. Your symptom sounds like the main loop is locking up. I'll look into adding the watchdog in, so if the main loop does lock up, the chip will automatically reset.

    I redid the code for this project to add watchdog protection (hopefully it addresses cheeze69's freezeup problem on a tiny45) and alternating flicker patterns (up and down) that change with each reset or power cycle. Download the new code from step 4 of this Instructable.

    Hi SolidSilver, I just tried the new code on the Tiny45. I re-compiled it again after adjusting the makefile for 8.0MHz and attiny45, using the AVRmacpack. It's running nicely and the new feature with the "low ficker high" and "high flicker low" works fine. I've run it for over 5 minutes without any lockup. Not sure if it was something with the gcc generated code or maybe I had some noise in the circuit (I have a couple fluorescent lights on the same 120v circuit and have seen the project lock-up when I switch a light off). Anyway, I definitely like the "low flicker high" mode best, so I'll modify the code to use that entirely. Now to find a good LED/etc. to make an old "Pirates of the Carribean" lantern for my back porch. Thanks for the great project and continued work!

    a while ago i saw a similar tutorial but done with a zener diode i believe, the idea was to build a zener-based "noise" generator and use it to power the LED

    1 reply

    Can you publish a link for the zener based circuit? (I'm requesting on a year old comment -- sorry about that.)