Turn Arduino On and Off Remotely

As an experiment I added a clock breakout board to my bare-bones processor board:

With the clock running all the time the power consumption went up from 0.14 mA to 1.3 mA which wasn't very good. However an amended sketch then powered up the clock by bringing pin 5 high (effectively giving power to the clock) and low again afterwards. This dropped power consumption back to 0.14 mA during sleep, and only 19 mA when awake (this sketch didn't use the LED). So it seems reasonable to power up a clock, find the time, and power it down again quickly. Here is the modified sketch:

// 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

// watchdog interrupt
ISR(WDT_vect) {
  wdt_disable();  // disable watchdog
}

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();
  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
}   // end of myWatchdogEnable

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.


  // -------- do something here if required by the time of day
  
  // finished with clock
  digitalWrite (CLOCK_POWER, LOW); 
  
  // turn off I2C pull-ups
  digitalWrite (A4, LOW);
  digitalWrite (A5, LOW);
  
  // sleep for a total of 20 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100001);  // 8 seconds
  myWatchdogEnable (0b100000);  // 4 seconds

}  // end of loop

// sleep bit patterns:
//  1 second:  0b000110
//  2 seconds: 0b000111
//  4 seconds: 0b100000
//  8 seconds: 0b100001

I wired up the breakout board as follows:

  • Gnd to Arduino Gnd
  • 5V to Arduino D5 (for power on when required)
  • SDA to Arduino A4
  • SCL to Arduino A5