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.
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.
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.
Upgrades
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.
Summary
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.
Home