Very low power LED firefly
(Last modified 21 May 2013)

Updated 21 May 2013
I haven't been able to get anything close to what I wanted for battery life, so I finally sat down and ran the numbers to see what is realistic.  Turns out two weeks is about it, given the current state of the project.

The ATtiny13A consumes 1.5 mA in active mode at 4.8 MHz clock (which is what my test firmware used) and .004 mA in power-down mode with the WDT enabled; these are the two modes used in my design.

The firefly duty cycle is active mode for 2.5 seconds and power-down mode for 8 seconds.  I'll ignore the current used while in power-down mode, given the tiny level involved, and focus on current used during active mode.

The CR2032 battery is rated for 225 mAhr.  Given a draw of 1.5 mA, this yields 150 hours of operation, or 6.25 days.  Since the firefly is in active mode only 2.5 seconds out of every 10.5 seconds (assuming it's dark all the time), actual yield is 150 * 4 or 600 hours, which is 25 days.

However, the amount of time that you will be able to see the LED blink is less than this.  Once the battery voltage drops below the forward voltage of the LED, the LED won't light any more even though the MCU is still running.  So for a green LED with a forward voltage of 2.2 VDC, the firefly will appear to stop working when the battery hits 2.2 VDC or thereabouts.

Note that the above calcs ignored the added current draw when the LED is lit.  Given the duty cycle of the LED blink (on for 1 msec, off for 12 msec), the LED will add about 2 mA of current for about 130 msecs during each active phase.

So how can you extend the operating life of the firefly?

One way is to use a red LED.  These typically have a forward voltage of about 1.8 VDC, which will extend the battery's useful life perhaps a day or so.

Another way is to add a 32 kHz crystal to the design and run the ATtiny13A at 32 kHz.  In this case, the active mode current consumption drops to about 110 uA (0.110 mA), or less than 1/10th of the current used at the higher clock rate.  However, this drastically changes the code for timing the LED pulses and could force a higher LED duty cycle, which in turn would consume more current.

Another option is to put the MCU in idle mode any time it is not changing the state of the LED.  This will require a separate wake-up method from the WDT interrupt used for the eight-second off state.  Basically, the MCU would be in either idle mode or power-down mode almost all the time.  Since idle mode only consumes 0.4 mA instead of 1.5 mA at 4.8 MHz, the battery life could essentially quadruple.  There still would be tiny intervals where the MCU was in active mode, just long enough to turn on or off the LED, or do some setup for the long power-down stretch.  If the numbers are right, this could extend the firefly battery life to almost two months.

Updated 5 May 2013
Two YEARS!  What, are you NEW?

No way the original code for this project gets two years of life from a CR2032 battery.  I was seriously optomistic (more like deranged) in my calculations.  This was pointed out by jacques in a HackADay post and by my own experiments.  Two weeks is more typical for the original code.

To improve battery life, I had two choices.  I could add a current-limiting resistor to the LED and leave the blink at full power, or I skip the resistor and PWM the blink to reduce overall current.  Since the point of this build is lowest parts count possible, I chose adding a 10% duty-cycle on the blink.  This means that if the firefly blinks all of the time, it will consume an average of 2 mA of current for the two seconds out of 11 that the LED is lit.  I still won't get two years of life, but I think 20 weeks should be doable. (Sorry, not possible; see section above.  KEL, 21 May 2013)

The PWM is not very smart, I just turn on the LED, spin-wait a while, turn off the LED, spin-wait a longer while, and repeat until the blink time has elapsed.  If you want to spend the time, you can modify the blink code to use a timer plus interrupt.

Note also that I hard-coded a threshold for darkness in my code.  Feel free to use a different number if you think the LED blinks when it shouldn't.

Also, be sure to use the highest-output LED you can find for this project, to improve the firefly's visibility.  Some years ago, lots of the LED Christmas strings used clear LEDs with an inward-pointing bevel to provide 360-degree visibility.  If you can scrounge any of those LEDs, they work great in this project.

So far, I've used green, yellow, red, and blue LEDs.  They all look good, though the blue LEDs are a bit dim, probably because their forward voltage is so close to the battery's nominal output voltage.  But if you stick to the other colors (excluding white), you should have lots of options.

I've replaced the original code here with this version, and included the final .hex file if you just want to load and go...

This is my version of an LED firefly, built with what I think is the smallest parts count and drawing the least amount of power that I can.  Here is the entire parts list:

1  ATtiny13a MCU
1  Green LED (diffused lens works best)
1  1 Mohm, 1/8-watt resistor (1/4-watt works also, of course)
1  CR2032 coin-cell battery
1  CR2032 coin-cell battery holder

Naturally, the MCU spends most of its time in sleep mode to keep the power drain down.  I'm using power-down mode for sleep, then using a watchdog interrupt to bring the MCU out of sleep.

Additionally, the MCU does not turn on the LED unless the light level is dark enough.  The MCU uses the LED as a light sensor, occasionally testing the light level and flashing the LED only if needed.

The power draw for this device is below my ability to measure.  I know it is well below 10 uA, but I don't know how far below.  I haven't had a chance to run one of these until the battery fails, but the CR2032 is rated for 225 mAHrs, so I'm probably looking at over two years.

A group of LED fireflies

Here is a group of three LED fireflies.  Wiring is point-to-point.  I left the pins on the MCU and intentionally connected only to the shoulders of each MCU pin.  This lets me update the firmware, if I need to, by tilting the MCU 90 degrees, then using a custom adapter to my Atmel programmer to plug onto the chip's leads.

Closeup of firefly wiring

Here is a closeup of the firefly wiring; pin one on the MCU is to the left.  I've wrapped the leads of the 1/8-watt resistor around the LED leads, then clipped the LED leads.  The resistor's leads are thin and flexible, making it easy to connect to the MCU's pins without shorting to adjacent pins.  Note that you can use a 1/4-watt resistor if you want, but it will make the connections to the MCU's leads a bit trickier.

I used a Renata CR2032 battery holder with through-hole tabs, turned upside down, as a base for the firefly.  The plastic shell of what would be the bottom of the battery holder makes an excellent insulated platform for the electronics.

It only takes about ten minutes to build up a firefly.  I then put the finished module on a shelf near a window, or in a small plastic bag and hang it in a tree outside.

Note that you want to use a diffused LED for this project; the LEDs with water-clear lenses don't let you see much of the blink.

The schematic
This project really doesn't require a schematic, but I did one in Eagle anyway; here is the PDF.

You can see that I'm not using a currently-limiting resistor on the LED.  If the MCU needs to flash the LED, it simply pulls the LED's port line high for a second.  Since the fiefly does a double-blink, the LED will be powered for at most two seconds out of every 12.

The 1M ohm resistor across the LED solves a problem that appears when I use the LED as a light sensor.  The instant the MCU activates the LED port line as an A/D input, there is a slight spike in voltage (maybe 20 mVDC) across the LED.  Because the LED has an internal capacitance effect, this presents an artificially high voltage level to the A/D.  In order to get a more accurate light level reading, I have the MCU wait a few msecs between turning on the A/D port and taking the reading, letting the resistor bleed off the voltage.  A delay of only 3 msecs or so works well.

Note that there is another common technique for using an LED as a light sensor.  Various web pages describe using two pins of the MCU to drive the LED and to read the voltage across the LED as it dissapates when the LED is off; the rate at which the voltage drops is a measure of the light level.  However, the voltage will drop very slowly (as in many seconds) if the LED is in darkness.  The technique used here gives reliable readings in milliseconds, regardless of light levels.

The code
I've included the C source file and a .hex file here.  The object file is only about 400 bytes out of the 1K available in the 'tiny13a, so there is plenty of room for additions.  The source file uses AVRStudio4 and WinAVR as the programming environment.

I have a few ideas for upgrades.

As you can see above, you can use different color LEDs for the firefly.  Yellow, green, and orange LEDs all work very well; so will red.  Just about any LED with a forward voltage of 3 VDC or so should work.

Kingbright makes an excellent SMD RGB LED which would fit perfectly on top of the MCU and let me do different colors of blinks from a single firefly.

You can add other LEDs of different colors so a single firefly can blink different colors without having to use an RGB LED.  Just tie the cathode of each new LED to pin 4 on the MCU, the anode to an unused output pin, and modify the code to add that LED to the blink.  Note that you will not need to add a 1M ohm resistor to any additional LEDs; only the LED used as a light sensor needs the resistor.

Another upgrade involves sync'ing multiple fireflies so they blink in unison.  There is a species of firefly in the South,
Photinus carolinus, that blinks in unison, and it would be cool to mimic that.  One possible way would be adding an IR LED that would send a burst of blinks at the start of a visible blink cycle.  Each firefly would also use this IR LED as a sensor, looking for such bursts, then use this signal to sequence their own blinks.

This is an excellent project for kids with a little help from an adult.  The soldering is pretty simple (maybe with a little help), the parts count is low, and it shouldn't cost more than $5 to build a firefly, even if you pay retail for new parts.  And I really enjoy seeing my fireflies in a backyard tree; given that I live in Seattle, that's about the only way I'm going to see local fireflies.