How to save energy in the WSN sleeping the motes
Marcos Yarza, David Gascón - September 3, 2008


Important: Libelium has launched a new sensor device: Waspmote. It is ready for research and market applications. You can discover the differences between both platforms in the document: Waspmote vs SquidBee.


No doubt one of the most important features in a wireless sensor network is the battery life of the motes. Currently, with the initial SquidBee software the battery life doesn't last too long due to the sensor read interval (the mote read and send messages every 5 seconds).

Normally in a "standard" sensor network, we don't need the motes send data every 5 seconds, because temperature, humidity or light don't change so much. So we consider a good interval of time is for example 5 minutes for sending data messages.

Another thing we do for saving power in SquidBee is to use the sleeping mode in the board  and the XBee module. Arduino can be configured to be sleeping and wake up with an interrupt source.

In Arduino we are going to use power save mode to save power and as interrupt source we are going to use the overflow interrupt in timer 2.

Timer 2 is a 8 bit counter (counts until 255)  and is able to trigger an overflow interrupt if we also use a 10 bits preescaler we divide the frecuency by 1024 and we get an interrupt source that is triggered 61 times per seconds (16000000 / 1024 / 255 = 61).

Once the interrupt source on timer 2 is configured we have to set the parameters to put Arduino and the XBee module in sleep mode.

Arduino

For setting the sleep paramters in Arduino we use the sleep library (example in arduino playground)

XBee

To configure XBee in sleep mode is very easy, the XBee we are gonig to use has to be configured with these parameters:

- ATSM1    => Sleep mode - pin hibernate
- ATD70     => CTS flow control disabled

0

Finally, we have to connect the pin 6 in arduino with pin 9 in XBee, since Arduino is working with 5v and XBee with 3.3 V, we shouldn't connect them directly, we are going to use a resistor bridge to adapt these levels (see image).



Once we have all the hardware we just upload the code and it's done, we have our Squidbee saving all the power we can.

¿How many power are we saving?

For answering this question we meassure the current power with normal SquidBee and later with the new power saving mode.

SquidBee normal mode ==> 69 - 70 mA. Power saved 69 mA

SquidBee power save mode ==>     14 mA in sleep mode 69 mA (sending state aprox. 0.5 s every 5 min)

                                                    Power saved ((14 mA x 295 s) + (69 mA x 5 s)) / 300 = 14. 91 mA

As you can see, the power saved is (69 - 14.91) / 69 = 78%

/*
* Copyright (C) 2008 Libelium Comunicaciones Distribuidas S.L.
*
* This file is part of SquidBee code examples
* squidbee_sleeping.pde is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/

/* Name: squidbee_sleeping.pde
* Version 0.0.1
* Desc: Example code to demonstrate the sleep functions in Squidbee.
* Author: Marcos Yarza <m.yarza"at/removethis"libelium.com>
*/

/ *
 * The variable time controls the time the squidbee is sleeping, when this time
 * is over arduino wakes up, it wakes up to xbee and send a messge via xbee, later
 * it goes back to sleep.
 *
 * Pin 7 in SquidBee (Arduino) is connected to pin 9 in XBee (resistor bridge) for controlling
 * XBee sleeping state
 *                                  -------
 *       pin 7 (Arduino)  ---------|       |---------+-------------  pin 9 XBee
 *                                  -------          | 
 *                                   10 k            |
 *                                                   -
 *                                                  | |
 *                                                  | |  15 k
 *                                                  | |
 *                                                   -
 *                                                   |
 *                                                   |
 *                                                   |
 *                                                  gnd 
 * /
 
#include <avr/interrupt.h>  
#include <avr/io.h>
#include <avr/sleep.h>

#define INIT_TIMER_COUNT 0
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT


int int_counter = 0;     
int second = 0;
int counter = 0;


int XBee_pin = 7;          // this pins wake up xbee and put it to sleep

int seconds = 300;           // time sleeping (aprox seconds)
                           // MINIMUM VALUE = 5
                          
int time = 2*seconds;      // aux. time

int sens0 = 0;             // SquidBee variables
int sens1 = 1;
int sens2 = 2;
int sens3 = 3;

int val0 = 0;   
int val1 = 0;
int val2 = 0;
int val3 = 0;

int id = 23;                   // node identifier
int al = 0;                    // alarm code



// Aruino runs at 16 Mhz, so we have 61 Overflows per second…
// 1/ ((16000000 / 1024) / 256) = 1 / 61


ISR(TIMER2_OVF_vect) {                // this subroutine is executed 61 times per second
  
  int_counter ++;
 
  if (int_counter == 15) {
    second++;
    int_counter = 0;
  }
 
  if (second == time - 1) {
    digitalWrite(XBee_pin, LOW);
  }
 
  if (second == time) {
   
    second = 0;
   
    val0 = analogRead(sens0);
    val1 = analogRead(sens1);
    val2 = analogRead(sens2);
    val3 = analogRead(sens3);
   
    sendData(id,al,val0,val1,val2,val3);
   
    digitalWrite(XBee_pin, HIGH);
  }
 
}


// function to send data

void sendData(int id, int al, int val_t0,int val_h0,int val_l0,int val_b0){
 
 
  //ID-virtualNode@#al=0#t0=6#gas0=234#...
 
  Serial.print(id);
  Serial.print("@#");

  Serial.print("al=");
  Serial.print(al);
 
  Serial.print("#t0=");
  Serial.print(val_t0);
   
  Serial.print("#h0=");
  Serial.print(val_h0);
 
  Serial.print("#l0=");
  Serial.print(val_l0);
 
  Serial.print("#b0=");
  Serial.print(val_b0);
   
  Serial.println("#r");      // end of message
}

void setup() {
 
  Serial.begin(19200);
  pinMode(XBee_pin, OUTPUT);
  digitalWrite(XBee_pin,HIGH);
 
  //Timer2 Settings:  Timer Prescaler /1024
  TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20));
  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= (1 << TOIE2);
  RESET_TIMER2;
  sei();
 
  digitalWrite(XBee_pin, LOW);
  delay(20);
    val0 = analogRead(sens0);
    val1 = analogRead(sens1);
    val2 = analogRead(sens2);
    val3 = analogRead(sens3);
   
    sendData(id,al,val0,val1,val2,val3);
  digitalWrite(XBee_pin,HIGH);
 
}

void sleepNow()         // here we put the arduino to sleep
{
    /* Now is the time to set the sleep mode. In the Atmega8 datasheet
     * http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf on page 35
     * there is a list of sleep modes which explains which clocks and
     * wake up sources are available in which sleep modus.
     *
     * In the avr/sleep.h file, the call names of these sleep modus are to be found:
     *
     * The 5 different modes are:
     *     SLEEP_MODE_IDLE         -the least power savings
     *     SLEEP_MODE_ADC
     *     SLEEP_MODE_PWR_SAVE
     *     SLEEP_MODE_STANDBY
     *     SLEEP_MODE_PWR_DOWN     -the most power savings
     *
     * For now, we want as much power savings as possible, so we
     * choose the according
     * sleep modus: SLEEP_MODE_PWR_DOWN
     *
     * Timer 2 overflow interrupt is only able to wake up the ATmega in PWR_SAVE
     *
     */ 
    set_sleep_mode(SLEEP_MODE_PWR_SAVE);   // sleep mode is set here

    sleep_enable();          // enables the sleep bit in the mcucr register
                             // so sleep is possible. just a safety pin

    sleep_mode();            // here the device is actually put to sleep!!
                             // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

    sleep_disable();         // first thing after waking from sleep:
                             // disable sleep...
}

void loop() {
 
  sleepNow();                // do nothing, only sleep
 
}


Links:

  • Let the arduino sleep
  • ATmega168 info

 

 

gallery.png
theGroup.png

barra_lateral/rss
Research
  • Enclosure
  • Energy Management
  • GPS Mesh Networks
  • Hardware Node
  • Manager Platform
  • Mesh Routing Protocols
  • Securing the Mesh
  • Sensor Integration
  • System and Communications
  • System and Manager Platform
barra_lateral/techM