lbenson
Senior Member
This project implements battery backup (with 3 AAs) to a regulated 5V supply (from mains), with checking of the return of mains supply while running on the battery, and monitoring of the battery voltage through ADC while running on the mains supply.
The original design posted has been replaced with this one to incorporate the suggestions of Mycroft5152 plus some which came to me.
Two LEDs, one red and one green, show the status of the power sources. When both LEDs are on, mains power is on and the battery is showing more than 3 volts (relative to the 5V regulated mains supply). If the battery (which is checked about once an hour) drops below 3 volts, the green LED goes out, showing that the batteries need to be replaced. If mains power goes out the processor clocks down to 31kHz to conserve battery power, and blinks the green LED about once every 7 seconds to show a heartbeat. An additional power-saving feature is the poking of the ADCON0 register to turn off the ADC module while on battery power. The timings are only approximate. The DISABLEBOD command is run upon initialization to reduce current draw and to allow the picaxe to run on very low batteries.
The Green LED uses a 22K series resistor, which makes it faint, but detectable. This reduces power draw when running on batteries. The red LED uses a 2K2 resistor--it is on only when mains power is available.
This is implemented on an 08M, and uses 130 bytes out of the 256 available. It would not be too useful on an 08M because only two I/O lines remains available. On a 14M or larger PICAXE, a good bit could be accomplished with this simple backup circuit.
Many thanks to those who have contributed the ideas for this circuit over the past year and more (nothing about it was invented by me): hippy, dippy, kranenborg, mycroft2152, beaniebots, Dr_Acula, manuka, and others. This seemed to be a good example for drawing a number of threads together.
Enhancement suggestions are invited.
Note that if the system can't do any meaningful work while on battery, the technique often suggested by Dr_Acula might be less trouble--save indicator variables in eeprom (non volatile), and when you restart after a power failure, check those variables so that you can recommence where you left off.
According to my DVM, this setup on batteries takes 31 microamps, blipping up briefly when the LED flashes to between 50 and 155 microamps (the capacitor is taking up some of the slack).
The original design posted has been replaced with this one to incorporate the suggestions of Mycroft5152 plus some which came to me.
Two LEDs, one red and one green, show the status of the power sources. When both LEDs are on, mains power is on and the battery is showing more than 3 volts (relative to the 5V regulated mains supply). If the battery (which is checked about once an hour) drops below 3 volts, the green LED goes out, showing that the batteries need to be replaced. If mains power goes out the processor clocks down to 31kHz to conserve battery power, and blinks the green LED about once every 7 seconds to show a heartbeat. An additional power-saving feature is the poking of the ADCON0 register to turn off the ADC module while on battery power. The timings are only approximate. The DISABLEBOD command is run upon initialization to reduce current draw and to allow the picaxe to run on very low batteries.
The Green LED uses a 22K series resistor, which makes it faint, but detectable. This reduces power draw when running on batteries. The red LED uses a 2K2 resistor--it is on only when mains power is available.
This is implemented on an 08M, and uses 130 bytes out of the 256 available. It would not be too useful on an 08M because only two I/O lines remains available. On a 14M or larger PICAXE, a good bit could be accomplished with this simple backup circuit.
Many thanks to those who have contributed the ideas for this circuit over the past year and more (nothing about it was invented by me): hippy, dippy, kranenborg, mycroft2152, beaniebots, Dr_Acula, manuka, and others. This seemed to be a good example for drawing a number of threads together.
Enhancement suggestions are invited.
Code:
' 08BakUp2 test battery backup and then battery life
#picaxe 08m
' pin0=AVAILABLE
' pin1=Green LED+22K (battery voltage ok--on while mains on, blinks when off)
' pin2=AVAILABLE
' pin3=sensor for mains--in series 10K, 1n914, 1n914
' pin4=ADC sensing battery low w. 4K7 (while mains on)
'
' Peek, Poke memory $50-$7f
'
' LEDs mark 4 states:
' 1 Regulated power, battery off: Both LEDs off
' 2 Regulated power on, battery>3Volts: Both LEDs on
' 3 Regulated power on, battery<3Volts: Red LED on, Green off
' 4 Regulated power off, battery on: Red LED off, Green blinks
'
' Registers used: b0 (bit0 only), b1 (scratch), b13
symbol mainsOn = bit0
symbol scratch = b1 ' reusable elsewhere for scratch
symbol loopCnt = b13 ' we have a 200ms pause each loop, so 25=5 sec
symbol mainsSensor = pin3
symbol ADCON0 = $1f ' ADC control SFR register to turn off ADC module
symbol OSCCON = $8f ' Oscillator control SFR register for speed up/down
symbol ADCtime = $7f ' counts # of 50 second loops; at 72 (1hr), ADC battery
symbol Red_LED = 0
symbol Green_LED = 1
dirs = %00000011
disableBOD ' turn off Brown Out Detection for low power
' and because we're doing our own battery monitoring
pause 5000
poke ADCtime,0 ' initialize counter
if mainsSensor = 1 then ' if we have mains power
readadc 4,scratch ' check battery voltage: 3V should be ok
if scratch > 153 then ' 255/5v*3v = 153
high Green_LED
endif
else ' we're starting up on battery
mainsOn = 1 ' pretend we're coming from a mains-on state
endif
'sertxd(" Restarted ",#scratch,CR,LF)
main:
do
if mainsOn = 1 then
pause 200 ' allow a little debounce time & a little loop time
' Note: instead of pause, "nap" will save
' power, but pwm and servo commands cease
' at 4mHz we will have about 5 loops per second
else
' pause 1 ' we're running at 1/128th the speed on battery
' timings will be based on slow instruction speed
endif
if mainsSensor = 1 then ' mains power is on
if mainsOn = 0 then ' power is just coming on
poke OSCCON,%01100000 ' = 4 MHz; speed back up
' high Red_LED ' indicate that we have mains power
mainsOn = 1
endif
else ' we're running on battery
if mainsOn = 1 then ' power just went off
scratch = b0 ' save bit settings
peek ADCON0, b0
bit0 = 0 ' turn off the ADC module to save power
poke ADCON0, b0
b0 = scratch
mainsOn = 0
low Green_LED ' can't monitor battery with mains off
poke OSCCON,%00000000 ' = 31 kHz slow down
endif
' low Red_LED ' turn off mains indicator or turn off blink
endif
inc loopCnt
scratch = loopCnt // 10 ' 10 loops @ 31kHz = 5-7 seconds (experimentally)
if mainsOn = 0 then ' we're on battery--give a 128ms flash every 5 sec
if scratch = 0 then ' about 5-7 seconds passed (on battery)
high Green_LED ' flash led
pause 1 ' 1*128 = 128ms
low Green_LED
endif
else ' we're on mains
' sertxd(" ",#loopCnt)
if loopCnt = 250 then ' about 50+ seconds passed (on mains)
peek ADCtime,scratch
inc scratch
poke ADCtime,scratch
if b1 = 72 then ' 250 loops = 50secs * 72 = 1 hour
readadc 4,scratch ' check battery voltage 3V should be ok
' sertxd(" ",#scratch,CR,LF)
if scratch > 153 then ' 255/5v*3v = 153
high Green_LED
else
low Green_LED ' battery needs to be replaced
endif
poke ADCtime,0 ' restart 1-hour clock
endif
loopCnt = 0
endif
endif
loop
Note that if the system can't do any meaningful work while on battery, the technique often suggested by Dr_Acula might be less trouble--save indicator variables in eeprom (non volatile), and when you restart after a power failure, check those variables so that you can recommence where you left off.
According to my DVM, this setup on batteries takes 31 microamps, blipping up briefly when the LED flashes to between 50 and 155 microamps (the capacitor is taking up some of the slack).
Attachments
Last edited: