Extend Battery Life with Sleep Mode

Hi, I have a project where I use arduinos inside advertising tables. We use several LEDs and a photoresistor. I have around 75 tables to install, but I need the arduino battery to last at least a a week; I am hoping this is possible. What I want is the arduino to wake up every 20 minutes, scan if there is action with the photoresistor for a couple of minutes and then go back to sleep for another 20 minutes and so on.

I am new to the Arduino world, so I have been running plenty of tests but still having trouble.

I am currently using an Arduino One with one Rayovac 9V Alcaline battery, and another battery to for the LEDs. I use to different circuits so I have transistors running each circuit from different LEDpins on the ARDUINO (8 and 9) with the ground from the LED battery going to the Arduino Ground. The circuits works very well, the LED battery does not drains out.

The link below shows one of our tables.

https://www.sugarsync.com/pf/D6610987_7918806_22553

For the program I am using the WatchDog timer to wake it up, but from what I understand I can only use it for 8 secunds, so I set up a counter for 150 times. I also tried the Narcolpetic Library but I couldn´t get to sleep for more than 8 seconds.

Regarding LED program itself what I am doing is getting an average of ten light measurements from the photoresistor (because I have different light conditions in different places and times) and then setting a range, if the last reading is under that range the LED routine starts.

I have been considering using a bigger battery (like a motorcycle battery) or a 555 external timer to cut off the power.

This is my code, it is based on the nightingale program.

//???????????????????????????????????????????????????????????????????????
//???????????????????????????????????????????????????????????????????????
//???????????????????????????????????????????????????????????????????????
//???????????????????????????????????????????????????????????????????????


#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 nint;
int pinLed=13;

volatile boolean f_wdt=1;

//------------------------------------------------------

const int FotoceldaPin1 = 5;
const int ledPin8 =  8;    
const int ledPin9 =  9;   
const int ledPin10 =  10;    


int EstadoSensor1 = 0;
int var = 0; // sumatoria
int rango =0; //valor del rango del sensor de luz
int x = 0; //valor del for
int j=0;
int k = 0;
int y = 0;
int salida = 151; // para salir del ciclo

void setup() {
// initialize the LED pin as an output:
pinMode(ledPin8, OUTPUT);  
pinMode(ledPin9, OUTPUT);
pinMode(ledPin10, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(FotoceldaPin1, INPUT);

Serial.begin(9600); //ver la pantalla en PC


//???????????????????????????????????????????????

  pinMode(pinLed,OUTPUT);
  Serial.println("Setup watchdog");

  // CPU Sleep Modes
  // SM2 SM1 SM0 Sleep Mode
  // 0    0  0 Idle
  // 0    0  1 ADC Noise Reduction
  // 0    1  0 Power-down
  // 0    1  1 Power-save
  // 1    0  0 Reserved
  // 1    0  1 Reserved
  // 1    1  0 Standby(1)

  cbi( SMCR,SE );     // sleep enable, power down mode
  cbi( SMCR,SM0 );     // power down mode
  sbi( SMCR,SM1 );     // power down mode
  cbi( SMCR,SM2 );     // power down mode

  setup_watchdog(9);
 
//??????????????????????????????????????????????????
}

byte del;
int cnt;
int counter = 150; // timer for counting watchdog cicles
long time = 0;





//****************************************************************
//****************************************************************
//****************************************************************
void loop(){

  if (f_wdt==1) {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
    f_wdt=0;     // reset flag

    ///// debuging purpose only /////
    time = millis();
    Serial.print(counter);
    Serial.print(" ");
    Serial.println(time);
    delay(2); //needed for serial.print operation to finish
    /////////////////////////////////////

    if(counter==150)  // if ==10 -> this will be true every 10x8 = 80seconds; set to 225 to get 225x8=1800s = 30min
    {

     //////////////// put code inside this IF ////////

     for (k = 0; k<4; k++){
             //sacar el promedio
        for (x=0; x<10; x++) {
            EstadoSensor1 =  analogRead(FotoceldaPin1); //lee el valor de la fotocelda
            Serial.print(x); Serial.print(": "); Serial.println(EstadoSensor1);
            //delay(250);
            var = var + EstadoSensor1;
         }
            
         var = var / 10;
         Serial.print("promedio: "); Serial.println(var);
            
         rango = var - 25;
   
         Serial.print("rango: "); Serial.println(rango);
         Serial.print("K: "); Serial.println(k);
         delay(1000);            
          for (x=0; x< 150; x++){
            EstadoSensor1 =  analogRead(FotoceldaPin1); //lee el valor de la fotocelda
            Serial.print("lectura: "); Serial.println(EstadoSensor1);
            //delay(250);
              for (j=0; j<1; j++){ //repite esta accion J veces
                   if (EstadoSensor1 <=  rango) {   
                    //enciende las luces de acuerdo con el orden
                      for (y=0; y<3; y++){
                          digitalWrite(ledPin9, HIGH);
                          delay (500);
                          digitalWrite(ledPin9, LOW);
                          delay (250);
                        }
                      delay (000);
                      digitalWrite(ledPin9, HIGH);
                      digitalWrite(ledPin8, HIGH);
                      delay (2000);
                      digitalWrite(ledPin9, LOW);
                      delay(2000);       
                      digitalWrite(ledPin8, LOW);
                
                      x=salida;
                   
                       }
              }
          }
          delay (1000);
          //aqui el programa lo que realiza es un tiempo
          // se suma hasta cumplir 3 minutos aproximadamente
         
     }
    var=0;
     ////////////////////////////////////////////////////

     counter = 0;
    }
    else counter++;

    system_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;
  Serial.println(ww);


  MCUSR &= ~(1<<WDRF);
  // start timed sequence
  WDTCSR |= (1<<WDCE) | (1<<WDE);
  // set new watchdog timeout value
  WDTCSR = bb;
  WDTCSR |= _BV(WDIE);

}
//****************************************************************
// Watchdog Interrupt Service / is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt=1;  // set global flag
}

Any ideas are welcome!!

I am currently using an Arduino One with one Rayovac 9V Alcaline battery

Get a better battery. The 9v rectangular battery is a great battery - if you are making them or selling them. If you are using them, they are lousy choices. Most expensive/least current capacity battery you can buy. 4 AA's are less expensive, last longer, and provide more current, and they take up little more room.

Do you have a specific question, or just looking for general ideas?

Using the watchdog for 8s and then quickly sleeping again for some counter seems to be the most effective way to sleep for long periods. Unless you want to introduce an RTC peripheral which could interrupt at the right time.

Remember that sleeping only sleeps the MCU. If you have a bunch of other current-sucking components like an FTDI chip and a leaky power regulator, that stuff is eating your battery no matter how much the MCU is sleeping. Check out Sparkfun's Arduino Pro or Pro Mini.

Your system is providing power to LED's, so that is taking some power too. A typical 9V battery provides 600mAh at 7.2V (average). Compare that to 6 Lithum AA's which would provide 3000mAh.

Take a look at this application note also, discusses ways to reduce power.

8 MHz Pro mini running 3.7V LiPo wil go a long time if put into power down sleep mode.

Hi, Thnx for all the help. This is what I am doing. I am running 3 different tests with the same program, using Sealed Lead Acid Battery from a UPS 6V 4Ah, a 6V lantern battery (eveready super duty) and 4 AA alcaline batteries. How do I measure the current consumption?

Maniacup: My questions is if its possible to have the arduino up for a week using 20 minutes sleep periods and 3 minutes active peridos in between. I do think my problem are the other components within the arduino which I am not sure I can turn off. I allready have 75 Arduino Uno´s.

CR: Regarding the programming, I am already using the sleep modes, I am not sure if the pins are up. I need to review the clock pre-scale but I am I think that since I need the consecutive 8 second loops this migh be a problem.

How do I measure the current consumption?

You simply place a multimeter (setup for current readings) in series between the battery positive terminal to one lead of the meter the other meter lead wires to the load(s) positive input connection.

Lefty

earroyo05:
I allready have 75 Arduino Uno´s.

Ouch. It would have been better to work all this out on one or two, and then buy all the hardware when you've got the details settled. Arduino Uno's are not ideal for battery-operated usage, so pull out those big batteries!

earroyo05:
My questions is if its possible to have the arduino up for a week using 20 minutes sleep periods and 3 minutes active peridos in between. I do think my problem are the other components within the arduino which I am not sure I can turn off.

This is just an arithmetic problem. Measure current consumption when asleep, measure current consumption when awake, do the math.

I just went through this recently. Here's what I had:

Sleep Consumption 0.114 mA
Operating Consumption 10.4 mA
Sleep Duration 60 s
Operating Duration 0.04 s
Capacity 2300 mAh
Per sleep cycle
Capacity Used Sleeping 6.84 =Sleep_Consumption*Sleep_duration
Capacity Used Operating 0.416 =Operating_Consumption*Operating_Duration
Total Capacity Used mAs 7.256 =Operating_ConsumptionOperating_Duration+Sleep_ConsumptionSleep_duration
Total Capacity Used 0.00201555555555556 =Total_Capacity_Used_mAs/3600
Time Available cycles 1141124.58654906 =Capacity/Total_Capacity_Used
Time Available hours 19018.743109151 =Time_Available_cycles/(3600/Sleep_duration)
Time Available days 792.44762954796 =Time_Available_hours/24
Time Available months 26.414920984932 =Time_Available_days/30