186 lines
4.6 KiB
C++
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();
|
|
}
|