I wrote a little utility to log the Temperature and Relative Humidity in my house. The air gets very dry here in Denver, and I want to record a baseline temperature/RH in my house before I invest in a full house humidifier.
It is really pretty simple, using an Arduino Nano, DS3231 Real Time Clock, a micro SD card adapter, and a DHT22 for the sensor. It writes a simple 3 element Comma separated value file with the time in UNIX seconds, the temperature in C, and Relative Humidity percentage.
#include <DHT.h>
#include <TimeLib.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include <DS1307RTC.h> // a basic DS1307 library that returns time as a time_t
// include the SD library:
#include <SPI.h>
#include <SD.h>
/*
Takes commands from the serial monitor and returns properly formatted JSON object to Serial monitor
by Ken Terrell
12/2018
v0.1
DS3231 is at i2c Address 0x68 by default
AT24C32 is at 0x57 by default
Connections i2c
===============
Connect SCL to analog 5
Connect SDA to analog 4
Connect VDD to 3.3V DC
Connect GROUND to common ground
Connections SPI/SD
==================
SD card attached to SPI bus as follows:
VDD - 3.3V DC
MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
CS - pin 10 on Arduino Uno/Duemilanove/Diecimila
GND - Common Ground
*/
// Adafruit SD shields and modules: pin 10
const int chipSelect = 10;
#define TIME_HEADER "T" // Header tag for serial time sync message
#define DHTPIN 2 // what digital pin we're connected to
// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
//#define DHTTYPE DHT21 // DHT 21 (AM2301)
DHT dht(DHTPIN, DHTTYPE);
// Create File object for logfile.csv
File logFile;
void setup() {
Serial.begin(115200);
while (!Serial) ; // wait until Arduino Serial Monitor opens
Wire.begin(); // Start the I2C interface
dht.begin(); // STart temp/RH sensor
displayLogo();
initRTC();
initSD();
Alarm.timerRepeat(60, logCSVReadings);
}
void loop()
{
switch (Serial.read())
{
case 'g':
showCSVReadings();
break;
case 'd':
dumpCSVReadings();
break;
case 'e':
eraseCSVfile();
break;
case 's':
time_t t = processSyncMessage();
if (t != 0) {
RTC.set(t); // set the RTC and the system time to the received value
setTime(t);
}
break;
default:
break;
}
Alarm.delay(0); // Service the timers with minimal delay
}
void eraseCSVfile(void) {
SD.remove("logfile.csv");
if (SD.exists("logfile.csv")) {
} else {
Serial.println("logfile.csv erased.");
}
}
void showCSVReadings(void) {
//String jsonString = String(42);
float temp = dht.readTemperature();
float RH = dht.readHumidity();
//jsonString = (String)now() + "," + (String)temp + "," + (String)RH;
//Serial.println(jsonString);
Serial.println((String)now() + "," + (String)temp + "," + (String)RH);
}
void dumpCSVReadings(void) {
// re-open the file for reading:
logFile = SD.open("logfile.csv");
if (logFile) {
Serial.println("logfile.csv:");
// read from the file until there's nothing else in it:
while (logFile.available()) {
Serial.write(logFile.read());
}
// close the file:
logFile.close();
Serial.println("---");
} else {
// if the file didn't open, print an error:
Serial.println("error opening logfile.csv");
}
}
void logCSVReadings(void) {
String jsonString = String(42);
float temp = dht.readTemperature();
float RH = dht.readHumidity();
jsonString = (String)now() + "," + (String)temp + "," + (String)RH;
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
logFile = SD.open("logfile.csv", FILE_WRITE);
// if the file opened okay, write to it:
if (logFile) {
logFile.println(jsonString);
Serial.println(jsonString);
// close the file:
logFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("logCSVReadings() - error opening logfile.csv!");
}
}
/* code to process time sync messages from the serial port */
unsigned long processSyncMessage() {
unsigned long pctime = 0L;
const unsigned long DEFAULT_TIME = 1357041600; // Jan 1 2013
if (Serial.find(TIME_HEADER)) {
pctime = Serial.parseInt();
return pctime;
if ( pctime < DEFAULT_TIME) { // check the value is a valid time (greater than Jan 1 2013)
pctime = 0L; // return 0 to indicate that the time is not valid
}
}
return pctime;
}
void initRTC(void)
{
// Serial.println("------------------------------------");
// Serial.println("Attempting to set system time from RTC");
setSyncProvider(RTC.get); // the function to get the time from the RTC
if (timeStatus() != timeSet) {
Serial.println("Unable to sync with the RTC");
}
else {
Serial.print ("Current Time: "); Serial.println(now());
}
// Serial.println("------------------------------------");
}
void initSD(void)
{
// Serial.println("------------------------------------");
// Serial.println("Attempting to initialize SD card interface");
if (!SD.begin(chipSelect)) {
Serial.println("initSD() - initialization failed!");
while (1);
}
// Serial.println("initialization done.");
// Serial.println("------------------------------------");
}
void displayLogo(void)
{
Serial.println("CSVTempRHLogger");
}
Let me know if you find this usefull