#include #include #include "RTClib.h" #include "DHT.h" #include "SPI.h" // Data logger - temp, humidity, rtc, air quality, and vcc // Mashup of demo programs for DHT22 and Adafruit data logger shield // John Nordlie, February, 2016 // February, 2019 Added air quality sensor on ping A0 (MiCS 5524) // May, 2019 Added second air quality sensor on pin A1 (MQ-135) #define DHTPIN 2 // what digital pin we're connected to #define DHTTYPE DHT11 // DHT 11 (AM2302), AM2321 // how many milliseconds between grabbing data and logging it. 1000 ms is once a second #define LOG_INTERVAL 60000 // mills between entries (1/minute, reduce to take more/faster data) // how many milliseconds before writing the logged data permanently to disk // set it to the LOG_INTERVAL to write each time (safest) // set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to // the last 10 reads if power is lost but it uses less power and is much faster! #define SYNC_INTERVAL 60000 // mills between calls to flush() - to write data to the card uint32_t syncTime = 0; // time of last sync() #define ECHO_TO_SERIAL 1 // echo data to serial port #define WAIT_TO_START 0 // Wait for serial input in setup() #define BANDGAPREF 14 // special indicator that we want to measure the bandgap #define bandgap_voltage 1.1 // this is not super guaranteed but its not -too- off RTC_DS3231 RTC; // define the Real Time Clock object DHT dht(DHTPIN, DHTTYPE); // define DHT object // for the data logging shield, we use digital pin 10 for the SD cs line const int chipSelect = 10; // the logging file File logfile; int airQuality = 0; // MiCS 5524 on pin A0 int airQuality2 = 0; // MQ-135 on pin A1 void error(char *str) { Serial.print("error: "); Serial.println(str); while(1); } void setup(void) { Serial.begin(9600); Serial.println(); #if WAIT_TO_START Serial.println("Type any character to start"); while (!Serial.available()); #endif //WAIT_TO_START // initialize the SD card Serial.print("Initializing SD card..."); // make sure that the default chip select pin is set to // output, even if you don't use it: pinMode(10, OUTPUT); // see if the card is present and can be initialized: if (!SD.begin(chipSelect)) { error("Card failed, or not present"); } Serial.println("card initialized."); // create a new file char filename[] = "LOGGER00.CSV"; for (uint8_t i = 0; i < 100; i++) { filename[6] = i/10 + '0'; filename[7] = i%10 + '0'; if (! SD.exists(filename)) { // only open a new file if it doesn't exist logfile = SD.open(filename, FILE_WRITE); break; // leave the loop! } } if (! logfile) { error("couldnt create file"); } Serial.print("Logging to: "); Serial.println(filename); // connect to RTC Wire.begin(); if (!RTC.begin()) { logfile.println("RTC failed"); #if ECHO_TO_SERIAL Serial.println("RTC failed"); #endif //ECHO_TO_SERIAL } dht.begin(); // Initialize DHT 22 sensor // print header to data file logfile.println("millis,stamp,datetime,temp,humidity,airQuality,airQuality2,vcc"); #if ECHO_TO_SERIAL Serial.println("millis,stamp,datetime,temp,humidity,airQuality,airQuality2,vcc"); #endif //ECHO_TO_SERIAL } void loop(void) { DateTime now; // delay for the amount of time we want between readings delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL)); // log milliseconds since starting uint32_t m = millis(); logfile.print(m); // milliseconds since start logfile.print(", "); #if ECHO_TO_SERIAL Serial.print(m); // milliseconds since start Serial.print(", "); #endif // fetch the time now = RTC.now(); // log time logfile.print(now.unixtime()); // seconds since 1/1/1970 logfile.print(", "); logfile.print('"'); logfile.print(now.year(), DEC); logfile.print("/"); logfile.print(now.month(), DEC); logfile.print("/"); logfile.print(now.day(), DEC); logfile.print(" "); logfile.print(now.hour(), DEC); logfile.print(":"); logfile.print(now.minute(), DEC); logfile.print(":"); logfile.print(now.second(), DEC); logfile.print('"'); #if ECHO_TO_SERIAL Serial.print(now.unixtime()); // seconds since 1/1/1970 Serial.print(", "); Serial.print('"'); Serial.print(now.year(), DEC); Serial.print("/"); Serial.print(now.month(), DEC); Serial.print("/"); Serial.print(now.day(), DEC); Serial.print(" "); Serial.print(now.hour(), DEC); Serial.print(":"); Serial.print(now.minute(), DEC); Serial.print(":"); Serial.print(now.second(), DEC); Serial.print('"'); #endif //ECHO_TO_SERIAL // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) float h = dht.readHumidity(); // Read temperature as Celsius (the default) float t = dht.readTemperature(); // Read temperature as Fahrenheit (isFahrenheit = true) float f = dht.readTemperature(true); logfile.print(", "); logfile.print(f); logfile.print(", "); logfile.print(h); #if ECHO_TO_SERIAL Serial.print(", "); Serial.print(f); Serial.print(", "); Serial.print(h); #endif //ECHO_TO_SERIAL airQuality = analogRead(A0); airQuality2 = analogRead(A1); logfile.print(", "); logfile.print(airQuality); logfile.print(", "); logfile.print(airQuality2); #if ECHO_TO_SERIAL Serial.print(", "); Serial.print(airQuality); Serial.print(", "); Serial.print(airQuality2); #endif // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref analogRead(BANDGAPREF); delay(10); int refReading = analogRead(BANDGAPREF); float supplyvoltage = (bandgap_voltage * 1024) / refReading; logfile.print(", "); logfile.print(supplyvoltage); #if ECHO_TO_SERIAL Serial.print(", "); Serial.print(supplyvoltage); #endif // ECHO_TO_SERIAL logfile.println(); #if ECHO_TO_SERIAL Serial.println(); #endif // ECHO_TO_SERIAL // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card // which uses a bunch of power and takes time if ((millis() - syncTime) < SYNC_INTERVAL) return; syncTime = millis(); logfile.flush(); }