1

I made project using atmel-328p. I want to run it over a year. I am using power_down mode & 5500 mAh li-ion battery still battery discharges in 1 day. I am using standard code as explain on arduino site. code is:

String uniqueid;
char value;
volatile int NbTopsFan; //measuring the rising edges of the signal
uint32_t Calc;                               
int hallsensor = 2;    //The pin location of the sensor
int power = 4;
// ph sensor
define SensorPin 0          //pH meter Analog output to Arduino Analog Input 0
define Offset 0.00            //deviation compensate
unsigned long int avgValue;    //Store the average value of the sensor feedback
// temp sensor
OneWire  ds(8);     
byte i;
byte present = 0;
byte data[12];
byte addr[8];
int HighByte, LowByte, SignBit, Whole, Fract, TReading, Tc_100, FWhole;

int wakePin = 3;                 // pin used for waking up
int sleepStatus = 0;             // variable to store a request for sleep
int countsleep = 0;                   // counter

void wakeUpNow()        // here the interrupt is handled after wakeup
{// execute code here after wake-up before returning to the loop() function
 }
void rpm ()     //This is the function that the interupt calls 
{ 
 NbTopsFan++;  //This function measures the rising and falling edge of the 
//hall effect sensors signal
} 
void setup()
{
 pinMode(hallsensor, INPUT); //initializes digital pin 2 as an input
Serial.begin(9600); //This is the setup function where the serial port is 
pinMode(power, OUTPUT);
//initialised,
 attachInterrupt(0, rpm, RISING); //and the interrupt is attached
//initialised,
  //and the interrupt is attached
// temp sensor pin 8
        if ( !ds.search(addr)) 
        {
           //       Serial.println("temp sensor is not connected");
        delay(1000);
        ds.reset_search();
        return;
        }
        if ( OneWire::crc8( addr, 7) != addr[7]) 
        {
       //      Serial.println("CRC not valid!");
       delay(1000);
       return;
        }     
pinMode(wakePin, INPUT);

  attachInterrupt(1, wakeUpNow, LOW); // use interrupt 1 (pin 3) and run function

}

void sleepNow()         // here we put the arduino to sleep
{
  countsleep = 0;
ADCSRA = 0;  

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

    sleep_enable();          // enables the sleep bit in the mcucr register
                             // so sleep is possible. just a safety pin
  // turn off brown-out enable in software
  MCUCR = bit (BODS) | bit (BODSE);  // turn on brown-out enable select
  MCUCR = bit (BODS);        // this must be done within 4 clock cycles of above                          

 sleep_cpu ();  

    attachInterrupt(1,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function
                                       // wakeUpNow when pin 2 gets LOW

    sleep_mode();            // here the device is actually put to sleep!!
                             // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

    sleep_disable();         // first thing after waking from sleep:
                             // disable sleep...
    detachInterrupt(1);      // disables interrupt 0 on pin 2 so the
                             // wakeUpNow code will not be executed
}

void loop()
{

  countsleep++;
  delay(1000);                           // waits for a second
// compute the serial input
  if (Serial.available()) 
  {
    String content = "";
    char character;
// to read serial data coming
        while(Serial.available()>0) 
          {
              character = Serial.read();
              content.concat(character);
          }
      String uniqueidread = content.substring(0,16);
      String parameter = content.substring(16,17);
      String checkuuid = content.substring(0,3);
      String putinsleep = content.substring(0,5);
       if (uniqueidread == uniqueid && parameter == "5")
{         //    Serial.flush();
digitalWrite(power,HIGH);
 NbTopsFan = 0;      //Set NbTops to 0 ready for calculations
 sei();            //Enables interrupts
 delay (1000);      //Wait 1 second
 cli();            //Disable interrupts
 Calc = (NbTopsFan * 60 / 7.5); //(Pulse frequency x 60) / 7.5Q, = flow rate 

  digitalWrite(power,LOW);
          getTemp();
          delay(1000);
          getTemp();
          //   printTemp();
      Serial.print("Temp is: ");
           if (SignBit) 
           {  
                Serial.print(" - ");
           }
           if( Whole == 0)
           {
              Serial.print("temp sensor is not connected");
           }
           else
           {
              Serial.print(Whole);
              Serial.print(" C / ");
              Serial.print(FWhole);
              Serial.print(" F");
            }
              Serial.print(", Current Reading = ");
     Serial.print (Calc, DEC); //Prints the number calculated above
            Serial.print(" L/hour");
   phvalue();
            Serial.println("S=m");
              delay(100);
              sleepNow(); 
}

         if ( content == "sleep") 
         {
          Serial.println("S=m");
          delay(100);     // this delay is needed, the sleep 
          sleepNow();     // sleep function called here
         }
}

  if (countsleep >= 10) 
  {
      Serial.println("T=m");
      delay(100);     // this delay is needed, the sleep 
                      //function will provoke a Serial error otherwise!!
      sleepNow();     // sleep function called here
  }
}
      void getTemp() 
          {
              int foo, bar;

              ds.reset();
              ds.select(addr);
              ds.write(0x44,1);

              present = ds.reset();
              ds.select(addr);    
              ds.write(0xBE);

              for ( i = 0; i < 9; i++) {
                data[i] = ds.read();
              }

              LowByte = data[0];
              HighByte = data[1];
              TReading = (HighByte << 8) + LowByte;
              SignBit = TReading & 0x8000;  // test most sig bit

              if (SignBit) {
                TReading = -TReading;
              }
              Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
              Whole = Tc_100 / 100;          // separate off the whole and fractional portions
              Fract = Tc_100 % 100;
              if (Fract > 49) {
                if (SignBit) {
                  --Whole;
                } else {
                  ++Whole;
                }
              }

              if (SignBit) {
                bar = -1;
              } else {
                bar = 1;
              }
              foo = ((Whole * bar) * 18);      // celsius to fahrenheit conversion section
              FWhole = (((Whole * bar) * 18) / 10) + 32;
              if ((foo % 10) > 4) {            // round up if needed
                   ++FWhole;
              }
            }
void printTemp(void) 
{
         Serial.println("");
         Serial.print("Temp is: ");
         if (SignBit) 
         {  
              Serial.print(" - ");
         }
         Serial.print(Whole);
         Serial.print(" C / ");
         Serial.print(FWhole);
         Serial.print(" F");
}
void phvalue()
{
    int buf[10];                //buffer for read analog
    for(int i=0;i<10;i++)       //Get 10 sample value from the sensor for smooth the value
    { 
      buf[i]=analogRead(SensorPin);
      delay(10);
    }
    for(int i=0;i<9;i++)        //sort the analog from small to large
    {
      for(int j=i+1;j<10;j++)
      {
        if(buf[i]>buf[j])
        {
          int temp=buf[i];
          buf[i]=buf[j];
          buf[j]=temp;
        }
      }
    }
    avgValue=0;
    for(int i=2;i<8;i++)                      //take the average value of 6 center sample
      avgValue+=buf[i];
    float phValue=(float)avgValue*5.0/1024/6; //convert the analog into millivolt
    phValue=3.5*phValue+Offset;                      //convert the millivolt into pH value
    Serial.print(" pH:");  
    Serial.print(phValue,2);
    Serial.print(" ");
}

enter image description here

12
  • 1
    Welcome to Arduino SE! Can you please elaborate - what your code does, what is the hardware involved, and even post your full code so we could help you
    – Omer
    Jan 12, 2015 at 15:00
  • My hardware involve atmel-328p, xbee, temp sensor, water flow sensor & pH sensor. I used xbee to wake up atmel-328p using interrupt. When data receive on serial port of atmel using xbee interrupt break the sleep mode. My code is as follows: Jan 12, 2015 at 15:20
  • 1
    I would suggest editing your question and adding that information, which is crucial for answering your question.
    – Omer
    Jan 12, 2015 at 15:21
  • 2
    Try doing some measurements. Remove some components and see which one uses what amount of power. Try removing all components to see if your sleep code works (which it maybe doesn't do correctly, as you're calling sleepmode twice (sleep_cpu and sleep_mode)). PS I'd disable the brownout detection in the fuses. Disabling it using code is very difficult to do right, and the lithium cells protection will kick in way before the brownout detection, so there is no use for it in your case.
    – Gerben
    Jan 12, 2015 at 20:38
  • 1
    What clock frequency are you using? 16MHz? If so, you're running it pretty close to it's minimum voltage for that frequency. Not sure if it is an issue, but maybe your MCU is resetting or running erratically. Anyway, that's probably something to look out for.
    – Ricardo
    Jan 13, 2015 at 15:50

1 Answer 1

4

You need to first check the individual current consumption of all elements:

  • pH sensor,
  • temp sensor,
  • water flow sensor
  • xbee.

Since many of these just have an output pin in addition to +V & GND, this means those have a permanent current consumption that, overall, may possibly drain your battery.

You should then check the datasheets for all these components and see the minimum current consumption (and conditions for this consumption to be achieved).

If the total minimum current for these components is too high for your system, then you can possibly:

  • use an available ATmel digital output pin to power them (and unpower them just before switching the ATmel to low power mode); that's possible only if you stay within current limitations of the MCU (there are current limitation per pin, 20mA IIRC, and total current for the whole MCU)
  • if current consumption is above ATmel limits then you can still use the method above but add a MOSFET in-between so that you limit ATmel current consumption

I strongly advise you this link from Nick Gammon, which is comprehensive and complete.

6
  • Just found out I added this as an answer although I wanted it as a comment (issue of using smartphone with SE...) Sorry for that. I'll try to find time to edit the answer and add some more details then.
    – jfpoilpret
    Jan 12, 2015 at 20:31
  • 1
    OK, Thanks a lot, Now I am trying to measure individual current consumption of all elements, n will update soon. Looking forward for your help and suggestions. Jan 13, 2015 at 9:50
  • Still battery drains in 24 hours, Now I power only standalone Atmel-328 with 3.7 li-ion cell having 5500 mAh capacity. Jan 14, 2015 at 11:10
  • I think you should proceed step by step; your current circuit and code are too complex to start with. Simplify them first then perform some checks. In particular, verify that you spend the expected time in power down mode.
    – jfpoilpret
    Jan 14, 2015 at 12:34
  • Yes, sensor & xbee is draining my battery. I can override with sensor providing power through atmel digital pins. But how can i override xbee power loss because I am using as a external interrupt in my circuit to wake up IC. Jan 15, 2015 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.