Go Down

Topic: Turn Arduino On and Off Remotely (Read 8844 times) previous topic - next topic

nickgammon

I thought I would experiment with trying to save even more power. So read up about the Power Reduction Register (PRR).

By using that you can power off internal "peripherals" thus saving even more power. The code below, when used on a  bare-bones board, drops to 25 uA of current (0.025 mA) when in sleep mode. That's about 1000 times less than when awake. Of course, you don't want to power down something you might need but this shows how you can reduce sleep-mode power consumption from 140 uA in my original test to 25 uA - quite a big saving.

Code: [Select]
// Example of sleeping and saving power, and reading a clock
//
// Author: Nick Gammon
// Date:   25 May 2011

#include <Wire.h>
#include "RTClib.h"

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

RTC_DS1307 RTC;

#define CLOCK_POWER 5

#define LED 13

// watchdog interrupt
ISR(WDT_vect) {
  wdt_disable();  // disable watchdog
  sleep_disable();          // disables the sleep bit in the mcucr register
}

void myWatchdogEnable(const byte interval) {  // turn on watchdog timer; interrupt mode every 2.0s
  MCUSR = 0;                          // reset various flags
  WDTCSR |= 0b00011000;               // see docs, set WDCE, WDE
  WDTCSR =  0b01000000 | interval;    // set WDIE, and appropriate delay

  wdt_reset();
 
  // disable ADC
  ADCSRA = 0; 
 
  // power reduction register
  // Bit 7 - PRTWI: Power Reduction TWI
  // Bit 6 - PRTIM2: Power Reduction Timer/Counter2
  // Bit 5 - PRTIM0: Power Reduction Timer/Counter0
  // Bit 4 - Res: Reserved bit
  // Bit 3 - PRTIM1: Power Reduction Timer/Counter1
  // Bit 2 - PRSPI: Power Reduction Serial Peripheral Interface
  // Bit 1 - PRUSART0: Power Reduction USART0
  // Bit 0 - PRADC: Power Reduction ADC
 
  // turn off various modules
  PRR = 0x11101111;
   
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
  sleep_enable();          // enables the sleep bit in the mcucr register
  sleep_mode();            // now goes to Sleep and waits for the interrupt
 
  // stop power reduction
  PRR = 0;
}

void setup()
{
  pinMode (CLOCK_POWER, OUTPUT);
  digitalWrite (CLOCK_POWER, HIGH);  // power up clock
  delay (1);

  Wire.begin();
  RTC.begin();

  // set time in clock chip if not set before
  if (! RTC.isrunning()) {
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }

  digitalWrite (CLOCK_POWER, LOW);  // power down clock
 
}  // end of setup

void loop()
{

  // power up clock
  digitalWrite (CLOCK_POWER, HIGH);  // power up clock
  delay (1);  // give it time to stabilize

  // activate I2C and clock
  Wire.begin();
  RTC.begin();

  // find the time 
  DateTime now = RTC.now();

  // time now available in now.hour(), now.minute() etc.

  // finished with clock
  digitalWrite (CLOCK_POWER, LOW);
 
  // turn off I2C pull-ups
  digitalWrite (A4, LOW);
  digitalWrite (A5, LOW);
 
  // turn off I2C
  TWCR &= ~(_BV(TWEN) | _BV(TWIE) | _BV(TWEA));

  // -------- do something here if required by the time of day

  // in my case flash an LED for 5 seconds
  pinMode (LED, OUTPUT);
  digitalWrite (LED, HIGH);
  delay (5000);
  digitalWrite (LED, LOW);
 
  // sleep bit patterns:
  //  1 second:  0b000110
  //  2 seconds: 0b000111
  //  4 seconds: 0b100000
  //  8 seconds: 0b100001

  // sleep for a total of 20 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100000);  // 4 seconds

}  // end of loop

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

beccacora

Thank you everyone for your answers. Lots of really useful stuff, especially the watchdog and this really helps lengthen battery life.

However, the piece itself will be traveling and therefore not subject to consistent light patterns or hours of operation. It will be installed by the gallery and so cannot be reprogrammed once it leaves my studio to adjust for these changes. So I still really need a way to turn the arduino completely on/off remotely. I'm looking essentially for a pretty dumb switch/relay that doesn't need to be controlled by the arduino. I'm thinking to place it between the power source and the arduino, but my searches haven't yeilded much in the way of the correct hardware, probably because I'm not looking in the correct place.

Does anyone have any suggestions?

nickgammon

While it's actually on the road, a simple switch, surely? They could reach that.

While preparing to install, one idea is a couple of those rotary switches with numbers on it. The gallery could "dial up" the switch on and switch off times, before powering it up, and then the device could read the clock and check if the clock time was inside the dial-up time.

Or make it out of something like this:

http://shop.moderndevice.com/products/jeenode-kit

It's still an Atmega328P processor, but on a minimal board (with low power consumption therefore) but at the end is a small transmitter/receiver. This could be programmed with a simple "turn on/turn off" protocol. Then get a second one as the "remote". The remote sends the power-on/power-off code to the master.

Or if it is too hard to change the design now to use the JeeNode now, just have it there as well, simply acting as an on/off switch. As in, if a digital out from the JeeNode is high, your main board does its stuff, otherwise it goes back to sleep.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

edringel

I addressed this problem in a deep freeze alarm system; I wanted the Arduino to turn once every 10 minutes.  I used a 555CN timer chip to drive a logic level MOSFET-- that's  a MOSFET that turns on fully at only 5 volts gate voltage. The 555CN chip is the classic 555 chip, but implemented using CMOS technology, so it uses very low levels of current. The 555CN chip was independent of the Arduino and all the other electronics.  Every 10 minutes it turned on the MOSFET for 5 seconds and then went back to fully powered down.

You might also look at where your power costs are the greatest-- likely the servo uses much more power than the Arduino. A simple DVM might help you figure out ways of maximizing the efficiency.  It may be that the minimization of Arduino activity is NOT where the paydirt is.  If driving the Arduino is a significant power cost, consider using a DC to DC converter module to get your 12V down to 5V and then powering the board and logic.  If you are plugging the 12V directly into the board, you are wasting a great deal of energy using the Arduino's on-board regulator.

Just some thoughts, hope it helps.

ed

Go Up