Start of example conversion. Added sleep to MySensors API.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
// **** INCLUDES *****
|
||||
#include "LowPower.h"
|
||||
|
||||
void setup()
|
||||
{
|
||||
// No setup is required for this library
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Enter idle state for 8 s with the rest of peripherals turned off
|
||||
// Each microcontroller comes with different number of peripherals
|
||||
// Comment off line of code where necessary
|
||||
|
||||
// ATmega328P, ATmega168
|
||||
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
|
||||
SPI_OFF, USART0_OFF, TWI_OFF);
|
||||
|
||||
// ATmega32U4
|
||||
//LowPower.idle(SLEEP_8S, ADC_OFF, TIMER4_OFF, TIMER3_OFF, TIMER1_OFF,
|
||||
// TIMER0_OFF, SPI_OFF, USART1_OFF, TWI_OFF, USB_OFF);
|
||||
|
||||
// ATmega2560
|
||||
//LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF,
|
||||
// TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART3_OFF,
|
||||
// USART2_OFF, USART1_OFF, USART0_OFF, TWI_OFF);
|
||||
|
||||
// Do something here
|
||||
// Example: Read sensor, data logging, data transmission.
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// **** INCLUDES *****
|
||||
#include "LowPower.h"
|
||||
|
||||
// Use pin 2 as wake up pin
|
||||
const int wakeUpPin = 2;
|
||||
|
||||
void wakeUp()
|
||||
{
|
||||
// Just a handler for the pin interrupt.
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// Configure wake up pin as input.
|
||||
// This will consumes few uA of current.
|
||||
pinMode(wakeUpPin, INPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Allow wake up pin to trigger interrupt on low.
|
||||
attachInterrupt(0, wakeUp, LOW);
|
||||
|
||||
// Enter power down state with ADC and BOD module disabled.
|
||||
// Wake up when wake up pin is low.
|
||||
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
|
||||
|
||||
// Disable external pin interrupt on wake up pin.
|
||||
detachInterrupt(0);
|
||||
|
||||
// Do something here
|
||||
// Example: Read sensor, data logging, data transmission.
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// **** INCLUDES *****
|
||||
#include "LowPower.h"
|
||||
|
||||
void setup()
|
||||
{
|
||||
// No setup is required for this library
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// Enter power down state for 8 s with ADC and BOD module disabled
|
||||
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
|
||||
|
||||
// Do something here
|
||||
// Example: Read sensor, data logging, data transmission.
|
||||
}
|
||||
@@ -0,0 +1,856 @@
|
||||
/*******************************************************************************
|
||||
* LowPower Library
|
||||
* Version: 1.30
|
||||
* Date: 22-05-2013
|
||||
* Company: Rocket Scream Electronics
|
||||
* Website: www.rocketscream.com
|
||||
*
|
||||
* This is a lightweight low power library for Arduino. Please check our wiki
|
||||
* (www.rocketscream.com/wiki) for more information on using this piece of
|
||||
* library.
|
||||
*
|
||||
* This library is licensed under Creative Commons Attribution-ShareAlike 3.0
|
||||
* Unported License.
|
||||
*
|
||||
* Revision Description
|
||||
* ======== ===========
|
||||
* 1.30 Added support for ATMega168, ATMega2560, ATMega1280 & ATMega32U4.
|
||||
* Tested to work with Arduino IDE 1.0.1 - 1.0.4.
|
||||
* 1.20 Remove typo error in idle method for checking whether Timer 0 was
|
||||
* turned off.
|
||||
* Remove dependecy on WProgram.h which is not required.
|
||||
* Tested to work with Arduino IDE 1.0.
|
||||
* 1.10 Added #ifndef for sleep_bod_disable() for compatibility with future
|
||||
* Arduino IDE release.
|
||||
* 1.00 Initial public release.
|
||||
*******************************************************************************/
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "LowPower.h"
|
||||
|
||||
// Only Pico Power devices can change BOD settings through software
|
||||
#if defined __AVR_ATmega328P__
|
||||
#ifndef sleep_bod_disable
|
||||
#define sleep_bod_disable() \
|
||||
do { \
|
||||
unsigned char tempreg; \
|
||||
__asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
|
||||
"ori %[tempreg], %[bods_bodse]" "\n\t" \
|
||||
"out %[mcucr], %[tempreg]" "\n\t" \
|
||||
"andi %[tempreg], %[not_bodse]" "\n\t" \
|
||||
"out %[mcucr], %[tempreg]" \
|
||||
: [tempreg] "=&d" (tempreg) \
|
||||
: [mcucr] "I" _SFR_IO_ADDR(MCUCR), \
|
||||
[bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \
|
||||
[not_bodse] "i" (~_BV(BODSE))); \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define lowPowerBodOn(mode) \
|
||||
do { \
|
||||
set_sleep_mode(mode); \
|
||||
cli(); \
|
||||
sleep_enable(); \
|
||||
sei(); \
|
||||
sleep_cpu(); \
|
||||
sleep_disable(); \
|
||||
sei(); \
|
||||
} while (0);
|
||||
|
||||
// Only Pico Power devices can change BOD settings through software
|
||||
#if defined __AVR_ATmega328P__
|
||||
#define lowPowerBodOff(mode)\
|
||||
do { \
|
||||
set_sleep_mode(mode); \
|
||||
cli(); \
|
||||
sleep_enable(); \
|
||||
sleep_bod_disable(); \
|
||||
sei(); \
|
||||
sleep_cpu(); \
|
||||
sleep_disable(); \
|
||||
sei(); \
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
// Some macros is still missing from AVR GCC distribution for ATmega32U4
|
||||
#if defined __AVR_ATmega32U4__
|
||||
// Timer 4 PRR bit is currently not defined in iom32u4.h
|
||||
#ifndef PRTIM4
|
||||
#define PRTIM4 4
|
||||
#endif
|
||||
|
||||
// Timer 4 power reduction macro is not defined currently in power.h
|
||||
#ifndef power_timer4_disable
|
||||
#define power_timer4_disable() (PRR1 |= (uint8_t)(1 << PRTIM4))
|
||||
#endif
|
||||
|
||||
#ifndef power_timer4_enable
|
||||
#define power_timer4_enable() (PRR1 &= (uint8_t)~(1 << PRTIM4))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega328P/168 into idle state. Please make sure you
|
||||
* understand the implication and result of disabling module.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
* 4. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 5. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 6. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 7. usart0 USART0 module disable control:
|
||||
* (a) USART0_OFF - Turn off USART0 module
|
||||
* (b) USART0_ON - Leave USART0 module in its default state
|
||||
*
|
||||
* 8. twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
|
||||
power_timer2_disable();
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart0 == USART0_OFF) power_usart0_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
power_timer2_enable();
|
||||
}
|
||||
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart0 == USART0_OFF) power_usart0_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega32U4 into idle state. Please make sure you
|
||||
* understand the implication and result of disabling module.
|
||||
* Take note that Timer 2 is not available and USART0
|
||||
* is replaced with USART1 on ATmega32U4.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer4 Timer 4 module disable control:
|
||||
* (a) TIMER4_OFF - Turn off Timer 4 module
|
||||
* (b) TIMER4_ON - Leave Timer 4 module in its default state
|
||||
*
|
||||
* 4. timer3 Timer 3 module disable control:
|
||||
* (a) TIMER3_OFF - Turn off Timer 3 module
|
||||
* (b) TIMER3_ON - Leave Timer 3 module in its default state
|
||||
*
|
||||
* 5. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 6. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 7. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 8. usart1 USART1 module disable control:
|
||||
* (a) USART1_OFF - Turn off USART1 module
|
||||
* (b) USART1_ON - Leave USART1 module in its default state
|
||||
*
|
||||
* 9. twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
* 10.usb USB module disable control:
|
||||
* (a) USB_OFF - Turn off USB module
|
||||
* (b) USB_ON - Leave USB module in its default state
|
||||
*******************************************************************************/
|
||||
#if defined __AVR_ATmega32U4__
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer4 == TIMER4_OFF) power_timer4_disable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_disable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart1 == USART1_OFF) power_usart1_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
if (usb == USB_OFF) power_usb_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer4 == TIMER4_OFF) power_timer4_enable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_enable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart1 == USART1_OFF) power_usart1_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
if (usb == USB_OFF) power_usb_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega2560 & ATmega1280 into idle state. Please make sure
|
||||
* you understand the implication and result of disabling module.
|
||||
* Take note that extra Timer 5, 4, 3 compared to an ATmega328P/168.
|
||||
* Also take note that extra USART 3, 2, 1 compared to an
|
||||
* ATmega328P/168.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer5 Timer 5 module disable control:
|
||||
* (a) TIMER5_OFF - Turn off Timer 5 module
|
||||
* (b) TIMER5_ON - Leave Timer 5 module in its default state
|
||||
*
|
||||
* 4. timer4 Timer 4 module disable control:
|
||||
* (a) TIMER4_OFF - Turn off Timer 4 module
|
||||
* (b) TIMER4_ON - Leave Timer 4 module in its default state
|
||||
*
|
||||
* 5. timer3 Timer 3 module disable control:
|
||||
* (a) TIMER3_OFF - Turn off Timer 3 module
|
||||
* (b) TIMER3_ON - Leave Timer 3 module in its default state
|
||||
*
|
||||
* 6. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
* 7. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 8. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 9. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 10.usart3 USART3 module disable control:
|
||||
* (a) USART3_OFF - Turn off USART3 module
|
||||
* (b) USART3_ON - Leave USART3 module in its default state
|
||||
*
|
||||
* 11.usart2 USART2 module disable control:
|
||||
* (a) USART2_OFF - Turn off USART2 module
|
||||
* (b) USART2_ON - Leave USART2 module in its default state
|
||||
*
|
||||
* 12.usart1 USART1 module disable control:
|
||||
* (a) USART1_OFF - Turn off USART1 module
|
||||
* (b) USART1_ON - Leave USART1 module in its default state
|
||||
*
|
||||
* 13.usart0 USART0 module disable control:
|
||||
* (a) USART0_OFF - Turn off USART0 module
|
||||
* (b) USART0_ON - Leave USART0 module in its default state
|
||||
*
|
||||
* 14.twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
#if defined (__AVR_ATmega2560__) || defined (__AVR_ATmega1280__)
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
|
||||
power_timer2_disable();
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer5 == TIMER5_OFF) power_timer5_disable();
|
||||
if (timer4 == TIMER4_OFF) power_timer4_disable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_disable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart3 == USART3_OFF) power_usart3_disable();
|
||||
if (usart2 == USART2_OFF) power_usart2_disable();
|
||||
if (usart1 == USART1_OFF) power_usart1_disable();
|
||||
if (usart0 == USART0_OFF) power_usart0_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
power_timer2_enable();
|
||||
}
|
||||
|
||||
if (timer5 == TIMER5_OFF) power_timer5_enable();
|
||||
if (timer4 == TIMER4_OFF) power_timer4_enable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_enable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart3 == USART3_OFF) power_usart3_enable();
|
||||
if (usart2 == USART2_OFF) power_usart2_enable();
|
||||
if (usart1 == USART1_OFF) power_usart1_enable();
|
||||
if (usart0 == USART0_OFF) power_usart0_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: adcNoiseReduction
|
||||
* Description: Putting microcontroller into ADC noise reduction state. This is
|
||||
* a very useful state when using the ADC to achieve best and low
|
||||
* noise signal.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::adcNoiseReduction(period_t period, adc_t adc,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_ADC);
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerDown
|
||||
* Description: Putting microcontroller into power down state. This is
|
||||
* the lowest current consumption state. Use this together with
|
||||
* external pin interrupt to wake up through external event
|
||||
* triggering (example: RTC clockout pin, SD card detect pin).
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerDown(period_t period, adc_t adc, bod_t bod)
|
||||
{
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_PWR_DOWN);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerSave
|
||||
* Description: Putting microcontroller into power save state. This is
|
||||
* the lowest current consumption state after power down.
|
||||
* Use this state together with an external 32.768 kHz crystal (but
|
||||
* 8/16 MHz crystal/resonator need to be removed) to provide an
|
||||
* asynchronous clock source to Timer 2. Please take note that
|
||||
* Timer 2 is also used by the Arduino core for PWM operation.
|
||||
* Please refer to wiring.c for explanation. Removal of the external
|
||||
* 8/16 MHz crystal/resonator requires the microcontroller to run
|
||||
* on its internal RC oscillator which is not so accurate for time
|
||||
* critical operation.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
* 4. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerSave(period_t period, adc_t adc, bod_t bod,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_PWR_SAVE);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_SAVE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_SAVE);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerStandby
|
||||
* Description: Putting microcontroller into power standby state.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerStandby(period_t period, adc_t adc, bod_t bod)
|
||||
{
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_STANDBY);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_STANDBY);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_STANDBY);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerExtStandby
|
||||
* Description: Putting microcontroller into power extended standby state. This
|
||||
* is different from the power standby state as it has the
|
||||
* capability to run Timer 2 asynchronously.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
* 4. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerExtStandby(period_t period, adc_t adc, bod_t bod,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_EXT_STANDBY);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_EXT_STANDBY);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_EXT_STANDBY);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: ISR (WDT_vect)
|
||||
* Description: Watchdog Timer interrupt service routine. This routine is
|
||||
* required to allow automatic WDIF and WDIE bit clearance in
|
||||
* hardware.
|
||||
*
|
||||
*******************************************************************************/
|
||||
ISR (WDT_vect)
|
||||
{
|
||||
// WDIE & WDIF is cleared in hardware upon entering this ISR
|
||||
wdt_disable();
|
||||
}
|
||||
|
||||
LowPowerClass LowPower;
|
||||
@@ -0,0 +1,137 @@
|
||||
#ifndef LowPower_h
|
||||
#define LowPower_h
|
||||
|
||||
enum period_t
|
||||
{
|
||||
SLEEP_15Ms,
|
||||
SLEEP_30MS,
|
||||
SLEEP_60MS,
|
||||
SLEEP_120MS,
|
||||
SLEEP_250MS,
|
||||
SLEEP_500MS,
|
||||
SLEEP_1S,
|
||||
SLEEP_2S,
|
||||
SLEEP_4S,
|
||||
SLEEP_8S,
|
||||
SLEEP_FOREVER
|
||||
};
|
||||
|
||||
enum bod_t
|
||||
{
|
||||
BOD_OFF,
|
||||
BOD_ON
|
||||
};
|
||||
|
||||
enum adc_t
|
||||
{
|
||||
ADC_OFF,
|
||||
ADC_ON
|
||||
};
|
||||
|
||||
enum timer5_t
|
||||
{
|
||||
TIMER5_OFF,
|
||||
TIMER5_ON
|
||||
};
|
||||
|
||||
enum timer4_t
|
||||
{
|
||||
TIMER4_OFF,
|
||||
TIMER4_ON
|
||||
};
|
||||
|
||||
enum timer3_t
|
||||
{
|
||||
TIMER3_OFF,
|
||||
TIMER3_ON
|
||||
};
|
||||
|
||||
enum timer2_t
|
||||
{
|
||||
TIMER2_OFF,
|
||||
TIMER2_ON
|
||||
};
|
||||
|
||||
enum timer1_t
|
||||
{
|
||||
TIMER1_OFF,
|
||||
TIMER1_ON
|
||||
};
|
||||
|
||||
enum timer0_t
|
||||
{
|
||||
TIMER0_OFF,
|
||||
TIMER0_ON
|
||||
};
|
||||
|
||||
enum spi_t
|
||||
{
|
||||
SPI_OFF,
|
||||
SPI_ON
|
||||
};
|
||||
|
||||
enum usart0_t
|
||||
{
|
||||
USART0_OFF,
|
||||
USART0_ON
|
||||
};
|
||||
|
||||
enum usart1_t
|
||||
{
|
||||
USART1_OFF,
|
||||
USART1_ON
|
||||
};
|
||||
|
||||
enum usart2_t
|
||||
{
|
||||
USART2_OFF,
|
||||
USART2_ON
|
||||
};
|
||||
|
||||
enum usart3_t
|
||||
{
|
||||
USART3_OFF,
|
||||
USART3_ON
|
||||
};
|
||||
|
||||
enum twi_t
|
||||
{
|
||||
TWI_OFF,
|
||||
TWI_ON
|
||||
};
|
||||
|
||||
enum usb_t
|
||||
{
|
||||
USB_OFF,
|
||||
USB_ON
|
||||
};
|
||||
|
||||
class LowPowerClass
|
||||
{
|
||||
public:
|
||||
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
|
||||
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);
|
||||
#elif defined __AVR_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);
|
||||
#elif defined __AVR_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);
|
||||
#else
|
||||
#error "Please ensure chosen MCU is either 328P, 32U4 or 2560."
|
||||
#endif
|
||||
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);
|
||||
};
|
||||
|
||||
extern LowPowerClass LowPower;
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map LowPower
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
idle KEYWORD2
|
||||
adcNoiseReduction KEYWORD2
|
||||
powerDown KEYWORD2
|
||||
powerSave KEYWORD2
|
||||
powerStandby KEYWORD2
|
||||
powerExtStandby KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Instances (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
LowPower KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
||||
#######################################
|
||||
|
||||
SLEEP_15MS LITERAL1
|
||||
SLEEP_30MS LITERAL1
|
||||
SLEEP_60MS LITERAL1
|
||||
SLEEP_120MS LITERAL1
|
||||
SLEEP_250MS LITERAL1
|
||||
SLEEP_500MS LITERAL1
|
||||
SLEEP_1S LITERAL1
|
||||
SLEEP_2S LITERAL1
|
||||
SLEEP_4S LITERAL1
|
||||
SLEEP_8S LITERAL1
|
||||
SLEEP_FOREVER LITERAL1
|
||||
ADC_OFF LITERAL1
|
||||
ADC_ON LITERAL1
|
||||
BOD_OFF LITERAL1
|
||||
BOD_ON LITERAL1
|
||||
TIMER4_OFF LITERAL1
|
||||
TIMER4_ON LITERAL1
|
||||
TIMER3_OFF LITERAL1
|
||||
TIMER3_ON LITERAL1
|
||||
TIMER2_OFF LITERAL1
|
||||
TIMER2_ON LITERAL1
|
||||
TIMER1_OFF LITERAL1
|
||||
TIMER1_ON LITERAL1
|
||||
TIMER0_OFF LITERAL1
|
||||
TIMER0_ON LITERAL1
|
||||
USART3_OFF LITERAL1
|
||||
USART3_ON LITERAL1
|
||||
USART2_OFF LITERAL1
|
||||
USART2_ON LITERAL1
|
||||
USART1_OFF LITERAL1
|
||||
USART1_ON LITERAL1
|
||||
USART0_OFF LITERAL1
|
||||
USART0_ON LITERAL1
|
||||
SPI_OFF LITERAL1
|
||||
SPI_ON LITERAL1
|
||||
TWI_OFF LITERAL1
|
||||
TWI_ON LITERAL1
|
||||
USB_OFF LITERAL1
|
||||
USB_ON LITERAL1
|
||||
@@ -0,0 +1,856 @@
|
||||
/*******************************************************************************
|
||||
* LowPower Library
|
||||
* Version: 1.30
|
||||
* Date: 22-05-2013
|
||||
* Company: Rocket Scream Electronics
|
||||
* Website: www.rocketscream.com
|
||||
*
|
||||
* This is a lightweight low power library for Arduino. Please check our wiki
|
||||
* (www.rocketscream.com/wiki) for more information on using this piece of
|
||||
* library.
|
||||
*
|
||||
* This library is licensed under Creative Commons Attribution-ShareAlike 3.0
|
||||
* Unported License.
|
||||
*
|
||||
* Revision Description
|
||||
* ======== ===========
|
||||
* 1.30 Added support for ATMega168, ATMega2560, ATMega1280 & ATMega32U4.
|
||||
* Tested to work with Arduino IDE 1.0.1 - 1.0.4.
|
||||
* 1.20 Remove typo error in idle method for checking whether Timer 0 was
|
||||
* turned off.
|
||||
* Remove dependecy on WProgram.h which is not required.
|
||||
* Tested to work with Arduino IDE 1.0.
|
||||
* 1.10 Added #ifndef for sleep_bod_disable() for compatibility with future
|
||||
* Arduino IDE release.
|
||||
* 1.00 Initial public release.
|
||||
*******************************************************************************/
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "LowPower.h"
|
||||
|
||||
// Only Pico Power devices can change BOD settings through software
|
||||
#if defined __AVR_ATmega328P__
|
||||
#ifndef sleep_bod_disable
|
||||
#define sleep_bod_disable() \
|
||||
do { \
|
||||
unsigned char tempreg; \
|
||||
__asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
|
||||
"ori %[tempreg], %[bods_bodse]" "\n\t" \
|
||||
"out %[mcucr], %[tempreg]" "\n\t" \
|
||||
"andi %[tempreg], %[not_bodse]" "\n\t" \
|
||||
"out %[mcucr], %[tempreg]" \
|
||||
: [tempreg] "=&d" (tempreg) \
|
||||
: [mcucr] "I" _SFR_IO_ADDR(MCUCR), \
|
||||
[bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \
|
||||
[not_bodse] "i" (~_BV(BODSE))); \
|
||||
} while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define lowPowerBodOn(mode) \
|
||||
do { \
|
||||
set_sleep_mode(mode); \
|
||||
cli(); \
|
||||
sleep_enable(); \
|
||||
sei(); \
|
||||
sleep_cpu(); \
|
||||
sleep_disable(); \
|
||||
sei(); \
|
||||
} while (0);
|
||||
|
||||
// Only Pico Power devices can change BOD settings through software
|
||||
#if defined __AVR_ATmega328P__
|
||||
#define lowPowerBodOff(mode)\
|
||||
do { \
|
||||
set_sleep_mode(mode); \
|
||||
cli(); \
|
||||
sleep_enable(); \
|
||||
sleep_bod_disable(); \
|
||||
sei(); \
|
||||
sleep_cpu(); \
|
||||
sleep_disable(); \
|
||||
sei(); \
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
// Some macros is still missing from AVR GCC distribution for ATmega32U4
|
||||
#if defined __AVR_ATmega32U4__
|
||||
// Timer 4 PRR bit is currently not defined in iom32u4.h
|
||||
#ifndef PRTIM4
|
||||
#define PRTIM4 4
|
||||
#endif
|
||||
|
||||
// Timer 4 power reduction macro is not defined currently in power.h
|
||||
#ifndef power_timer4_disable
|
||||
#define power_timer4_disable() (PRR1 |= (uint8_t)(1 << PRTIM4))
|
||||
#endif
|
||||
|
||||
#ifndef power_timer4_enable
|
||||
#define power_timer4_enable() (PRR1 &= (uint8_t)~(1 << PRTIM4))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega328P/168 into idle state. Please make sure you
|
||||
* understand the implication and result of disabling module.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
* 4. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 5. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 6. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 7. usart0 USART0 module disable control:
|
||||
* (a) USART0_OFF - Turn off USART0 module
|
||||
* (b) USART0_ON - Leave USART0 module in its default state
|
||||
*
|
||||
* 8. twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
|
||||
power_timer2_disable();
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart0 == USART0_OFF) power_usart0_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
power_timer2_enable();
|
||||
}
|
||||
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart0 == USART0_OFF) power_usart0_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega32U4 into idle state. Please make sure you
|
||||
* understand the implication and result of disabling module.
|
||||
* Take note that Timer 2 is not available and USART0
|
||||
* is replaced with USART1 on ATmega32U4.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer4 Timer 4 module disable control:
|
||||
* (a) TIMER4_OFF - Turn off Timer 4 module
|
||||
* (b) TIMER4_ON - Leave Timer 4 module in its default state
|
||||
*
|
||||
* 4. timer3 Timer 3 module disable control:
|
||||
* (a) TIMER3_OFF - Turn off Timer 3 module
|
||||
* (b) TIMER3_ON - Leave Timer 3 module in its default state
|
||||
*
|
||||
* 5. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 6. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 7. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 8. usart1 USART1 module disable control:
|
||||
* (a) USART1_OFF - Turn off USART1 module
|
||||
* (b) USART1_ON - Leave USART1 module in its default state
|
||||
*
|
||||
* 9. twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
* 10.usb USB module disable control:
|
||||
* (a) USB_OFF - Turn off USB module
|
||||
* (b) USB_ON - Leave USB module in its default state
|
||||
*******************************************************************************/
|
||||
#if defined __AVR_ATmega32U4__
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer4 == TIMER4_OFF) power_timer4_disable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_disable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart1 == USART1_OFF) power_usart1_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
if (usb == USB_OFF) power_usb_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer4 == TIMER4_OFF) power_timer4_enable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_enable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart1 == USART1_OFF) power_usart1_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
if (usb == USB_OFF) power_usb_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: idle
|
||||
* Description: Putting ATmega2560 & ATmega1280 into idle state. Please make sure
|
||||
* you understand the implication and result of disabling module.
|
||||
* Take note that extra Timer 5, 4, 3 compared to an ATmega328P/168.
|
||||
* Also take note that extra USART 3, 2, 1 compared to an
|
||||
* ATmega328P/168.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control:
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer5 Timer 5 module disable control:
|
||||
* (a) TIMER5_OFF - Turn off Timer 5 module
|
||||
* (b) TIMER5_ON - Leave Timer 5 module in its default state
|
||||
*
|
||||
* 4. timer4 Timer 4 module disable control:
|
||||
* (a) TIMER4_OFF - Turn off Timer 4 module
|
||||
* (b) TIMER4_ON - Leave Timer 4 module in its default state
|
||||
*
|
||||
* 5. timer3 Timer 3 module disable control:
|
||||
* (a) TIMER3_OFF - Turn off Timer 3 module
|
||||
* (b) TIMER3_ON - Leave Timer 3 module in its default state
|
||||
*
|
||||
* 6. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
* 7. timer1 Timer 1 module disable control:
|
||||
* (a) TIMER1_OFF - Turn off Timer 1 module
|
||||
* (b) TIMER1_ON - Leave Timer 1 module in its default state
|
||||
*
|
||||
* 8. timer0 Timer 0 module disable control:
|
||||
* (a) TIMER0_OFF - Turn off Timer 0 module
|
||||
* (b) TIMER0_ON - Leave Timer 0 module in its default state
|
||||
*
|
||||
* 9. spi SPI module disable control:
|
||||
* (a) SPI_OFF - Turn off SPI module
|
||||
* (b) SPI_ON - Leave SPI module in its default state
|
||||
*
|
||||
* 10.usart3 USART3 module disable control:
|
||||
* (a) USART3_OFF - Turn off USART3 module
|
||||
* (b) USART3_ON - Leave USART3 module in its default state
|
||||
*
|
||||
* 11.usart2 USART2 module disable control:
|
||||
* (a) USART2_OFF - Turn off USART2 module
|
||||
* (b) USART2_ON - Leave USART2 module in its default state
|
||||
*
|
||||
* 12.usart1 USART1 module disable control:
|
||||
* (a) USART1_OFF - Turn off USART1 module
|
||||
* (b) USART1_ON - Leave USART1 module in its default state
|
||||
*
|
||||
* 13.usart0 USART0 module disable control:
|
||||
* (a) USART0_OFF - Turn off USART0 module
|
||||
* (b) USART0_ON - Leave USART0 module in its default state
|
||||
*
|
||||
* 14.twi TWI module disable control:
|
||||
* (a) TWI_OFF - Turn off TWI module
|
||||
* (b) TWI_ON - Leave TWI module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
#if defined (__AVR_ATmega2560__) || defined (__AVR_ATmega1280__)
|
||||
void LowPowerClass::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)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
|
||||
power_timer2_disable();
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
power_adc_disable();
|
||||
}
|
||||
|
||||
if (timer5 == TIMER5_OFF) power_timer5_disable();
|
||||
if (timer4 == TIMER4_OFF) power_timer4_disable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_disable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_disable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_disable();
|
||||
if (spi == SPI_OFF) power_spi_disable();
|
||||
if (usart3 == USART3_OFF) power_usart3_disable();
|
||||
if (usart2 == USART2_OFF) power_usart2_disable();
|
||||
if (usart1 == USART1_OFF) power_usart1_disable();
|
||||
if (usart0 == USART0_OFF) power_usart0_disable();
|
||||
if (twi == TWI_OFF) power_twi_disable();
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_IDLE);
|
||||
|
||||
if (adc == ADC_OFF)
|
||||
{
|
||||
power_adc_enable();
|
||||
ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
power_timer2_enable();
|
||||
}
|
||||
|
||||
if (timer5 == TIMER5_OFF) power_timer5_enable();
|
||||
if (timer4 == TIMER4_OFF) power_timer4_enable();
|
||||
if (timer3 == TIMER3_OFF) power_timer3_enable();
|
||||
if (timer1 == TIMER1_OFF) power_timer1_enable();
|
||||
if (timer0 == TIMER0_OFF) power_timer0_enable();
|
||||
if (spi == SPI_OFF) power_spi_enable();
|
||||
if (usart3 == USART3_OFF) power_usart3_enable();
|
||||
if (usart2 == USART2_OFF) power_usart2_enable();
|
||||
if (usart1 == USART1_OFF) power_usart1_enable();
|
||||
if (usart0 == USART0_OFF) power_usart0_enable();
|
||||
if (twi == TWI_OFF) power_twi_enable();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: adcNoiseReduction
|
||||
* Description: Putting microcontroller into ADC noise reduction state. This is
|
||||
* a very useful state when using the ADC to achieve best and low
|
||||
* noise signal.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::adcNoiseReduction(period_t period, adc_t adc,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
lowPowerBodOn(SLEEP_MODE_ADC);
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerDown
|
||||
* Description: Putting microcontroller into power down state. This is
|
||||
* the lowest current consumption state. Use this together with
|
||||
* external pin interrupt to wake up through external event
|
||||
* triggering (example: RTC clockout pin, SD card detect pin).
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerDown(period_t period, adc_t adc, bod_t bod)
|
||||
{
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_PWR_DOWN);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_DOWN);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerSave
|
||||
* Description: Putting microcontroller into power save state. This is
|
||||
* the lowest current consumption state after power down.
|
||||
* Use this state together with an external 32.768 kHz crystal (but
|
||||
* 8/16 MHz crystal/resonator need to be removed) to provide an
|
||||
* asynchronous clock source to Timer 2. Please take note that
|
||||
* Timer 2 is also used by the Arduino core for PWM operation.
|
||||
* Please refer to wiring.c for explanation. Removal of the external
|
||||
* 8/16 MHz crystal/resonator requires the microcontroller to run
|
||||
* on its internal RC oscillator which is not so accurate for time
|
||||
* critical operation.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
* 4. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerSave(period_t period, adc_t adc, bod_t bod,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_PWR_SAVE);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_SAVE);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_PWR_SAVE);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerStandby
|
||||
* Description: Putting microcontroller into power standby state.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control. Turning off the ADC module is
|
||||
* basically removing the purpose of this low power mode.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerStandby(period_t period, adc_t adc, bod_t bod)
|
||||
{
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_STANDBY);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_STANDBY);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_STANDBY);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: powerExtStandby
|
||||
* Description: Putting microcontroller into power extended standby state. This
|
||||
* is different from the power standby state as it has the
|
||||
* capability to run Timer 2 asynchronously.
|
||||
*
|
||||
* Argument Description
|
||||
* ========= ===========
|
||||
* 1. period Duration of low power mode. Use SLEEP_FOREVER to use other wake
|
||||
* up resource:
|
||||
* (a) SLEEP_15MS - 15 ms sleep
|
||||
* (b) SLEEP_30MS - 30 ms sleep
|
||||
* (c) SLEEP_60MS - 60 ms sleep
|
||||
* (d) SLEEP_120MS - 120 ms sleep
|
||||
* (e) SLEEP_250MS - 250 ms sleep
|
||||
* (f) SLEEP_500MS - 500 ms sleep
|
||||
* (g) SLEEP_1S - 1 s sleep
|
||||
* (h) SLEEP_2S - 2 s sleep
|
||||
* (i) SLEEP_4S - 4 s sleep
|
||||
* (j) SLEEP_8S - 8 s sleep
|
||||
* (k) SLEEP_FOREVER - Sleep without waking up through WDT
|
||||
*
|
||||
* 2. adc ADC module disable control.
|
||||
* (a) ADC_OFF - Turn off ADC module
|
||||
* (b) ADC_ON - Leave ADC module in its default state
|
||||
*
|
||||
* 3. bod Brown Out Detector (BOD) module disable control:
|
||||
* (a) BOD_OFF - Turn off BOD module
|
||||
* (b) BOD_ON - Leave BOD module in its default state
|
||||
*
|
||||
* 4. timer2 Timer 2 module disable control:
|
||||
* (a) TIMER2_OFF - Turn off Timer 2 module
|
||||
* (b) TIMER2_ON - Leave Timer 2 module in its default state
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LowPowerClass::powerExtStandby(period_t period, adc_t adc, bod_t bod,
|
||||
timer2_t timer2)
|
||||
{
|
||||
// Temporary clock source variable
|
||||
unsigned char clockSource = 0;
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (TCCR2B & CS22) clockSource |= (1 << CS22);
|
||||
if (TCCR2B & CS21) clockSource |= (1 << CS21);
|
||||
if (TCCR2B & CS20) clockSource |= (1 << CS20);
|
||||
|
||||
// Remove the clock source to shutdown Timer2
|
||||
TCCR2B &= ~(1 << CS22);
|
||||
TCCR2B &= ~(1 << CS21);
|
||||
TCCR2B &= ~(1 << CS20);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA &= ~(1 << ADEN);
|
||||
|
||||
if (period != SLEEP_FOREVER)
|
||||
{
|
||||
wdt_enable(period);
|
||||
WDTCSR |= (1 << WDIE);
|
||||
}
|
||||
if (bod == BOD_OFF)
|
||||
{
|
||||
#if defined __AVR_ATmega328P__
|
||||
lowPowerBodOff(SLEEP_MODE_EXT_STANDBY);
|
||||
#else
|
||||
lowPowerBodOn(SLEEP_MODE_EXT_STANDBY);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
lowPowerBodOn(SLEEP_MODE_EXT_STANDBY);
|
||||
}
|
||||
|
||||
if (adc == ADC_OFF) ADCSRA |= (1 << ADEN);
|
||||
|
||||
#if !defined(__AVR_ATmega32U4__)
|
||||
if (timer2 == TIMER2_OFF)
|
||||
{
|
||||
if (clockSource & CS22) TCCR2B |= (1 << CS22);
|
||||
if (clockSource & CS21) TCCR2B |= (1 << CS21);
|
||||
if (clockSource & CS20) TCCR2B |= (1 << CS20);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Name: ISR (WDT_vect)
|
||||
* Description: Watchdog Timer interrupt service routine. This routine is
|
||||
* required to allow automatic WDIF and WDIE bit clearance in
|
||||
* hardware.
|
||||
*
|
||||
*******************************************************************************/
|
||||
ISR (WDT_vect)
|
||||
{
|
||||
// WDIE & WDIF is cleared in hardware upon entering this ISR
|
||||
wdt_disable();
|
||||
}
|
||||
|
||||
LowPowerClass LowPower;
|
||||
@@ -0,0 +1,137 @@
|
||||
#ifndef LowPower_h
|
||||
#define LowPower_h
|
||||
|
||||
enum period_t
|
||||
{
|
||||
SLEEP_15Ms,
|
||||
SLEEP_30MS,
|
||||
SLEEP_60MS,
|
||||
SLEEP_120MS,
|
||||
SLEEP_250MS,
|
||||
SLEEP_500MS,
|
||||
SLEEP_1S,
|
||||
SLEEP_2S,
|
||||
SLEEP_4S,
|
||||
SLEEP_8S,
|
||||
SLEEP_FOREVER
|
||||
};
|
||||
|
||||
enum bod_t
|
||||
{
|
||||
BOD_OFF,
|
||||
BOD_ON
|
||||
};
|
||||
|
||||
enum adc_t
|
||||
{
|
||||
ADC_OFF,
|
||||
ADC_ON
|
||||
};
|
||||
|
||||
enum timer5_t
|
||||
{
|
||||
TIMER5_OFF,
|
||||
TIMER5_ON
|
||||
};
|
||||
|
||||
enum timer4_t
|
||||
{
|
||||
TIMER4_OFF,
|
||||
TIMER4_ON
|
||||
};
|
||||
|
||||
enum timer3_t
|
||||
{
|
||||
TIMER3_OFF,
|
||||
TIMER3_ON
|
||||
};
|
||||
|
||||
enum timer2_t
|
||||
{
|
||||
TIMER2_OFF,
|
||||
TIMER2_ON
|
||||
};
|
||||
|
||||
enum timer1_t
|
||||
{
|
||||
TIMER1_OFF,
|
||||
TIMER1_ON
|
||||
};
|
||||
|
||||
enum timer0_t
|
||||
{
|
||||
TIMER0_OFF,
|
||||
TIMER0_ON
|
||||
};
|
||||
|
||||
enum spi_t
|
||||
{
|
||||
SPI_OFF,
|
||||
SPI_ON
|
||||
};
|
||||
|
||||
enum usart0_t
|
||||
{
|
||||
USART0_OFF,
|
||||
USART0_ON
|
||||
};
|
||||
|
||||
enum usart1_t
|
||||
{
|
||||
USART1_OFF,
|
||||
USART1_ON
|
||||
};
|
||||
|
||||
enum usart2_t
|
||||
{
|
||||
USART2_OFF,
|
||||
USART2_ON
|
||||
};
|
||||
|
||||
enum usart3_t
|
||||
{
|
||||
USART3_OFF,
|
||||
USART3_ON
|
||||
};
|
||||
|
||||
enum twi_t
|
||||
{
|
||||
TWI_OFF,
|
||||
TWI_ON
|
||||
};
|
||||
|
||||
enum usb_t
|
||||
{
|
||||
USB_OFF,
|
||||
USB_ON
|
||||
};
|
||||
|
||||
class LowPowerClass
|
||||
{
|
||||
public:
|
||||
#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
|
||||
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);
|
||||
#elif defined __AVR_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);
|
||||
#elif defined __AVR_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);
|
||||
#else
|
||||
#error "Please ensure chosen MCU is either 328P, 32U4 or 2560."
|
||||
#endif
|
||||
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);
|
||||
};
|
||||
|
||||
extern LowPowerClass LowPower;
|
||||
#endif
|
||||
@@ -10,6 +10,8 @@
|
||||
*/
|
||||
|
||||
#include "MySensor.h"
|
||||
#include "LowPower.h"
|
||||
|
||||
|
||||
// Inline function and macros
|
||||
inline MyMessage* build (MyMessage* msg, uint8_t sender, uint8_t destination, uint8_t sensor, uint8_t command, uint8_t type) {
|
||||
@@ -499,7 +501,7 @@ uint8_t MySensor::getChildRoute(uint8_t childId) {
|
||||
}
|
||||
|
||||
|
||||
long MySensor::getInternalTemp(void)
|
||||
float MySensor::getInternalTemp(void)
|
||||
{
|
||||
long result;
|
||||
// Read internal temp sensor against 1.1V reference
|
||||
@@ -511,9 +513,48 @@ long MySensor::getInternalTemp(void)
|
||||
result |= ADCH<<8;
|
||||
result = (result - 125) * 1075;
|
||||
|
||||
return result;
|
||||
return static_cast<float>(static_cast<int>(result/1000.)) / 10.;
|
||||
}
|
||||
|
||||
int continueTimer = true;
|
||||
void wakeUp() //place to send the interrupts
|
||||
{
|
||||
continueTimer = false;
|
||||
}
|
||||
|
||||
void MySensor::internalSleep(int ms) {
|
||||
while (continueTimer && ms >= 8000) { LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); ms -= 8000; }
|
||||
if (continueTimer && ms >= 4000) { LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF); ms -= 4000; }
|
||||
if (continueTimer && ms >= 2000) { LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); ms -= 2000; }
|
||||
if (continueTimer && ms >= 1000) { LowPower.powerDown(SLEEP_1S, ADC_OFF, BOD_OFF); ms -= 1000; }
|
||||
if (continueTimer && ms >= 500) { LowPower.powerDown(SLEEP_500MS, ADC_OFF, BOD_OFF); ms -= 500; }
|
||||
if (continueTimer && ms >= 250) { LowPower.powerDown(SLEEP_250MS, ADC_OFF, BOD_OFF); ms -= 250; }
|
||||
if (continueTimer && ms >= 125) { LowPower.powerDown(SLEEP_120MS, ADC_OFF, BOD_OFF); ms -= 120; }
|
||||
if (continueTimer && ms >= 64) { LowPower.powerDown(SLEEP_60MS, ADC_OFF, BOD_OFF); ms -= 60; }
|
||||
if (continueTimer && ms >= 32) { LowPower.powerDown(SLEEP_30MS, ADC_OFF, BOD_OFF); ms -= 30; }
|
||||
if (continueTimer && ms >= 16) { LowPower.powerDown(SLEEP_15Ms, ADC_OFF, BOD_OFF); ms -= 15; }
|
||||
}
|
||||
|
||||
void MySensor::sleep(int ms) {
|
||||
RF24::powerDown();
|
||||
continueTimer = true;
|
||||
internalSleep(ms);
|
||||
}
|
||||
|
||||
void MySensor::sleep(int interrupt, int mode, int ms) {
|
||||
RF24::powerDown();
|
||||
attachInterrupt(interrupt, wakeUp, mode); //Interrupt on pin 3 for any change in solar power
|
||||
if (ms>0) {
|
||||
continueTimer = true;
|
||||
sleep(ms);
|
||||
} else {
|
||||
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
|
||||
}
|
||||
detachInterrupt(interrupt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void MySensor::debugPrint(const char *fmt, ... ) {
|
||||
char fmtBuffer[300];
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdarg.h>
|
||||
#include "LowPower.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug(x,...) debugPrint(x, ##__VA_ARGS__)
|
||||
@@ -193,15 +194,30 @@ class MySensor : public RF24
|
||||
*/
|
||||
MyMessage* getLastMessage(void);
|
||||
|
||||
/**
|
||||
* Sleep (PowerDownMode) the Arduino and radio. Wake up on timer.
|
||||
* @param ms Number of milliseconds to sleep.
|
||||
*/
|
||||
void sleep(int ms);
|
||||
|
||||
/**
|
||||
* Sleep (PowerDownMode) the Arduino and radio. Wake up on timer or pin change.
|
||||
* See: http://arduino.cc/en/Reference/attachInterrupt for details on modes and which pin
|
||||
* is assigned to what interrupt. On Nano/Pro Mini: 0=Pin2, 1=Pin3
|
||||
* @param interrupt Interrupt that should trigger the wakeup
|
||||
* @param mode RISING, FALLING, CHANGE
|
||||
* @param ms Number of milliseconds to sleep or 0 to sleep forever
|
||||
*/
|
||||
void sleep(int interrupt, int mode, int ms=0);
|
||||
|
||||
/**
|
||||
* getInternalTemp
|
||||
*
|
||||
* Read temp from internal (ATMEGA328 only) temperature sensor
|
||||
*
|
||||
* @return Temperature in milli-degrees Celsius
|
||||
* @return Temperature in degrees Celsius (one decimal)
|
||||
*/
|
||||
long getInternalTemp(void);
|
||||
float getInternalTemp(void);
|
||||
|
||||
|
||||
|
||||
@@ -240,6 +256,7 @@ class MySensor : public RF24
|
||||
uint8_t getChildRoute(uint8_t childId);
|
||||
void addChildRoute(uint8_t childId, uint8_t route);
|
||||
void removeChildRoute(uint8_t childId);
|
||||
void internalSleep(int ms);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,17 +2,13 @@
|
||||
// Instructions for measuring battery capacity on A0 are available in the follwoing forum
|
||||
// thread: http://forum.micasaverde.com/index.php/topic,20078.0.html
|
||||
|
||||
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
|
||||
int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
|
||||
|
||||
Sensor gw;
|
||||
Sleep sleep;
|
||||
MySensor gw;
|
||||
unsigned long SLEEP_TIME = 900000; // sleep time between reads (seconds * 1000 milliseconds)
|
||||
int oldBatteryPcnt = 0;
|
||||
|
||||
@@ -54,12 +50,6 @@ void loop()
|
||||
}
|
||||
|
||||
// delay to allow transmissions to gateway to be completed before sleep
|
||||
delay(500);
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call
|
||||
gw.powerDown();
|
||||
|
||||
sleep.pwrDownMode(); // set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME); // sleep for SLEEP_TIME
|
||||
delay(300);
|
||||
gw.sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
@@ -2,17 +2,20 @@
|
||||
// Connect button or door/window reed switch between
|
||||
// digitial I/O pin 3 (BUTTON_PIN below) and GND.
|
||||
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Bounce2.h>
|
||||
|
||||
#define CHILD_ID 3
|
||||
#define BUTTON_PIN 3 // Arduino Digital I/O pin for button/reed switch
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
Bounce debouncer = Bounce();
|
||||
int oldValue=-1;
|
||||
// Change to V_LIGHT if you use S_LIGHT in presentation below
|
||||
MyMessage msg(CHILD_ID,V_TRIPPED);
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -30,7 +33,7 @@ void setup()
|
||||
// Register binary input sensor to gw (they will be created as child devices)
|
||||
// You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage.
|
||||
// If S_LIGHT is used, remember to update variable type you send in below.
|
||||
gw.sendSensorPresentation(BUTTON_PIN, S_DOOR);
|
||||
gw.present(CHILD_ID, S_DOOR);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +46,7 @@ void loop()
|
||||
|
||||
if (value != oldValue) {
|
||||
// Send in the new value
|
||||
gw.sendVariable(BUTTON_PIN, V_TRIPPED, value==HIGH ? "1" : "0"); // Change to V_LIGHT if you use S_LIGHT in presentation above
|
||||
gw.send(msg.set(value==HIGH ? 1 : 0));
|
||||
oldValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// Example sketch showing how to send in OneWire temperature readings
|
||||
#include <MySensor.h>
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <DallasTemperature.h>
|
||||
#include <OneWire.h>
|
||||
@@ -12,7 +11,6 @@ unsigned long SLEEP_TIME = 30; // Sleep time between reads (in seconds)
|
||||
OneWire oneWire(ONE_WIRE_BUS);
|
||||
DallasTemperature sensors(&oneWire);
|
||||
MySensor gw;
|
||||
Sleep sleep;
|
||||
float lastTemperature[MAX_ATTACHED_DS18B20];
|
||||
int numSensors=0;
|
||||
boolean receivedConfig = false;
|
||||
@@ -64,10 +62,8 @@ void loop()
|
||||
}
|
||||
}
|
||||
// Power down the radio and sleep Arduino to save batteries.
|
||||
delay(500);
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
|
||||
delay(300);
|
||||
gw.sleep(SLEEP_TIME * 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <NewPing.h>
|
||||
|
||||
#define CHILD_ID 1
|
||||
#define TRIGGER_PIN 6 // Arduino pin tied to trigger pin on the ultrasonic sensor.
|
||||
#define ECHO_PIN 5 // Arduino pin tied to echo pin on the ultrasonic sensor.
|
||||
#define MAX_DISTANCE 300 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
|
||||
unsigned long SLEEP_TIME = 5; // Sleep time between reads (in seconds)
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
|
||||
Sleep sleep;
|
||||
|
||||
MyMessage msg(CHILD_ID, V_DISTANCE);
|
||||
int lastDist;
|
||||
boolean metric = true;
|
||||
|
||||
@@ -25,8 +24,8 @@ void setup()
|
||||
gw.sendSketchInfo("Distance Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
gw.sendSensorPresentation(0, S_DISTANCE);
|
||||
metric = gw.isMetricSystem();
|
||||
gw.present(CHILD_ID, S_DISTANCE);
|
||||
boolean metric = gw.getConfig().isMetric;
|
||||
}
|
||||
|
||||
void loop()
|
||||
@@ -39,16 +38,12 @@ void loop()
|
||||
|
||||
|
||||
if (dist != lastDist) {
|
||||
gw.sendVariable(0, V_DISTANCE, dist);
|
||||
gw.send(msg.set(dist));
|
||||
lastDist = dist;
|
||||
}
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.sleep(SLEEP_TIME*1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -7,26 +7,21 @@
|
||||
// sleepmode. So we cannot make this sensor sleep if we also want
|
||||
// to calculate/report watt-number.
|
||||
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
|
||||
#define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!)
|
||||
#define PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter
|
||||
#define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false.
|
||||
#define MAX_WATT 10000 // Max watt value to report. This filetrs outliers.
|
||||
#define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway)
|
||||
#define CHILD_ID 1 // Id of the sensor child
|
||||
#define CHILD_ID 1 // Id of the sensor child
|
||||
unsigned long SEND_FREQUENCY = 20; // Minimum time between send (in seconds). We don't wnat to spam the gateway.
|
||||
|
||||
Sensor gw;
|
||||
Sleep sleep;
|
||||
|
||||
//double kwhPerBlink = 1.0/((double)PULSE_FACTOR);
|
||||
MySensor gw;
|
||||
double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour
|
||||
|
||||
boolean pcReceived = false;
|
||||
volatile unsigned long pulseCount = 0;
|
||||
volatile unsigned long lastBlink = 0;
|
||||
volatile unsigned long watt = 0;
|
||||
@@ -34,21 +29,24 @@ unsigned long oldPulseCount = 0;
|
||||
unsigned long oldWatt = 0;
|
||||
double oldKwh;
|
||||
unsigned long lastSend;
|
||||
MyMessage wattMsg(CHILD_ID,V_WATT);
|
||||
MyMessage kwhMsg(CHILD_ID,V_KWH);
|
||||
MyMessage pcMsg(CHILD_ID,V_VAR1);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
gw.begin();
|
||||
gw.begin(incomingMessage);
|
||||
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
gw.sendSketchInfo("Energy Meter", "1.0");
|
||||
|
||||
// Register this device as power sensor
|
||||
gw.sendSensorPresentation(CHILD_ID, S_POWER);
|
||||
gw.present(CHILD_ID, S_POWER);
|
||||
|
||||
// Fetch last known pulse count value from gw
|
||||
pulseCount = oldPulseCount = atol(gw.getStatus(CHILD_ID, V_VAR1));
|
||||
Serial.print("Last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
gw.request(CHILD_ID, V_VAR1);
|
||||
|
||||
attachInterrupt(INTERRUPT, onPulse, RISING);
|
||||
lastSend=millis();
|
||||
}
|
||||
@@ -56,15 +54,17 @@ void setup()
|
||||
|
||||
void loop()
|
||||
{
|
||||
unsigned long now = millis();
|
||||
gw.process();
|
||||
unsigned long now = millis();
|
||||
// Only send values at a maximum frequency or woken up from sleep
|
||||
if (SLEEP_MODE || now - lastSend > 1000*SEND_FREQUENCY) {
|
||||
bool sendTime = now - lastSend > 1000*SEND_FREQUENCY;
|
||||
if (pcReceived && (SLEEP_MODE || sendTime)) {
|
||||
// New watt value has been calculated
|
||||
if (!SLEEP_MODE && watt != oldWatt) {
|
||||
// Check that we dont get unresonable large watt value.
|
||||
// could hapen when long wraps or false interrupt triggered
|
||||
if (watt<((unsigned long)MAX_WATT)) {
|
||||
gw.sendVariable(CHILD_ID, V_WATT, watt); // Send watt value to gw
|
||||
gw.send(wattMsg.set(watt)); // Send watt value to gw
|
||||
}
|
||||
Serial.print("Watt:");
|
||||
Serial.println(watt);
|
||||
@@ -73,26 +73,32 @@ void loop()
|
||||
|
||||
// Pulse cout has changed
|
||||
if (pulseCount != oldPulseCount) {
|
||||
gw.sendVariable(CHILD_ID, V_VAR1, pulseCount); // Send kwh value to gw
|
||||
gw.send(pcMsg.set(pulseCount)); // Send pulse count value to gw
|
||||
double kwh = ((double)pulseCount/((double)PULSE_FACTOR));
|
||||
oldPulseCount = pulseCount;
|
||||
//Serial.print("Pulse count:");
|
||||
//Serial.println(pulseCount);
|
||||
if (kwh != oldKwh) {
|
||||
gw.sendVariable(CHILD_ID, V_KWH, kwh, 4); // Send kwh value to gw
|
||||
//Serial.print("KWH:");
|
||||
//Serial.println(kwh);
|
||||
gw.send(kwhMsg.set(kwh, 4)); // Send kwh value to gw
|
||||
oldKwh = kwh;
|
||||
}
|
||||
}
|
||||
}
|
||||
lastSend = now;
|
||||
} else if (sendTime && !pcReceived) {
|
||||
// No count received. Try requesting it again
|
||||
gw.request(CHILD_ID, V_VAR1);
|
||||
}
|
||||
|
||||
if (SLEEP_MODE) {
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SEND_FREQUENCY * 1000); //sleep for: sleepTime
|
||||
gw.sleep(SEND_FREQUENCY * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
void incomingMessage(MyMessage message) {
|
||||
if (message.type==V_VAR1) {
|
||||
pulseCount = oldPulseCount = message.getLong();
|
||||
Serial.print("Last pulse count from gw:");
|
||||
Serial.println(pulseCount);
|
||||
pcReceived = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <DHT.h>
|
||||
|
||||
#define CHILD_ID_HUM 0
|
||||
@@ -10,12 +8,14 @@
|
||||
#define HUMIDITY_SENSOR_DIGITAL_PIN 3
|
||||
unsigned long SLEEP_TIME = 30; // Sleep time between reads (in seconds)
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
DHT dht;
|
||||
Sleep sleep;
|
||||
float lastTemp;
|
||||
float lastHum;
|
||||
boolean metric = true;
|
||||
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
|
||||
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -26,10 +26,10 @@ void setup()
|
||||
gw.sendSketchInfo("Humidity", "1.0");
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
gw.sendSensorPresentation(CHILD_ID_HUM, S_HUM);
|
||||
gw.sendSensorPresentation(CHILD_ID_TEMP, S_TEMP);
|
||||
gw.present(CHILD_ID_HUM, S_HUM);
|
||||
gw.present(CHILD_ID_TEMP, S_TEMP);
|
||||
|
||||
metric = gw.isMetricSystem();
|
||||
metric = gw.getConfig().isMetric;
|
||||
}
|
||||
|
||||
void loop()
|
||||
@@ -44,9 +44,9 @@ void loop()
|
||||
if (!metric) {
|
||||
temperature = dht.toFahrenheit(temperature);
|
||||
}
|
||||
gw.sendVariable(CHILD_ID_TEMP, V_TEMP, temperature, 1);
|
||||
Serial.print("T: ");
|
||||
Serial.println(temperature);
|
||||
gw.send(msgTemp.set(temperature, 1));
|
||||
Serial.print("T: ");
|
||||
Serial.println(temperature);
|
||||
}
|
||||
|
||||
float humidity = dht.getHumidity();
|
||||
@@ -54,17 +54,13 @@ void loop()
|
||||
Serial.println("Failed reading humidity from DHT");
|
||||
} else if (humidity != lastHum) {
|
||||
lastHum = humidity;
|
||||
gw.sendVariable(CHILD_ID_HUM, V_HUM, humidity, 1);
|
||||
gw.send(msgHum.set(humidity, 1));
|
||||
Serial.print("H: ");
|
||||
Serial.println(humidity);
|
||||
}
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.sleep(SLEEP_TIME * 1000); //sleep a bit
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
// When binary light on is clicked - sketch will send volume up ir command
|
||||
// When binary light off is clicked - sketch will send volume down ir command
|
||||
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
@@ -20,39 +20,26 @@ IRrecv irrecv(RECV_PIN);
|
||||
IRdecode decoder;
|
||||
//decode_results results;
|
||||
unsigned int Buffer[RAWBUF];
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
MyMessage msg(CHILD_1, V_VAR1);
|
||||
|
||||
void setup()
|
||||
{
|
||||
irrecv.enableIRIn(); // Start the ir receiver
|
||||
decoder.UseExtnBuf(Buffer);
|
||||
gw.begin();
|
||||
gw.begin(incomingMessage);
|
||||
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
gw.sendSketchInfo("IR Sensor", "1.0");
|
||||
|
||||
// Register a sensors to gw. Use binary light for test purposes.
|
||||
gw.sendSensorPresentation(CHILD_1, S_LIGHT);
|
||||
gw.present(CHILD_1, S_LIGHT);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (gw.messageAvailable()) {
|
||||
message_s message = gw.getMessage();
|
||||
|
||||
int incomingRelayStatus = atoi(message.data);
|
||||
if (incomingRelayStatus == 1) {
|
||||
irsend.send(NEC, 0x1EE17887, 32); // Vol up yamaha ysp-900
|
||||
} else {
|
||||
irsend.send(NEC, 0x1EE1F807, 32); // Vol down yamaha ysp-900
|
||||
}
|
||||
// Start receiving ir again...
|
||||
irrecv.enableIRIn();
|
||||
}
|
||||
|
||||
|
||||
gw.process();
|
||||
if (irrecv.GetResults(&decoder)) {
|
||||
irrecv.resume();
|
||||
decoder.decode();
|
||||
@@ -61,11 +48,26 @@ void loop()
|
||||
char buffer[10];
|
||||
sprintf(buffer, "%08lx", decoder.value);
|
||||
// Send ir result to gw
|
||||
gw.sendVariable(CHILD_1, V_VAR1, buffer);
|
||||
gw.send(msg.set(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void incomingMessage(MyMessage message) {
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_LIGHT) {
|
||||
int incomingRelayStatus = message.getInt();
|
||||
if (incomingRelayStatus == 1) {
|
||||
irsend.send(NEC, 0x1EE17887, 32); // Vol up yamaha ysp-900
|
||||
} else {
|
||||
irsend.send(NEC, 0x1EE1F807, 32); // Vol down yamaha ysp-900
|
||||
}
|
||||
// Start receiving ir again...
|
||||
irrecv.enableIRIn();
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps out the decode_results structure.
|
||||
// Call this after IRrecv::decode()
|
||||
// void * to work around compiler issue
|
||||
|
||||
@@ -16,12 +16,9 @@
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <RF24.h>
|
||||
#include <EEPROM.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <BH1750.h>
|
||||
#include <Wire.h>
|
||||
|
||||
@@ -29,9 +26,9 @@
|
||||
#define LIGHT_SENSOR_ANALOG_PIN 0
|
||||
unsigned long SLEEP_TIME = 30; // Sleep time between reads (in seconds)
|
||||
|
||||
BH1750 lightSensor;
|
||||
Sensor gw;
|
||||
Sleep sleep;
|
||||
BH1750 lightSensor;
|
||||
MySensor gw;
|
||||
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
|
||||
int lastlux;
|
||||
|
||||
void setup()
|
||||
@@ -42,7 +39,7 @@ void setup()
|
||||
gw.sendSketchInfo("Light Lux Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
gw.sendSensorPresentation(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
|
||||
lightSensor.begin();
|
||||
}
|
||||
@@ -52,14 +49,10 @@ void loop()
|
||||
uint16_t lux = lightSensor.readLightLevel();// Get Lux value
|
||||
Serial.println(lux);
|
||||
if (lux != lastlux) {
|
||||
gw.sendVariable(CHILD_ID_LIGHT, V_LIGHT_LEVEL, lux);
|
||||
gw.send(msg.set(lux));
|
||||
lastlux = lux;
|
||||
}
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.sleep(SLEEP_TIME * 1000);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <RF24.h>
|
||||
#include <EEPROM.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
|
||||
#define CHILD_ID_LIGHT 0
|
||||
#define LIGHT_SENSOR_ANALOG_PIN 0
|
||||
|
||||
unsigned long SLEEP_TIME = 30; // Sleep time between reads (in seconds)
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
|
||||
int lastLightLevel;
|
||||
Sleep sleep;
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -21,7 +19,7 @@ void setup()
|
||||
gw.sendSketchInfo("Light Sensor", "1.0");
|
||||
|
||||
// Register all sensors to gateway (they will be created as child devices)
|
||||
gw.sendSensorPresentation(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
|
||||
}
|
||||
|
||||
void loop()
|
||||
@@ -29,16 +27,12 @@ void loop()
|
||||
int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23;
|
||||
Serial.println(lightLevel);
|
||||
if (lightLevel != lastLightLevel) {
|
||||
gw.sendVariable(CHILD_ID_LIGHT, V_LIGHT_LEVEL, lightLevel);
|
||||
gw.send(msg.set(lightLevel));
|
||||
lastLightLevel = lightLevel;
|
||||
}
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); //sleep for: sleepTime
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.sleep(SLEEP_TIME * 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include <MySensor.h>
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <RF24.h>
|
||||
|
||||
@@ -8,15 +7,11 @@
|
||||
#define CHILD_ID 1 // Id of the sensor child
|
||||
|
||||
MySensor gw;
|
||||
Sleep sleep;
|
||||
// Initialize motion message
|
||||
MyMessage msg(CHILD_ID, V_TRIPPED);
|
||||
|
||||
void setup()
|
||||
{
|
||||
//eeprom_write_byte((uint8_t*)EEPROM_PARENT_NODE_ID_ADDRESS, 1);
|
||||
//eeprom_write_byte((uint8_t*)EEPROM_NODE_ID_ADDRESS, 255);
|
||||
//delay(2000);
|
||||
gw.begin();
|
||||
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
@@ -24,9 +19,7 @@ void setup()
|
||||
|
||||
pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
delay(500);
|
||||
gw.present(CHILD_ID, S_MOTION);
|
||||
delay(1000);
|
||||
|
||||
}
|
||||
|
||||
@@ -38,12 +31,8 @@ void loop()
|
||||
Serial.println(tripped);
|
||||
gw.send(msg.set(tripped?"1":"0")); // Send tripped value to gw
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(200); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepInterrupt(INTERRUPT,CHANGE);
|
||||
// Sleep until interrupt comes in on motion sensor. Send update every two minute.
|
||||
gw.sleep(INTERRUPT,CHANGE, 120000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
#include <Sleep_n0m1.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_BMP085.h>
|
||||
|
||||
#define BARO_CHILD 0
|
||||
#define TEMP_CHILD 1
|
||||
|
||||
#define LIGHT_SENSOR_ANALOG_PIN 0
|
||||
unsigned long SLEEP_TIME = 60; // Sleep time between reads (in seconds)
|
||||
|
||||
Adafruit_BMP085 bmp = Adafruit_BMP085(); // Digital Pressure Sensor
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
|
||||
float lastPressure = -1;
|
||||
float lastTemp = -1;
|
||||
int lastForecast = -1;
|
||||
Sleep sleep;
|
||||
char *weather[] = {"stable","sunny","cloudy","unstable","thunderstorm","unknown"};
|
||||
int minutes;
|
||||
float pressureSamples[180];
|
||||
@@ -24,6 +24,11 @@ bool firstRound = true;
|
||||
float pressureAvg[7];
|
||||
float dP_dt;
|
||||
boolean metric;
|
||||
MyMessage tempMsg(TEMP_CHILD, V_TEMP);
|
||||
MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
|
||||
MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
|
||||
|
||||
|
||||
|
||||
void setup() {
|
||||
gw.begin();
|
||||
@@ -37,9 +42,9 @@ void setup() {
|
||||
}
|
||||
|
||||
// Register sensors to gw (they will be created as child devices)
|
||||
gw.sendSensorPresentation(0, S_BARO);
|
||||
gw.sendSensorPresentation(1, S_TEMP);
|
||||
metric = gw.isMetricSystem();
|
||||
gw.present(BARO_CHILD, S_BARO);
|
||||
gw.present(TEMP_CHILD, S_TEMP);
|
||||
metric = gw.getConfig().isMetric;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,17 +69,17 @@ void loop() {
|
||||
|
||||
|
||||
if (temperature != lastTemp) {
|
||||
gw.sendVariable(1, V_TEMP, temperature,1);
|
||||
gw.send(tempMsg.set(temperature,1));
|
||||
lastTemp = temperature;
|
||||
}
|
||||
|
||||
if (pressure != lastPressure) {
|
||||
gw.sendVariable(0, V_PRESSURE, pressure, 0);
|
||||
gw.send(pressureMsg.set(pressure, 0));
|
||||
lastPressure = pressure;
|
||||
}
|
||||
|
||||
if (forecast != lastForecast) {
|
||||
gw.sendVariable(0, V_FORECAST, weather[forecast]);
|
||||
gw.send(forecastMsg.set(weather[forecast]));
|
||||
lastForecast = forecast;
|
||||
}
|
||||
|
||||
@@ -89,12 +94,8 @@ void loop() {
|
||||
5 = "Unknown (More Time needed)
|
||||
*/
|
||||
|
||||
// Power down the radio. Note that the radio will get powered back up
|
||||
// on the next write() call.
|
||||
delay(1000); //delay to allow serial to fully print before sleep
|
||||
gw.powerDown();
|
||||
sleep.pwrDownMode(); //set sleep mode
|
||||
sleep.sleepDelay(SLEEP_TIME * 1000); // sleep to conserve power
|
||||
delay(300); //delay to allow serial to fully print before sleep
|
||||
gw.sleep(SLEEP_TIME * 1000);
|
||||
}
|
||||
|
||||
int sample(float pressure) {
|
||||
|
||||
@@ -39,6 +39,7 @@ void loop()
|
||||
}
|
||||
|
||||
void incomingMessage(MyMessage message) {
|
||||
Serial.println(gw.getInternalTemp());
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_LIGHT) {
|
||||
// Change relay state
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// Example sketch för a "light switch" where you can control light or something
|
||||
// else from both vera and a local physical button (connected between digital
|
||||
// pin 3 and +5V).
|
||||
// This node also works as a repeader for other nodes
|
||||
|
||||
#include <Relay.h>
|
||||
#include <MySensor.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
#include <Bounce2.h>
|
||||
|
||||
#define RELAY_PIN 4 // Arduino Digital I/O pin number for relay
|
||||
#define BUTTON_PIN 3 // Arduino Digital I/O pin number for button (with 10k pulldown)
|
||||
@@ -13,37 +14,40 @@
|
||||
#define RELAY_ON 0
|
||||
#define RELAY_OFF 1
|
||||
|
||||
int buttVal;
|
||||
int previousVal;
|
||||
int state;
|
||||
int switched = 0;
|
||||
long pressTime = 0; // the last time the button pin was pressed
|
||||
long debounce = 200; // the debounce time, increase if the output flickers
|
||||
|
||||
Relay gw;
|
||||
Bounce debouncer = Bounce();
|
||||
int oldValue=-1;
|
||||
bool state;
|
||||
MySensor gw;
|
||||
MyMessage msg(CHILD_ID,V_LIGHT);
|
||||
|
||||
void setup()
|
||||
{
|
||||
gw.begin();
|
||||
gw.begin(incomingMessage, AUTO, true);
|
||||
|
||||
// Send the sketch version information to the gateway and Controller
|
||||
gw.sendSketchInfo("Relay & Button", "1.0");
|
||||
|
||||
// Set buttonPin as Input
|
||||
pinMode(BUTTON_PIN, INPUT);
|
||||
buttVal = digitalRead(BUTTON_PIN); //read initial state
|
||||
// Setup the button
|
||||
pinMode(BUTTON_PIN,INPUT);
|
||||
// Activate internal pull-up
|
||||
digitalWrite(BUTTON_PIN,HIGH);
|
||||
|
||||
// After setting up the button, setup debouncer
|
||||
debouncer.attach(BUTTON_PIN);
|
||||
debouncer.interval(5);
|
||||
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
gw.sendSensorPresentation(CHILD_ID, S_LIGHT);
|
||||
gw.present(CHILD_ID, S_LIGHT);
|
||||
|
||||
// Make sure relays are off when starting up
|
||||
digitalWrite(RELAY_PIN, RELAY_OFF);
|
||||
// Then set relay pins in output mode
|
||||
pinMode(RELAY_PIN, OUTPUT);
|
||||
|
||||
// Request/wait for relay status
|
||||
gw.getStatus(CHILD_ID, V_LIGHT);
|
||||
setRelayStatus(gw.getMessage()); // Wait here until status message arrive from gw
|
||||
// Set relay to last known state (using eeprom storage)
|
||||
digitalWrite(RELAY_PIN, gw.loadState(CHILD_ID));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -53,40 +57,35 @@ void setup()
|
||||
*/
|
||||
void loop()
|
||||
{
|
||||
if (gw.messageAvailable()) {
|
||||
// ot new messsage from gw
|
||||
message_s message = gw.getMessage();
|
||||
setRelayStatus(message);
|
||||
}
|
||||
gw.process();
|
||||
debouncer.update();
|
||||
// Get the update value
|
||||
int value = debouncer.read();
|
||||
|
||||
buttVal = digitalRead(BUTTON_PIN); // read input value and store it in val
|
||||
|
||||
if (buttVal == HIGH && previousVal == LOW) {
|
||||
// Start counter from when button was pressed
|
||||
pressTime = millis();
|
||||
switched = 0;
|
||||
}
|
||||
|
||||
if (buttVal == HIGH && switched == 0 && millis() - pressTime > debounce) {
|
||||
// Switch state if button pressed more than 200 msec
|
||||
state = state==1?0:1;
|
||||
gw.sendVariable(CHILD_ID, V_LIGHT, state); // We will receive an ack message
|
||||
switched = 1; // No more switches until button is released
|
||||
if (value != oldValue && value!=0) {
|
||||
gw.saveState(CHILD_ID, state);
|
||||
gw.send(msg.set(state==1?0:1), true); // Send and request ack
|
||||
oldValue = value;
|
||||
}
|
||||
previousVal = buttVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void setRelayStatus(message_s message) {
|
||||
if (message.header.type==V_LIGHT) { // This could be M_ACK_VARIABLE or M_SET_VARIABLE
|
||||
state = atoi(message.data);
|
||||
void incomingMessage(MyMessage message) {
|
||||
Serial.println(gw.getInternalTemp());
|
||||
// We only expect one type of message from controller. But we better check anyway.
|
||||
if (message.type==V_LIGHT) {
|
||||
// Change relay state
|
||||
digitalWrite(RELAY_PIN, state==1?RELAY_ON:RELAY_OFF);
|
||||
state = message.getBool();
|
||||
digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
|
||||
// Store state in eeprom
|
||||
gw.saveState(CHILD_ID, state);
|
||||
|
||||
// Write some debug info
|
||||
Serial.print(message.header.messageType == M_ACK_VARIABLE ? "Button":"Gateway");
|
||||
Serial.print(" change. New state: ");
|
||||
Serial.println(state == 1 ?"on":"off" );
|
||||
}
|
||||
Serial.print("Incoming change for sensor:");
|
||||
Serial.print(message.sensor);
|
||||
Serial.print(", New status: ");
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
// gw.messageAvailable() frequently. This sketch should not
|
||||
// sleep.
|
||||
|
||||
#include <Relay.h>
|
||||
#include <MySensor.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <RF24.h>
|
||||
|
||||
Relay gw;
|
||||
MySensor gw;
|
||||
|
||||
void setup()
|
||||
{
|
||||
gw.begin();
|
||||
// The third argument enables relaying mode.
|
||||
gw.begin(NULL, AUTO, true);
|
||||
|
||||
//Send the sensor node sketch version information to the gateway
|
||||
gw.sendSketchInfo("Relaying Node", "1.0");
|
||||
@@ -21,10 +21,7 @@ void setup()
|
||||
|
||||
void loop()
|
||||
{
|
||||
// By calling this regularely you route messages in the background
|
||||
if (gw.messageAvailable()) {
|
||||
|
||||
// Handleincoming message for this node here...
|
||||
}
|
||||
// By calling process() you route messages in the background
|
||||
gw.process();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
// Contribution by: Derek Macias
|
||||
|
||||
|
||||
#include <Sensor.h>
|
||||
#include <MySensor.h>
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include <Servo.h>
|
||||
#include <RF24.h>
|
||||
|
||||
@@ -18,7 +17,7 @@
|
||||
#define DETACH_DELAY 900 // Tune this to let your movement finish before detaching the servo
|
||||
#define CHILD_ID 10 // Id of the sensor child
|
||||
|
||||
Sensor gw;
|
||||
MySensor gw;
|
||||
Servo myservo; // create servo object to control a servo
|
||||
// a maximum of eight servo objects can be created Sensor gw(9,10);
|
||||
unsigned long timeOfLastChange = 0;
|
||||
@@ -33,7 +32,7 @@ void setup()
|
||||
gw.sendSketchInfo("Servo", "1.0");
|
||||
|
||||
// Register all sensors to gw (they will be created as child devices)
|
||||
gw.sendSensorPresentation(CHILD_ID, S_COVER);
|
||||
gw.present(CHILD_ID, S_COVER);
|
||||
|
||||
// Fetch servo state at startup
|
||||
gw.getStatus(CHILD_ID, V_DIMMER);
|
||||
|
||||
Reference in New Issue
Block a user