Librería LowPower para Arduino

Una de las librerías más usadas para el ahorro de energía es LowPower. Esta librería unifica un poco todo lo que hemos visto hasta ahora bajo una interface simple y fácil de usar. Su principal problema es que en algunos casos es demasiado exhaustiva y eso hace que sea tediosa de programar.

Tras descargar la librería en el IDE de Arduino hay que incluirla en el programa:

#include "LowPower.h"

El objecto LowPower tiene un método para cada uno de los modos de sleep:

  • idle
  • adcNoiseReduction
  • powerDown
  • powerSave
  • powerStandby
  • powerExtStandby
  • standby

El primer parámetro «period» indica cuanto tiempo va permanecer dormido tras llamar a esta función, los posible valores son:

  • SLEEP_15MS
  • SLEEP_30MS
  • SLEEP_60MS
  • SLEEP_120MS
  • SLEEP_250MS
  • SLEEP_500MS
  • SLEEP_1S
  • SLEEP_2S
  • SLEEP_4S
  • SLEEP_8S
  • SLEEP_FOREVER

Los siguientes parámetros permiten apagar distintos módulos de la placa mientras esta dormida. Cada modo tiene unos parámetros distintos:

void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2) 
void powerDown(period_t period, adc_t adc, bod_t bod) 
void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2) 
void powerStandby(period_t period, adc_t adc, bod_t bod) 
void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t timer2)

El estado Idle tiene una larga lista de parámetros, que ademas cambia según para que placa se compile:

// ATmega328P, ATmega168, ATmega168P, AVR_ATmega88
void idle(period_t period, adc_t adc, timer2_t timer2,
     timer1_t timer1, timer0_t timer0, spi_t spi,
     usart0_t usart0, twi_t twi);

// ATmega644P, AVR_ATmega1284P
void idle(period_t period, adc_t adc, timer2_t timer2,
     timer1_t timer1, timer0_t timer0, spi_t spi,
     usart1_t usart1, usart0_t usart0, twi_t twi);

// ATmega2560
void idle(period_t period, adc_t adc, timer5_t timer5,
     timer4_t timer4, timer3_t timer3, timer2_t timer2,
     timer1_t timer1, timer0_t timer0, spi_t spi,
     usart3_t usart3, usart2_t usart2, usart1_t usart1,
     usart0_t usart0, twi_t twi);

// ATmega256RFR2
void idle(period_t period, adc_t adc, timer5_t timer5,
     timer4_t timer4, timer3_t timer3, timer2_t timer2,
     timer1_t timer1, timer0_t timer0, spi_t spi,
     usart1_t usart1, usart0_t usart0, twi_t twi);

// ATmega32U4
void idle(period_t period, adc_t adc, timer4_t timer4,
     timer3_t timer3, timer1_t timer1, timer0_t timer0,
     spi_t spi, usart1_t usart1, twi_t twi, usb_t usb);

Los parámetros son enumeraciones, cuyos posibles valores pueden ser el nombre del modulo al que res refieren seguido de ON u OFF. Por ejemplo adc puede tener los valores ADC_ON o ADC_OFF, timer2 puede tener los valores TIMER2_ON y TIMER2_OFF

Veamos dos ejemplos, el primero duerme la placa durante 8 segundo en modo powerDown y ademas desactiva los módulos ADC y BOD, similar a ejecutar las instrucciones: power_adc_disable() y sleep_bod_disable()

#include "LowPower.h"

void setup(){ 

}

void loop(){
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
		// codigo cuando se despierta la placa
}

El siguiente ejemplo duerme la placa hasta que sea despertada por una interrupción en el pin 2:

#include "LowPower.h"

const int wakeUpPin = 2;

void wakeUp(){
	// codigo a ejecutar cuando se despierta la placa
}

void setup(){
    pinMode(wakeUpPin, INPUT);  
		attachInterrupt(0, wakeUp, LOW); 
}

void loop(){    
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);    
}