Pages: 1 [2] 3   Go Down
Author Topic: Power saving in code for extended battery life.  (Read 4593 times)
0 Members and 1 Guest are viewing this topic.
United Kingdom
Online Online
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

hi dc42,
thanks for your very informative reply. i think it going to take me a while to digest all of that, there are a few things i dont understand and will have to google. like the "analog comparator function".
Quote
Preferably, use the internal 128KHz RC oscillator, which requires programming the fuses. If you don't want to program the fuses, you can still get a substantial power reduction by writing to the clock prescaler register, which allows the clock frequency to be divided by up to 256.
can either of these be done with the standard arduino board?

See the datasheet http://www.atmel.com/Images/doc8271.pdf for details of the analog comparator function and the clock prescaler. You can use both of these on a standard Arduino, but not switch to the internal 128KHz oscillator.

The following (untested) tested code should switch the clock prescaler to 256:

  CLKPR = 0x80;   // set the CLKPCE bit
  CLKPR = 0x08;   // set the prescaler to 256
« Last Edit: May 03, 2012, 07:18:38 am by dc42 » Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for testing that,
So i have put
  CLKPR = 0x80;   // set the CLKPCE bit
  CLKPR = 0x08;   // set the prescaler to 256
into my setup function, is that correct?
am i also correct in changing all my references to milliseconds to /256 eg Delay(50/256);  ?

in reading about the analogue comparator; i am reading the pdf u linked for me. i can see where its says what the analogue camparator does and that it has a few different ways of running. I think one of these 2 modes is what i need
Quote
• Bit 4 – ACI: Analog Comparator Interrupt Flag
This bit is set by hardware when a comparator output event triggers the interrupt mode defined
by ACIS1 and ACIS0. The Analog Comparator interrupt routine is executed if the ACIE bit is set
and the I-bit in SREG is set. ACI is cleared by hardware when executing the corresponding interrupt
handling vector. Alternatively, ACI is cleared by writing a logic one to the flag.
• Bit 3 – ACIE: Analog Comparator Interrupt Enable
When the ACIE bit is written logic one and the I-bit in the Status Register is set, the Analog Comparator
interrupt is activated. When written logic zero, the interrupt is disabled.
but i cant see where it says how to use it. im sorry, i must seam like an utter nonse to you. probaly because i am. smiley-razz

as far as wiring it up goes i think i need:
  a voltage divider on one pin to input around 4volts to the pin
  the photo transistor and a resistor on another pin for the ACI to compare the first pin
what pins on the arduino can be used for the analogue comparator?
Logged

United Kingdom
Online Online
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

So i have put
  CLKPR = 0x80;   // set the CLKPCE bit
  CLKPR = 0x08;   // set the prescaler to 256
into my setup function, is that correct?
am i also correct in changing all my references to milliseconds to /256 eg Delay(50/256);  ?

Yes and yes.

in reading about the analogue comparator; i am reading the pdf u linked for me. i can see where its says what the analogue camparator does and that it has a few different ways of running. I think one of these 2 modes is what i need
Quote
• Bit 4 – ACI: Analog Comparator Interrupt Flag
This bit is set by hardware when a comparator output event triggers the interrupt mode defined
by ACIS1 and ACIS0. The Analog Comparator interrupt routine is executed if the ACIE bit is set
and the I-bit in SREG is set. ACI is cleared by hardware when executing the corresponding interrupt
handling vector. Alternatively, ACI is cleared by writing a logic one to the flag.
• Bit 3 – ACIE: Analog Comparator Interrupt Enable
When the ACIE bit is written logic one and the I-bit in the Status Register is set, the Analog Comparator
interrupt is activated. When written logic zero, the interrupt is disabled.
but i cant see where it says how to use it. im sorry, i must seam like an utter nonse to you. probaly because i am. smiley-razz

as far as wiring it up goes i think i need:
  a voltage divider on one pin to input around 4volts to the pin
  the photo transistor and a resistor on another pin for the ACI to compare the first pin

That's one way, although it assumes that the analog comparator is OK with a common mode input voltage of 4V on a 5V supply. I would use the internal bandgap reference to provide the other input. It's about 1.1v, so in this case it would be best to wire the input pin with the phototransistor between the pin and +5v, and resistor between the pin and ground.

From the datasheet, it looks like the analog comparator takes 70uA @ 5V and the bandgap reference takes about 10uA. So if you are using the watchdog timer to wake the unit up regularly, I suggest you power these units down when you put the device to sleep.

what pins on the arduino can be used for the analogue comparator?

From the diagram on page 248, the +ve input of the comparator can be selected to be either the bandgap reference or pin Ain0. The -ve input can be either Ain1, or (when you are not using the ADC) any of the analog input pins. The pin mapping diagram at http://arduino.cc/hu/Hacking/PinMapping shows that Ain0 is digital pin 6 and Ain1 is digital pin 7.
Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Anchorage, AK
Offline Offline
Edison Member
*
Karma: 42
Posts: 1176
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://arduino.cc/it/Hacking/PinMapping168

Looks like pins 12 and 13 (D6 and D7).

A regulator is only necessary if you're trying to keep a constant voltage from a source either too high to run directly, or too variable to run reliably.  Batteries are fine.  You may want to devise a low-battery alarm or power-off though.  (Look into the on-chip brown-out detector.)
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i dont think burning a new boot loader or changing fuses is for me at this stage, so the BOD might be a bit hard.

I was under the impression that running from a 9v and regulating it to 5v would produce a longer life as there is 5v it can drop whereas if i used a 6v hooked up without regulation there is only 2v to drop before its considered flat.

will a low voltage cut off draw more power? im not sure that it is entirely necessary, i have discovered already that with flat batteries the PIR trips constantly, so i will have a pretty good idea when the batteries run down.

any thoughts on the TDA3664? ive fond them on ebay and am waiting to hear before i buy some.

Quote
http://arduino.cc/it/Hacking/PinMapping168

Looks like pins 12 and 13 (D6 and D7).
That's great, defiantly helps make more sense of the datasheet.
any idea what the code would look like for a analogue comparator interrupt?
im looking at the nightingale sketch for a bit of inspiration but as it sleeps and wakes on a timer not an interrupt i dont think its much use.

i have devised this from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1272923299 and the nightingale sketch:
Code:
#include <avr/sleep.h>
ACSR =
 (0<<ACD) |   // Analog Comparator: Enabled
 (0<<ACBG) |   // Analog Comparator Bandgap Select: AIN0 is applied to the positive input
 (0<<ACO) |   // Analog Comparator Output: Off
 (1<<ACI) |   // Analog Comparator Interrupt Flag: Clear Pending Interrupt
 (1<<ACIE) |   // Analog Comparator Interrupt: Enabled
 (0<<ACIC) |   // Analog Comparator Input Capture: Disabled
 (1<<ACIS1) | (1<ACIS0);   // Analog Comparator Interrupt Mode: Comparator Interrupt on Rising Output Edge

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

}
Code:
ISR(ANALOG_COMP_vect )
{
lightReading = analogRead(lightPin);
if(lightReading > 1000) {
  Wakeup                           <<--- whats the code for this??
}
this will obviously have to be inserted into my original sketch. i am yet to test it as i dont know what the code will be to compare the analog signals or to wake up.
Logged

Boston, MA
Offline Offline
Full Member
***
Karma: 0
Posts: 129
Batteries? We don't need no steenking batteries!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like people have beat me to all of the good answers ;-)

Quote
I was under the impression that running from a 9v and regulating it to 5v would produce a longer life as there is 5v it can drop whereas if i used a 6v hooked up without regulation there is only 2v to drop before its considered flat.

There is some truth to that (the discharge curve of alkalines is anything but flat), but also consider what a "9V" battery actually is: if you saw one open, it is 6 "AAA" cells (actually something much smaller) wired in series! So the internal resistance is higher, and a lot of the space in the battery is wasted (round cells in a square case), so the capacity (mAh rating) per $ and per volume is not great. You may get much better runtime from 4 "AA" (or larger if you have room) cells in series, even if the voltage "headroom" is less.

Quote
will a low voltage cut off draw more power? im not sure that it is entirely necessary, i have discovered already that with flat batteries the PIR trips constantly, so i will have a pretty good idea when the batteries run down.

In general a low-battery cutoff will draw "some" extra ("some" may not be enough to worry about; there are very efficient circuits/ICs for this nowadays), but it sounds like you wouldn't need it anyway :-)

Quote
any thoughts on the TDA3664? ive fond them on ebay and am waiting to hear before i buy some.

Here is the datasheet for TDA3664 - looks good! Some lesser leakage ones exist (I am partial to Microchip's MCP170x family, but not sure if you have easy access to those) but 15uA is pretty respectable. And sometimes "available" is the most important spec of all!
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Looks like people have beat me to all of the good answers ;-)
i dunno, think you doing pretty well...
Quote
There is some truth to that (the discharge curve of alkalines is anything but flat), but also consider what a "9V" battery actually is: if you saw one open, it is 6 "AAA" cells (actually something much smaller) wired in series! So the internal resistance is higher, and a lot of the space in the battery is wasted (round cells in a square case), so the capacity (mAh rating) per $ and per volume is not great. You may get much better run time from 4 "AA" (or larger if you have room) cells in series, even if the voltage "headroom" is less.
i have pulled apart a 9v when i was a kid, so i can picture what your saying. I see what you mean.
the MCP1702 are sourceable, but not economically with the postage. .50c item with $12 postage   smiley-eek
What sort of battery life would you expect if i did away with the regulator and its 2 capacitors, hooked up it directly to 4x 2500mAH rechargable NiMH which are 1.2V fully charged? Assuming i can get the sleep code working too. know how to wake it after its sleeps, and is the sleep method from the nightingale sketch the way to go?
Logged

United Kingdom
Online Online
Tesla Member
***
Karma: 224
Posts: 6619
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

What sort of battery life would you expect if i did away with the regulator and its 2 capacitors, hooked up it directly to 4x 2500mAH rechargable NiMH which are 1.2V fully charged? Assuming i can get the sleep code working too. know how to wake it after its sleeps, and is the sleep method from the nightingale sketch the way to go?

If you use regular NiMH cells, they will lose their charge through self-discharge in a small number of months. If you use low self-discharge (also called hybrid) cells, they should last longer than a 9v battery, probably several years if you get the current consumption low enough. The starting voltage of a fully charged NiMH cell can be as high as 1.4v so you may briefly be running the processor at 5.6v.

Another possibility is 3 x lithium AA cells. These have a long shelf life and flat discharge curve, see http://data.energizer.com/PDFs/l91.pdf.
« Last Edit: May 04, 2012, 03:20:45 am by dc42 » Logged

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The starting voltage of a fully charged NiMH cell can be as high as 1.4v so you may briefly be running the processor at 5.6v.
The batteries ive got ive had for a while and tested them alot, after a full charge they sit at 1.2V. so i dont think ill be running the risk of running at over 5v. What is the likelihood of causing damage by doing this out of interest?
Because i already have loads (like 30) NiMH hanging around, ild be inclined to use them. If i can get a couple of months out of them a few times in a row, then ild probably go get some of them lithums. that datasheet was a good one, i like the look of the graph for Lithium vs Alkaline for low current continuous usage. very steady.

the last bit of info ill need before i go and make all these changes is to know for sure that the "void system_sleep()" function is from the nightingale is right for me and how to wake it up from the "ISR(ANALOG_COMP_vect )"
Logged

Anchorage, AK
Offline Offline
Edison Member
*
Karma: 42
Posts: 1176
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Another thing about regulators:  Even the most efficient regulators are not 100% efficient.  Linear regulators are far, far from efficient.  So, if you're dropping 4v from a 9v to reach 5v, that's 4v that's just heating the air around your regulator.  This pretty much scraps any advantage from trying to conserve power through sleep modes.  Running it direct from batteries removes this waste.

The ATmegas are rated to 5.5v, so while four alkalines might be pushing it (don't fresh ones start around 1.45 or so?  I don't know), NiMH would likely be just fine.  Remember, 5.5v is the serving suggestion.  The actual capabilities of the chip could be well beyond that.  (You take a risk if you overvolt it, but if it's worth the $4 to you to try it and see what happens, by all means.. give it a shot.)

Fuses aren't bad.  Don't be intimidated, just devote an afternoon to reading up on them.  There are online calculators that let you pick your options and it'll spit out the values.  Then, you follow a tutorial on using avrdude from the command line -- which also isn't a big deal.  You can just about copy the command line used by the IDE.

The BoD would be worth it, in my opinion.  I would rather have a clear indication when the batteries need to be swapped than slowly having performance turn to crap.  Ultimately, it's your call, just don't let having to set fuses scare you off.  It's not hard.
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12928
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
so while four alkalines might be pushing it (don't fresh ones start around 1.45 or so?  I don't know)

The ones I use start life at 1.6 volts, quickly run down to 1.5 volts, very slowly run down to 0.8 volts (almost linearly), at which point they are effectively dead.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Guys,

Ive almost got it all working! smiley-grin
i have the analog interrupt working and it going to sleep and the clock being wound back. all great.

BUT....

i cannot get the analog interrupt to trigger while its is in sleep mode! smiley-sad

please, what am i doing wrong now?

here is the relevent bits of code:
Code:
#include <avr/sleep.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
Code:
void setup(){
ACSR =
 (0<<ACD) |   // Analog Comparator: Enabled
 (1<<ACBG) |   // Analog Comparator Bandgap Select: AIN0 is applied to the positive input
 (0<<ACO) |   // Analog Comparator Output: Off
 (1<<ACI) |   // Analog Comparator Interrupt Flag: Clear Pending Interrupt
 (1<<ACIE) |   // Analog Comparator Interrupt: Enabled
 (0<<ACIC) |   // Analog Comparator Input Capture: Disabled
 (1<<ACIS1) | (0<ACIS0);   // Analog Comparator Interrupt Mode: Comparator Interrupt on Rising Output Edge
Code:
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

}
Code:
ISR(ANALOG_COMP_vect )
{
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
    sleep_disable();                     // System continues execution here when watchdog timed out
    sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
    wake = 1;
}
Logged

Global Moderator
Dallas
Online Online
Shannon Member
*****
Karma: 207
Posts: 12928
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here

From the datasheet...

Quote
When entering Idle mode, the Analog Comparator should be disabled if not used. When entering ADC Noise Reduction mode, the Analog Comparator should be disabled. In other sleep modes, the Analog Comparator is automatically disabled.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Guys,
Thanks for all your help. ive finally got it finished. Ended up using a couple of watchdogs as i could not get the Analog Comparator to work in sleep mode.
Quote
In other sleep modes, the Analog Comparator is automatically disabled.
"Automatically", i couldn't find the manual on. and sleeping to IDLE mode wasnt going to give the power savings needed, so watchdog timers set to differing lengths for different light levels and slowing the clock down.
Could not have a slow clock while fading on the lights as analogWrite doesn't work properly and the lights flash on and off instead of fade till the are on. i worked around that with 2 little subroutines.

here are my initial power consumption results:
Quote
   
  • it draws 22mA (both with the PIR off or on)
  • it draws 47mA when LED's are at full brightness (for 9 seconds)
   
here they are now:
    In dark: 0.03mA - 4mA (16 Second sleep)
    In Light: 0.3mA - 5mA (1/2 Second Sleep)
    LED on: 40.7mA (on for 4 Seconds)
Last night tested battery at 5.18v at 8:30PM and tested again at 8:30am (12 Hours) 5.1v

Thanks so much for everyones help. been a great learning.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
I love YaBB 1G - SP1!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey Great project! I have a write up about a similar project posted on my blog that friend just finished. He had the same problems but ended up tackling them in different ways. You might want to take a look since the project is so similar.

http://n0m1.com/2012/05/13/mday-low-power-motion-sensor-arduino-night-light/

We wrote an arduino sleep library that was used in the project. It has both wake from interrupt as well as watchdog sleep. Its here:
https://github.com/n0m1/Sleep_n0m1

I hope this helps someone out!
Logged

Pages: 1 [2] 3   Go Up
Jump to: