On the internet there are so many Led Flasher’s projects, some even with low current consumption, but what I needed was a flasher to be used for geocaching, extremely small and that could last at least one year with a button battery.
I started so a little experiments with the ATtiny85 low power modes using the sketch of insidegadgets, achieving a power consumption of about 4.5uA in standby and of about 3mA during the led flash that occurs every 4 seconds and lasts for about 30ms.
In this way, the average consumption is around 25uA, which with a CR2032 button battery from about 220mAh, this means about a year of life!
After a first draft of the project, I thought it might be useful to also have a 12V version so that it can be also powered by the battery of a car.
Here you can see the circuit on the first version, namely the one powered by 3V button battery:
The schematic is really very simple because the real work is done by the code:
/* Ultra Low Power Led Flasher with AtTiny85 @ 1Mhz by Luca Soltoggio 06/01/2014 http://www.arduinoelettronica.com */ #include <avr/sleep.h> #include <avr/wdt.h> #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif int pinLed = 4; volatile boolean f_wdt = 1; void setup(){ pinMode(pinLed,OUTPUT); setup_watchdog(8); // approximately 4 seconds sleep } void loop(){ if (f_wdt==1) { // wait for timed out watchdog / flag is set when a watchdog timeout occurs f_wdt=0; // reset flag digitalWrite(pinLed,HIGH); // let led blink delay(30); digitalWrite(pinLed,LOW); pinMode(pinLed,INPUT); // set all used port to intput to save power system_sleep(); pinMode(pinLed,OUTPUT); // set all ports into state before sleep } } // set system into the sleep state // system wakes up when wtchdog is timed out void system_sleep() { cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here sleep_enable(); sleep_mode(); // System sleeps here sleep_disable(); // System continues execution here when watchdog timed out sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON } // 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms // 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec void setup_watchdog(int ii) { byte bb; int ww; if (ii > 9 ) ii=9; bb=ii & 7; if (ii > 7) bb|= (1<<5); bb|= (1<<WDCE); ww=bb; MCUSR &= ~(1<<WDRF); // start timed sequence WDTCR |= (1<<WDCE) | (1<<WDE); // set new watchdog timeout value WDTCR = bb; WDTCR |= _BV(WDIE); } // Watchdog Interrupt Service / is executed when watchdog timed out ISR(WDT_vect) { f_wdt=1; // set global flag }
The complete project, 3V and 12V dual-use version can be found on Fritzing posted to the following address:
http://fritzing.org/projects/ultra-low-power-led-flasher-with-attiny
See you soon!
Here is an interesting observation. I created your 3V circuit and used the same code above on my attiny85 running at 1MHZ. I noticed:
a. When LED is not flashing, the consumption is 4.2uA.
b. When the LED is flashing, the consumption seems to cycle from 16uA and increase by 10uA for every flash. When it reaches 130uA it flips to the opposite and starts to decrease by 10uA until it reached 16uA and starts all over again.
I edited it for cheaper ATtiny13 (I am using ATtiny13A-SU internal R/C osc 4.8 MHz divided by 8 – 600 kHz = low_fuses=0x69 high_fuses=0xff ). Code is more optimised and also there is added on/off switch. ATtiny13 in this configuration = 600kHz and on 3V battery consuming cca 0.1uA if it is in OFF state and 4.4uA between LED flashes = power down, but WDT is running. After battery is connected, and after reset, power is ON. So you do not need to use/connect switch.
Currently I am using Arduino IDE 1.6.0 with core13 for compiling and uploading this sketch.
http://sourceforge.net/projects/ard-core13/
/*
ATTINY13 Ultra Low Power Led Flasher with ON/OFF switch
ATTINY13
+-\/-+
ADC0 PB5 1| |8 Vcc
ADC3 PB3 2| |7 PB2 ADC1
PCINT4 ADC2 PB4 3| |6 PB1 PWM1 INT0 tactile switch
GND 4| |5 PB0 PWM0 LED
+—-+
WDT = Watchdog Timer
*/
#include // sleep code
//define function cbi – Clear Bit in I/O Register
//define function sbi – Set Bit in I/O Register
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~(1<<bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= 1< 7) // for 8 and 9
{
cbi(t,3); // set 3rd bit to 0
sbi(t,5); // set 5th bit to 1
}
t |= 1<<6; // WDTIE = 1 (WDT int. enable)
WDTCR = t; // write WDT prescale setting bits
}
/////////////////////////////////////////////////////////////////////
void loop(){ // one 30ms flash, sleep
sbi(PORTB,led); // turn LED ON
delay(30); // for 30ms
cbi(PORTB,led); // and OFF
sleep_cpu(); // Power down
// MCU is waked up by WDT interrupt or INT0
}
/////////////////////////////////////////////////////////////////////
ISR(WDT_vect) // WDT interrupt service routine
{
// empty, but it must be here 🙂
// it will not work without it
}
/////////////////////////////////////////////////////////////////////
ISR(INT0_vect) // INT0 interrupt service routine
{
delay(1000); // wait 1 sec
WDTCR ^= (1<<WDTIE); // toggle WDT interrupt
}
1st post is messed
Good Morning.
You can tell me how to modify than 7 = 3 sec.
Modify the program but remains 2 sec
jordiwrGeorge:
This is the command:
“setup_watchdog(7);” and this is just comment: // WDT prescale select 0-9
This is also just comment:
// 0=16ms, 1=32ms, 2=64ms, 3=125ms, 4=250ms, 5=500ms
// 6=1 sec, 7=2 sec, 8=4 sec, 9=8sec
So you can use values 0….9 in command “setup_watchdog(7);”
And each value means time from 16ms to 8 seconds, you can chose 2 or 4 seconds.
For 4 seconds you need to change 7 to 8 in command:
“setup_watchdog(7);”
Hello;
I am new in this field i need a simple single LED flasher circuit with code that will accept two types of signal one is positive +5v and other is -5v when +5 signal input to atiny it starts flashing LED at rate of 2sec and when -5v signal input the LED becomes solid.Please reply.