How to use the SLEEP_MODE_PWR_DOWN ?!

Hi everybody !!
I’m Valentin (17 yo), a French beginner in programmation and Arduino too. Last year, I decided to create an independant hen house (with Arduino and solar panel too). However, I think my Uno consumes too much. In fact, the hen’s door closes at night but, at morning…nothing happends !! I have a 9V Li-ion 1000mAh rechargeable battery (charging time : approximately 7 hours).
Here is three possibilities :
-I have a energy leakage somewhere ;
-The Arduino card consumes too much ;
-My SLEEP_MODE_PWR_DOWN is not efficient (or poorly implemented).
I have to tell you that I’m stuck… Any help would be welcome!!

Here is my code :

#include<avr/wdt.h>
#include<avr/interrupt.h>
#include<avr/sleep.h>
#include<avr/power.h>

#define led 13

int nbr_remaining;

int analogPin=2;
int analogValue=0;
int ledPin=8;
int led2Pin=5;
int ouvert=0;
int ferme=0;
const int switchPin1 = 2;
const int switchPin2 = 7;

ISR(WDT_vect){
  wdt_reset();
}

/////////////////////////WDT////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void configure_wdt(void){
  cli();
  MCUSR = 0;
  WDTCSR |= 0b00011000;
  WDTCSR = 0b01000000 | 0b100001;
  sei();
}

/////////////////////////SLEEP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void sleep(int ncycles){
  nbr_remaining = ncycles;
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  power_adc_disable();

  while (nbr_remaining > 0){
    sleep_mode();
    sleep_disable();
    nbr_remaining = nbr_remaining - 1;
    
  }
  power_all_enable();    
}

/////////////////////////SETUP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {

  Serial.begin(9600);
  pinMode(ledPin,OUTPUT);
  pinMode(led2Pin,OUTPUT);
  pinMode(12,OUTPUT);
  pinMode(9,OUTPUT);

  pinMode(switchPin1, INPUT); 
  digitalWrite(switchPin1, HIGH);
  pinMode(switchPin2, INPUT); 
  digitalWrite(switchPin2, HIGH);

  pinMode(led, OUTPUT);
  digitalWrite(13, LOW);
  delay(1000);

  configure_wdt();

}

/////////////////////////BAISSER TRAPPE/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void baisser_trappe(){
   digitalWrite(12,LOW);
   digitalWrite(9,LOW);
   analogWrite(3,255);
}
/////////////////////////LEVER TRAPPE///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void lever_trappe(){
   digitalWrite(12,HIGH);
   digitalWrite(9,LOW);
   analogWrite(3,255);
}

/////////////////////////ARRETER////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void arreter(){
   digitalWrite(9, HIGH);
}

/////////////////////////LED////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void led_temoin(){
  digitalWrite(ledPin, HIGH);
  delay(1800000);
  digitalWrite(ledPin, LOW);
}
/////////////////////////LOOP///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {

  analogValue = analogRead(analogPin);
  Serial.println(analogValue);
  
  if (analogValue > 105){
    
      if (ouvert == 0){
          digitalWrite(ledPin,LOW);
          lever_trappe();
          
          if (digitalRead(switchPin1) == LOW){
              arreter();        
              ouvert = 1;
              ferme = 0;
              delay(2000);
              sleep(1);
              
          }else{
              lever_trappe();
         }
     }else{
         sleep(1);      
      }
}

  else{
    
      if (ferme == 0){
        
          digitalWrite(ledPin,HIGH);
          digitalWrite(led2Pin, HIGH);
          delay(500);
          digitalWrite(ledPin,LOW);
          digitalWrite(led2Pin, LOW);
          delay(500);
          digitalWrite(ledPin,HIGH);
          digitalWrite(led2Pin, HIGH);
          delay(500);
          digitalWrite(ledPin,LOW);
          digitalWrite(led2Pin, LOW);
          delay(500);
                              
          baisser_trappe();
          
          if (digitalRead(switchPin2) == LOW){
              arreter();
              led_temoin();
              ouvert = 0;
              ferme = 1; 
              delay(2000);
              sleep(1);   
              
          }else{
              baisser_trappe();
          }
      }else{
         sleep(1);
   }
  }
 }

A_SYS_POULES___SLEEP_MODE_PWR_DOWN.ino (4.68 KB)

A UNO (or its more practical version, the Nano) is the wrong choice for battery operation. A Pro Mini is the appropriate one.

The USB interface consumes power and is not a part of battery operation in any case. You would want to disable the pilot LED and the regulator to get the sleep mode really down. When I say you should not be using the regulator, why are you using a 9 V battery? You would need to select a very efficient switchmode regulator with negligible quiescent current to convert from 9 to 5 V if you are using the 5 V for anything else.

What sort of motor is operating the door? Not a servo to be sure. :roll_eyes:

In fact, there is a motor shield on my Uno, so I can't use a nano (even though I would have liked). Plus, I must use a 9V battery because my motor is a DC motor 12 V (under-fed). However, is my code good ?
Thanks for your answer !!

PS : here is my motor : https://www.amazon.fr/Electrique-Réduction-Réversible-Turbine-Engrenages/dp/B0752SM4XG/ref=sr_1_3?__mk_fr_FR=ÅMÅŽÕÑ&crid=1C2EZQBU6XT90&dchild=1&keywords=moteur%2B12%2Bvolt%2Bcouple&qid=1592210600&sprefix=moteur%2B12%2Bv%2Caps%2C137&sr=8-3&th=1


OK, that is a very respectable motor. :grinning:

I suspect however that your so-far-unknown motor shield, together with the USB chip on the UNO and anything else you have omitted to mention, are drawing a consistent 50 to 100 mA which over a 12 hour period will drain your battery notwithstanding the ATmega328 sleeping.

Yeah. That's what's most likely... However, I use this type of motor shield : https://www.amazon.fr/Shield-dextension-Conducteur-Arduino-Mega2560/dp/B01LVXM0JS/ref=sr_1_6?__mk_fr_FR=ÅMÅŽÕÑ&crid=1XPHL8WUKIY9L&dchild=1&keywords=shield+motor+arduino&qid=1592229523&sprefix=shield+motor+%2Caps%2C152&sr=8-6

So, how can I reduce this consumption to run my program all night ?
Thanks for your answers :wink:

I would also strongly recommend a Pro Mini, and to use a modern, much efficient motor driver module, like those from Pololu. The ancient L298 on your shield wastes about as much energy as the motor uses.

You can cut power dissipation down to essentially zero during sleep. All you need to know is in this excellent tutorial on power saving methods. The Arduino alone can run for years on 2xAA batteries with these methods.

Ok. Thanks. I'll check that soon :wink:
Good afternoon
Valentin