/* * For the Riffle Datalogger * The sketch logs the temperature and humidity from a DHT22 sensor and * temperature from two MCP9808 I2C sensors. * The logging interval is editable. * It uses the RTC as a scheduler by using an Alarm and Interrupt * pin to wake up the ATmega at an interval. * It logs to the SD card and outputs time and values in the Serial * Monitor * Adapted by C. Fastie (6/8/16) from Kina Smith's SHT21_Logger.ino */ #include #include #include #include #include // Kina's fork #include #include "Adafruit_MCP9808.h" // for the Adafruit MCP9808 temperature sensor https://www.adafruit.com/products/1782?&main_page=product_info&products_id=1782 #include #include "DHT.h" //for DHT temp and humidity sensors DS3231 rtc; //initialize the Real Time Clock const int led = 9; //led pin const int bat_v_pin = A3; //battery voltage pin (1/2 of actual voltage) const int bat_v_enable = 4; //enable pin for bat. voltage read const int sd_pwr_enable = 6; //enable pin for SD power const int chipSelect = 7; //chipSelect for SD card const int RTC_INT = 5; //RTC interrupt pin int interval_sec = 300; //Logging interval in seconds //sensor values float bat_v; float DHTh; float DHTt; float MCP1; float MCP2; // DHT22 initialization #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 #define DHTPIN 2 // what digital pin the DHT is connected to DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor #define SENSOR_MS 400 // Sensor reading delay // Create the MCP9808 temperature sensor objects Adafruit_MCP9808 tempsensor1 = Adafruit_MCP9808(); Adafruit_MCP9808 tempsensor2 = Adafruit_MCP9808(); void pin5_interrupt() { disableInterrupt(RTC_INT); //first it disables the interrupt so it doesn't get retriggered } //Puts the MCU into power saving sleep mode and sets the wake time void enterSleep(DateTime& dt) { //argument is Wake Time as a DateTime object rtc.clearAlarm(); //resets the alarm interrupt status on the RTC enableInterrupt(RTC_INT, pin5_interrupt, FALLING); //enables the interrupt on Pin5 rtc.enableAlarm(dt); //Sets the alarm on the RTC to the specified time (using the DateTime Object passed in) delay(100); //wait for a moment for everything to complete LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF); //power down everything until the alarm fires } float getBat_v(int read_p, int en_p) { float v; digitalWrite(en_p, LOW); //write mosfet low to enable read delay(10); //wait for it to settle v = analogRead(read_p); //read voltage delay(10); //wait some more...for some reason digitalWrite(en_p, HIGH); //disable read circuit v = (v * (3.3 / 1024.0)) * 2.0; //calculate actual voltage return v; } void writeDataToCard(long utc, float DHTh, float DHTt, float MCP1, float MCP2, float v) { //open and write files to SD card File dataFile = SD.open("MCPDHTs.CSV", FILE_WRITE); if (dataFile) { dataFile.print(utc); dataFile.print(","); dataFile.print(DHTh); dataFile.print(","); dataFile.print(DHTt); dataFile.print(","); dataFile.print(MCP1); dataFile.print(","); dataFile.print(MCP2); dataFile.print(","); dataFile.print(v); dataFile.println(); dataFile.close(); } } void Blink(byte PIN, int DELAY_MS) { //Blink an LED pinMode(PIN, OUTPUT); digitalWrite(PIN, HIGH); delay(DELAY_MS); digitalWrite(PIN, LOW); delay(DELAY_MS); } void setup() { Wire.begin(); Serial.begin(9600); pinMode(bat_v_enable, OUTPUT); pinMode(sd_pwr_enable, OUTPUT); pinMode(RTC_INT, INPUT_PULLUP); //RTC interrupt line requires a pullup rtc.begin(); //start RTC // rtc.adjust(DateTime((__DATE__), (__TIME__))); //sets the RTC to the computer time. digitalWrite(sd_pwr_enable, LOW); //Enable power for SD card if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present"); while (1) { Blink(led, 200); } } //MCP9808 temperature sensors -- each has a different address if (!tempsensor1.begin(0x19)) { Serial.println("Couldn't find MCP9808 A0!"); while (1); } if (!tempsensor2.begin(0x1A)) { Serial.println("Couldn't find MCP9808 A1!"); while (1); } } void loop() { DateTime now = rtc.now(); //get the current time DateTime nextAlarm = DateTime(now.unixtime() + interval_sec); Serial.print("The Current Time is: "); Serial.print(now.unixtime()); Serial.println(); //take readings bat_v = getBat_v(bat_v_pin, bat_v_enable); //takes 20ms // Read DHT sensor float DHTh = dht.readHumidity(); // Read temperature as Celsius (the default) float DHTt = dht.readTemperature(); // Read MCP 1 tempsensor1.shutdown_wake(0); float MCP1 = tempsensor1.readTempC(); delay(250); tempsensor1.shutdown_wake(1); // shutdown MCP9808 // Read MCP 2 tempsensor2.shutdown_wake(0); float MCP2 = tempsensor2.readTempC(); delay(250); tempsensor2.shutdown_wake(1); // shutdown MCP9808 Serial.print(DHTh); Serial.print(", "); Serial.print(DHTt); Serial.print(", "); Serial.print(MCP1); Serial.print(", "); Serial.print(MCP2); Serial.print(", "); Serial.print(bat_v); Serial.println(); //write data writeDataToCard(now.unixtime(), DHTh, DHTt, MCP1, MCP2, bat_v); Blink(led, 100); Serial.print("Sleeping for "); Serial.print(interval_sec); Serial.print(" seconds."); Serial.println(); enterSleep(nextAlarm); //enter Sleep until alarm fires }