arduino_projects/sleep/sleep.ino

186 lines
4.6 KiB
C++

#include <SD.h>
#include <SPI.h>
#include <DHT.h>
#include <DS3231.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
#define DHTPIN 2
#define DHTTYPE DHT22
const int chipSelect = 4;
//real time clock ds3231
DS3231 rtc(SDA, SCL);
DHT dht(DHTPIN, DHTTYPE);
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) {
pinMode(LED_BUILTIN, OUTPUT);
dht.begin();
rtc.begin();
Serial.begin(9600);
while (!Serial) { }
Serial.print("Initializing SD card...");
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
while (1);
}
Serial.println("card initialized.");
setup_interrupts();
}
void visualize(float h, float t, String data) {
Serial.print("Hezetasuna:");
Serial.print(h);
Serial.println("");
Serial.print("Tenperatura:");
Serial.print(t);
Serial.println("");
Serial.print("dataString:");
Serial.println(data + "\n");
}
void getAndWrite(){
digitalWrite(LED_BUILTIN, HIGH);
float h = dht.readHumidity();
float t = dht.readTemperature();
double unixTime = rtc.getUnixTime(rtc.getTime());
if (isnan(t) || isnan(h)){
Serial.println("Failed to read from DHT");
return;
}
String dataString = "";
dataString = String(h) + ";" + String(t) + ";" + String(unixTime);
visualize(h, t, dataString);
writeSD(dataString);
digitalWrite(LED_BUILTIN, LOW);
}
void writeSD(String dataString) {
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
}
}
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();*/
getAndWrite();
delay(1000);
}
}
// Go to sleep!
sleep();
}