Sleep is a special mode of the processor which halts normal program execution and shuts down internal components to reduce power consumption. Once a processor is asleep it can only be awakened by specific events such as an external interrupt from a button press, or a timer counting a period of time.
One thing to note is that sleep modes aren't currently exposed by Arduino's programming library. However, because Arduino is built on the AVR Libc library you can access that library's sleep and power management functions in an Arduino sketch. This example is a little more complex than a typical Arduino sketch because it makes use of these lower level library functions to access sleep modes.
For this example I chose to use the lowest power consumption sleep mode, power-down sleep. In this mode almost all components of the processor are disabled and only an external interrupt, two-wire interface signal, or watchdog timer can wake the processor. Because I need the hardware to wake from sleep after a period of time, I use the watchdog timer to wake from power-down sleep.
The watchdog is a component inside the AVR processor which resets the processor if it detects normal program execution has stopped. Typically the watchdog is used to make an unreliable or buggy program run with more stability. However by changing the watchdog control registers, it's possible to use the watchdog as a timer which wakes the processor from power-down sleep instead of reseting it. See section 10.8 of the ATmega328P datasheet for more information on the watchdog.
The hardware for this example is exactly the same as the hardware from the first example. The only changes made are in the software. Load the Example_2_Power_Down_Sleep sketch from the software download in Arduino. Update the configuration in the same way as example 1, and upload the sketch to your hardware.
Looking at the sketch code, the differences from the previous example are:
The watchdog is configured as a timer to wake from sleep.
Inside the setup() function the watchdog control register is changed so the watchdog functions as a timer that fires interrupts instead of resetting the processor. The watchdog timer has a limited configuration of periods, so the maximum period of about 8 seconds is used for this example.
The Arduino is put into power-down sleep mode while sitting idle between measurements.
When the watchdog timer fires every 8 seconds the Arduino will be awakened from sleep. Once awake the Arduino increments a count and after it reaches 7 sleep iterations (roughly 56 seconds) a sensor measurement is logged. Finally, the Arduino is put back into sleep mode while it waits for the watchdog to wake it again.
The CC3000 is disabled while the Arduino is asleep.
In the setup() function communication with the CC3000 is initialized, and then the wlan_stop() function is called to put the CC3000 into a low power disabled state. When the Arduino awakes to take a measurement the CC3000 is enabled by calling wlan_start(), connects to the wireless network to send the measurement, and finally shuts down by calling wlan_stop() again.
For this test I'll use the same AAA Ni-MH batteries as the first example. Looking at the chart of battery capacity at different discharge rates, I'll extrapolate a bit and assume at 45 mA of average current consumption the batteries will have a capacity of 775 mAh.
Expected battery life:
775 mAh / 45 mA = 17.2 hours
In this test the hardware ran for exactly the amount of time expected!
Actual battery life: