0

I have a project which runs a continuous loop and listens for the push of a button to light an led and activate a servo motor on an Arduino Uno (R2). The arduino is powered by 4 AA batteries, and the servo is powered by a 9V. I'm wondering how long I can leave this running off battery power. Does anyone know how to estimate this? As a side note, if anyone spots a way to improve battery life in my sketch / wiring, I'd love to know.

Below is my code and attached is the wiring diagram for the project (minus the batteries).

    #include <Servo.h>

const int buttonPin = 2;     // the number of the pushbutton pin
boolean buttonPushed = false;

const int ledPin =  13;      // the number of the LED pin


const int servoPin = 9;
Servo servo;
int angle = 0;
int servoStartAngle = 90;
int servoEndAngle = 10;

boolean servoActivated = false;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

int photoCellPin = 2;
int photoCellThreshold = 500;
int photoCellActivated = false;


void setup() {
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);

  servo.attach(servoPin);
  servo.write(servoStartAngle);

}

void loop(){
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  int photoCellVal = analogRead(photoCellPin);

  if (photoCellVal > photoCellThreshold){
   photoCellActivated = true; 
  } else {
   photoCellActivated = false; 
  }

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == LOW && buttonPushed == false) {     
    // turn LED on:    
    buttonPushed = true;
    Serial.println("button pushed");
  } else if (buttonState == LOW && buttonPushed == true){
   buttonPushed = false;
   Serial.println('deactivate');
  } 



  if (buttonPushed == true){
   digitalWrite(ledPin, HIGH); 
  } else {
   digitalWrite(ledPin, LOW); 
  }

  if (buttonPushed && servoActivated == false && photoCellActivated == true){
    servoActivated = true;
    Serial.println("activate motor");

    for(angle = servoStartAngle; angle > servoEndAngle; angle--){                                  
      servo.write(angle);
      Serial.println(angle);
      delay(15);    
    } 
  } else if (buttonPushed == false && servoActivated == true){ //deactivate
    for(angle = servoEndAngle; angle < servoStartAngle; angle++){                                  
      servo.write(angle);
      Serial.println(angle);
      delay(15);    
    }
    delay(200);
    servoActivated = false; 

  }

  delay(200);
}
  • First don't use 9V batteries to power motors, they don't contain enough energy to last long. Then, consider using ATmega328 sleep modes (you can wake it on an input pin value, eg your button). Finally, consider ditching the UNO altogether and replace it with a minimal circuit (Arduino boards are not optimized for low consumption, but they are good forprototyping). – jfpoilpret Feb 10 '15 at 22:11
  • I agree. 9V batteries also don't have enough discharge capacity for driving things that need more than a few 100 mA. You can use high capacity AAs for that (NiMH cells for example - but beware of their high self-discharge rates, that may offset any economy you gain by configuring the MCU into low power mode). Also, the voltage regulator on the Uno will consume all of your battery, no matter how you configure the '328 for low power consumption. See this great answer by Anindo Ghosh for more details. – Ricardo Feb 11 '15 at 11:12
  • You would have to disengage the servo, when it's done moving. Otherwise it will continue to draw power. You also can't put the arduino in sleep mode, while the servo is attached, as it needs to be sent position data continuously. In case there is some pressure on the servo; if you connect the gnd and vcc of the servo, it will act like a break. – Gerben Feb 11 '15 at 16:42
  • @jfpoilpret - I will look into the ATmega328 - as far as replacing it with a minimal circuit - I'm afraid my current circuitry knowledge is limited - I'm not even sure I would know where to get started with that. Can you explain or link me to anything that explains how to replace an arduino with a circuit? – mheavers Feb 11 '15 at 23:26
  • ATmega328 is the central intelligence of Arduino UNO. UNO brings a lot of extra stuff that majes it cool for prototyping but not for definitive circuits: typically you won't need USB in the definitive circuit, you won't need voltage regulator if you provide voltage with bateries under 5V overall. For links, google is your firend :-)aybe start with "Arduino on breadboard" that will show you simple circuits to start with. – jfpoilpret Feb 12 '15 at 20:07
3

I'm wondering how long I can leave this running off battery power. Does anyone know how to estimate this?

If your circuit draws 1A @ 12V, a 12V 1Ah battery will power it for approximately one hour. A 9V alkaline typically contains about 565mAh. You can use the datasheets to sum all the power consumption, but its probably easier just to measure it with a multimeter.

As a side note, if anyone spots a way to improve battery life in my sketch / wiring, I'd love to know.

-Check out the ATTiny series (parametric); they are tiny, low-power, and Arduino-compatible; perfect when you only need a couple of pins.

-Use an interrupt to monitor the button's pin; the MCU can sleep until the interrupt fires.

Generally:
1) The interrupt will set a flag so main() knows that something happened, then wake the processor.
2) Main() resumes, checks the flag, turns on/off the LED accordingly, tells the servo where to go, waits for the servo to get there (delay()), clears the flag, and then puts the MCU back to sleep.

-As others have pointed out, delay() is bad. delay() tells the MCU to do nothing (NO-OP) repeatedly, for a period of time. This is different from having nothing to do because it's asleep.

  • Jon - thanks - can you explain a little bit more about an interrupt or link to something where I can learn more about how to set this up? – mheavers Feb 11 '15 at 23:28
  • 1
    Please visit this link from Arduino.cc; the "Using Interrupts" section says it perfectly: arduino.cc/en/Reference/AttachInterrupt – Jon Feb 11 '15 at 23:34
  • Additional: gammon.com.au/interrupts – Jon Feb 11 '15 at 23:43
  • added psuedocode-ish interrupt scenario – Jon Feb 11 '15 at 23:50
  • 1
    If you have issues with the interrupt going off multiple times when you press the button once, search for "how to debounce a button" – Jon Feb 11 '15 at 23:52
1

I can support what mheavers said in a comment above. Use a Bareduino or any kind of custom Board, use sleep-modes and avoid delay(). I wrote a blog-post about my experiences with this setup here, if you get it right the ATmel can go down below 1mA in sleep. In your case an extreme scenario (depending on your usage pattern) could be to wake-up the Arduino with an interrupt triggered through the sensor and otherwise sleep completely. You will find example on the net where people used a setup like this for remote controls for instance.

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.