0

I am using an Arduino Pro Mini with various sensors. I am powering it with 2 3.7v 3400mA batteries which I recharge with a solar panel. I take a reading from the batteries and if the reading is above a certain number I disconnect the solar panel from the batteries using a relay. Then when the battery reading gets below a certain number I switch back on the solar panel using the same relay. This all works fine. To conserve energy I want to delay the loop to the Arduino's activities for say two hours. Right now I call lowPower(); at the end of the loop{. void lowPower(){ is

LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

Which I continually repeat for the two hours I want. The problem is during this two hours the high or low limit of the battery charge could be reached but I wouldn't know it.

What I would like to do is repeat

LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

for 15 minutes and then check the batteries and turn on or off the solar charger as need. Then repeat the whole thing until two hrs is reached. At that point I would rerun the loop{ to check all sensors etc. I have tried the following

   void loop(){
    //code to run other sensors etc.
    if (Delay ==4) {
  delay(180000);
//check the battery to begin with
sensorBatValue = analogRead(batteryInPin);
  delay(500);
if(chargeSwitch ==1){
 if(sensorBatValue < batteryNoCharge) {
  }
 else if(sensorBatValue > batteryNoCharge) {
     digitalWrite(10,HIGH);
   delay(1000);
   digitalWrite(10,LOW);
   chargeSwitch = 2;
  }
   }
else if(chargeSwitch ==2){
    if(sensorBatValue > batteryCharge) {
    }
    else if(sensorBatValue < batteryCharge) {
      digitalWrite(13,HIGH);
    delay(1000);
   digitalWrite(13,LOW);
   chargeSwitch = 1;
    }
  }
//put to sleep
lowPower();
//check battery again
delay(180000);//real
sensorBatValue = analogRead(batteryInPin);
  delay(500);
if(chargeSwitch ==1){
 if(sensorBatValue < batteryNoCharge) {
  }
 else if(sensorBatValue > batteryNoCharge) {
     digitalWrite(10,HIGH);
   delay(1000);
   digitalWrite(10,LOW);
   chargeSwitch = 2;
  }
   }
else if(chargeSwitch ==2){
    if(sensorBatValue > batteryCharge) {
    }
    else if(sensorBatValue < batteryCharge) {
      digitalWrite(13,HIGH);
    delay(1000);
   digitalWrite(13,LOW);
   chargeSwitch = 1;
    }
  }
// put to sleep
lowPower();
//repeat for total of 2 hours.
}

 void lowPower(){
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    //repeat until 15 minutes is reached
}

This doesn't seem to work. The Arduino waits the correct time but from what I can tell the battery is never checked.

Or should I try

    void loop(){
    everything
    if (Delay ==4) {
  delay(180000);//real
  sensorBatValue = analogRead(batteryInPin);
  delay(500);
if(chargeSwitch ==1){
 if(sensorBatValue < batteryNoCharge) {
  }
 else if(sensorBatValue > batteryNoCharge) {
     digitalWrite(10,HIGH);
   delay(1000);
   digitalWrite(10,LOW);
   chargeSwitch = 2;
  }
   }
else if(chargeSwitch ==2){
    if(sensorBatValue > batteryCharge) {
    }
    else if(sensorBatValue < batteryCharge) {
      digitalWrite(13,HIGH);
    delay(1000);
   digitalWrite(13,LOW);
   chargeSwitch = 1;
    }
  }
    //include the checking of the battery inside the lowPower
    void lowPower(){
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    etc.
    LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);
    //check battery after 15 min.
    delay(500);
       sensorBatValue = analogRead(batteryInPin);
    delay(500);
    if(chargeSwitch ==1){
     if(sensorBatValue < batteryNoCharge) {
     }
     else if(sensorBatValue > batteryNoCharge) {
         digitalWrite(10,HIGH);
       delay(1000);
       digitalWrite(10,LOW);
       chargeSwitch = 2;
      }
       }
    else if(chargeSwitch ==2){
        if(sensorBatValue > batteryCharge) {
       }
        else if(sensorBatValue < batteryCharge) {
          digitalWrite(13,HIGH);
        delay(1000);
       digitalWrite(13,LOW);
       chargeSwitch = 1;
        }
      }
    //then repeat to two hours
    }

Do I need to do something to wake up the Arduino and Turn on the battery sensor pin and turn back on ADC?

Not sure how to do this Please HELP.

  • Please don't post pseudo code (how should we know what condition is?) and indent your code properly. I'm not going to solve that puzzle... – Sim Son Nov 9 at 13:34
0

Try to use an external timer. I have the same problem approximatly.

  • I don't want to use an external timer as that adds energy costs. There should be a way to do this. – user1114881 Nov 9 at 15:04
0

In your function lowPower(), instead of repeating the LowPower.powerDown(), loop over that call enough time to make up the total sleep-time you need. That's the general case. For your specific case, where you need 15-minute intervals and 2-hour intervals, lowPower() should loop 113 times (15:04, since 15 *60 doesn't divide evenly by 8). In your loop() function, loop over lowPower() 8 times (to make 2 hours), and each time it returns, check your battery. When the loop over lowPower() exits, it's time to do your "every 2 hours" jobs.

Because the 8s doesn't evenly divide 15 minutes, this timing isn't exact (but neither is the watchdog timer!), so you may want to tweak things a little, such as using a 4-second sleep, which does divide evenly.

Also, when I indented your code, I found void lowPower() nested inside the loop() function. C doesn't support that. If that was unintentional, check the pairing of your braces.

0

Here's a sketch that uses the LowPower library. You'll have to "tweak" the batteryCounter and sensorCounter variables to get the times a little closer to your specifications.

#include "LowPower.h"
unsigned int sleepCounter = 0;
unsigned int sleepCounter2 = 0;
unsigned int batteryCounter = 110; // 8 sec X 110 = 15 min approx.
unsigned int sensorCounter = 900;  // 8 sec X 900 = 2 hours approx.
unsigned int voltageReading = 0;

void setup(){

  // Test using pin 13 and Serial Monitor.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.begin(9600);

}

void loop(){

  // Enter power down state for 8 seconds.
  LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  

  // Increment counters. 
  sleepCounter++;
  sleepCounter2++;

  // Check the battery voltage.
  if(sleepCounter == batteryCounter){

    // Reset the counter.
    sleepCounter = 0;

    delay(10);
    voltageReading = analogRead(A0);

    // Turn the built in LED On for 1 second then Off.
    // Send the voltage reading to the Serial Monitor.
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    Serial.print("Voltage=");
    Serial.println(voltageReading);
    Serial.flush();
  }

  // Check the sensors.
  if(sleepCounter2 == sensorCounter){

    // Reset the counter.
    sleepCounter2 = 0;

    // Turn the built in LED On for 2 seconds then Off.
    // Send a message to the Serial Monitor.
    digitalWrite(LED_BUILTIN, HIGH);
    delay(2000);
    digitalWrite(LED_BUILTIN, LOW);
    Serial.println("Checking Sensors.");
    Serial.flush();
  }

}
0

You have to note that if you go in "power down" mode, you will not be able to get the time as millis() will return the wrong time.

If you just want 15 minutes, you can just put it inside a for loop:

for(int j=0;j<112;j++) LowPower.powerDown(SLEEP_8S,ADC_OFF,BOD_OFF);

So the next instruction will be executed approximately after 15 minutes (15 * 60 / 8 = 112).

I made a similar project with a Teensy. With it you have more functions for the time. Just remember that with the power down, you will not be able to have any time function without an external time module on the Arduino.

Battery measurement schematics is also important. If you insert 2 resistors like 1M and 4M you will not be able to measure it since the measurement is done internally over multiple measurements and the current is not enough to measure it more than 1 time every 10-20ms. You have to add a capacitor to read a good value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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