111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#include <SPI.h>
|
|
#include <avr/sleep.h>
|
|
#include <avr/power.h>
|
|
#include <avr/wdt.h>
|
|
|
|
// Seconds to wait before a new sensor reading is logged.
|
|
#define LOGGING_FREQ_SECONDS 60
|
|
|
|
// Number of times to sleep (for 8 seconds) before
|
|
// a sensor reading is taken and sent to the server.
|
|
// Don't change this unless you also change the
|
|
// watchdog timer configuration.
|
|
#define MAX_SLEEP_ITERATIONS LOGGING_FREQ_SECONDS / 8
|
|
|
|
int sleepIterations = 0;
|
|
volatile bool watchdogActivated = false;
|
|
|
|
// Define watchdog timer interrupt.
|
|
ISR(WDT_vect) {
|
|
// Set the watchdog activated flag.
|
|
// Note that you shouldn't do much work inside an interrupt handler.
|
|
watchdogActivated = true;
|
|
}
|
|
|
|
// Put the Arduino to sleep.
|
|
void sleep() {
|
|
// Set sleep to full power down. Only external interrupts or
|
|
// the watchdog timer can wake the CPU!
|
|
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
|
|
|
// Turn off the ADC while asleep.
|
|
power_adc_disable();
|
|
|
|
// Enable sleep and enter sleep mode.
|
|
sleep_mode();
|
|
|
|
// CPU is now asleep and program execution completely halts!
|
|
// Once awake, execution will resume at this point.
|
|
|
|
// When awake, disable sleep mode and turn on all devices.
|
|
sleep_disable();
|
|
power_all_enable();
|
|
}
|
|
|
|
|
|
// Take a sensor reading and send it to the server.
|
|
void logSensorReading() {
|
|
// Take a sensor reading
|
|
int reading = 99999;
|
|
|
|
// Connect to the server and send the reading.
|
|
Serial.print(F("Sending measurement: ")); Serial.println(reading, DEC);
|
|
|
|
}
|
|
void setup_interrupts(void) {
|
|
// Setup the watchdog timer to run an interrupt which
|
|
// wakes the Arduino from sleep every 8 seconds.
|
|
|
|
// Note that the default behavior of resetting the Arduino
|
|
// with the watchdog will be disabled.
|
|
|
|
// This next section of code is timing critical, so interrupts are disabled.
|
|
// See more details of how to change the watchdog in the ATmega328P datasheet
|
|
// around page 50, Watchdog Timer.
|
|
noInterrupts();
|
|
|
|
// Set the watchdog reset bit in the MCU status register to 0.
|
|
MCUSR &= ~(1<<WDRF);
|
|
|
|
// Set WDCE and WDE bits in the watchdog control register.
|
|
WDTCSR |= (1<<WDCE) | (1<<WDE);
|
|
|
|
// Set watchdog clock prescaler bits to a value of 8 seconds.
|
|
WDTCSR = (1<<WDP0) | (1<<WDP3);
|
|
|
|
// Enable watchdog as interrupt only (no reset).
|
|
WDTCSR |= (1<<WDIE);
|
|
|
|
// Enable interrupts again.
|
|
interrupts();
|
|
|
|
Serial.println(F("Setup complete."));
|
|
|
|
}
|
|
|
|
void setup(void) {
|
|
Serial.begin(115200);
|
|
setup_interrupts();
|
|
}
|
|
|
|
void loop(void)
|
|
{
|
|
// Don't do anything unless the watchdog timer interrupt has fired.
|
|
if (watchdogActivated)
|
|
{
|
|
watchdogActivated = false;
|
|
// Increase the count of sleep iterations and take a sensor
|
|
// reading once the max number of iterations has been hit.
|
|
sleepIterations += 1;
|
|
if (sleepIterations >= MAX_SLEEP_ITERATIONS) {
|
|
// Reset the number of sleep iterations.
|
|
sleepIterations = 0;
|
|
// Log the sensor data (waking the CC3000, etc. as needed)
|
|
logSensorReading();
|
|
}
|
|
}
|
|
|
|
// Go to sleep!
|
|
sleep();
|
|
}
|