The Freakduino was designed from the ground up to be used in battery operated environments. With this in mind, there were many features that were added to cut down on power. From component selection to how the software was written, the device was designed to survive on very constrained energy resources. To maximize the low power features, it’s important to understand how to configure the Freakduino properly and also to be aware of low power operation when you write the software.
In this tutorial, we’re going to configure the Freakduino to go into deep sleep mode. In this mode, it consumes minimal power. A typical low power application, such as a battery powered wireless sensing device, would be in sleep mode most of the time and then wake up periodically to collect data from the sensors. It would then transmit the data, do any remaining housekeeping tasks, and then go back to sleep. It would do this in an infinite loop.
The Freakduino itself consumes approximately 0.3 mA in sleep mode. This means it could survive for more than six months on 2 AA batteries. In reality, it would consume more than this because it would have to wake up periodically and there would also be peripherals other than the Freakduino that would consume power. However the idea is still the same. We want to shut down all the peripherals and be in as much of a low power state as possible most of the time. Then for the single instant we wake up, we take care of all our tasks, and then immediately sleep again. Before we discuss going into sleep mode though, we need to first discuss how we will wake up.
There are a couple of ways to wake up from deep sleep mode. The most common way to wake up is from an external interrupt. This could be some trigger like a real time clock alarm or some event occurs in the system. In this case, we will use the built-in watchdog timer to wake the system up. The watchdog timer has three modes of operation:
- System Reset
- Interrupt mode
- System Reset and Interrupt mode
The most common use case for the watchdog timer is to use it in system reset mode. This resets the system if anything ever goes wrong, like for instance, the system hangs. We can also configure the watchdog timer to be in interrupt mode. In this mode, it will just generate an interrupt every X number of seconds where X has a maximum of 8 seconds. In our case, this sounds lovely so we will configure the watchdog interrupt for 8 seconds. This means that before we go to sleep, we have to turn on the watchdog timer and after we wake up, we have to turn it off.
First we will configure the watchdog timer
/*** Setup the WDT ***/
/* Clear the reset flag. */
MCUSR &= ~(1<<WDRF);
WDTCSR &= ~(1<<WDE);
WDTCSR |= (1 << WDCE);
Then we will set up the interrupt service routine to catch it when the interrupt goes off.
if(wdtFlag == 0)
wdtFlag = 1;
There isn’t a built-in way for the Arduino system to attach an interrupt to the watchdog timer. This has to be done through the AVR standard library which is why it looks a little bit strange. In any case, once the interrupt fires, it will jump into this function where it sets a flag. We don’t really need the flag since we just want the interrupt to wake us up. But it’s nice to have it just in case.
Now that this is all set up, we are ready to go to sleep. In deep sleep, the I/O aren’t powered so they will float to whatever voltage they are tied to. That’s why it’s important that we tie the inputs to whatever chips we’re using to a known state. When the main IC goes to sleep, if the chip select to the radio isn’t tied high (inactive), then the radio could intermittently turn on and use whatever random noise on the SPI bus and think it’s valid data. This is all taken care of in the hardware though.
There is also a sequence we need to follow when shutting things down. We first want to turn off the radio. If there is a shield attached, it will also need to be configured for low power mode. Any ICs should be disabled and put into a sleep mode (if they have one) or whatever is the lowest power mode they support.
For the MCU, we need to disable the UART perhiperhal and then save off the GPIO registers so we can resume where we left off. I like to set them to a specific value before hand as well, just so they have a starting point when the power is taken away. After that, we disable the ADC and set the sleep mode.
It’s very important to disable the watchdog timer right before you go to sleep. Ideally, this should even be an atomic operation where no interrupts are allowed to come in. If you have an interrupt that will wake the MCU up, this should be cleared right before going to sleep too. Otherwise, its possible the MCU will sleep forever.
Once all the details are taken care of, you can go right to sleep. All of this is taken care of for you in the chibiArduino stack and you just need to make a call to the library to put the MCU to sleep. Note that this should be done after the radio is put into sleep mode and any other peripherals attached to the freakduino are also in low power mode.
// disable ADC
ADCSRA &= ~(1 << ADEN);
// set sleep mode
// go to sleep
sleep_enable(); // setting up for sleep ...
// waking up here
[connect to multimeter and display power consumption] Once everything is working, the device will go to sleep for 8 seconds at at time. Every 8 seconds, it will wake up and toggle the LED. You can see it working here and also the current consumption via the multimeter.
Hope this helps you understand a bit more about how you can use the freakduino in low power modes. These modes are extremely important when you’re running off of battery power, especially if you have to deploy these in the field.
If you have any questions, post it to the forum or leave a comment below.