Created
November 7, 2015 19:26
-
-
Save ProfJayHam/95cb4a0ec77171eb3836 to your computer and use it in GitHub Desktop.
HTU21DF RH and temperature datalogger program (with statistics) for Arduino R3 and datalogger shield
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* HTU_logger_stat_V1.ino | |
RH and Temp data logger for the Arduino using a Adafruits HTU21D breakout board and | |
datalogger shield. Includes statistics - averages data over user defined intervals | |
J. Ham, Colorado State Univesity | |
last revision: 11/05/2015 | |
Desciption: Program gets Temperature and RH from HTU21D sensor at a user-defined | |
interval (5s default), calculates averages over a user-defined interval (10 min default), | |
and saves the result to SD card with time stamp obtained from the RTC. | |
Also calculates and saves Dewpoint temperature as calculated with user-defined function. | |
The program waits to start until 0 seconds into a 1 min interval. | |
Output format: | |
Date and Time | |
Unix time | |
T | |
RH | |
Tdew | |
Number of samples in statistic | |
Avg T | |
Avg Tdew | |
Maximum T | |
Minimum T | |
Example header and output | |
datetime,unixtime,temp,RH,tdew,nT,avgT,avgtdew,maxT,minT | |
2015-11-06 16:20:00,1446826800,21.47,29.84,3.11,96,21.49,3.04,21.52,21.43 | |
Reference: portions adapted from adafruits lighttemplogger.ped | |
http://learn.adafruit.com/adafruit-data-logger-shield/downloads | |
Notes:The RTC must be set prior to running this program. | |
https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/understanding-the-code | |
search for the word "unique" to find user-adjustable variables such as the sampling | |
interval or the file name to be stored on the sd card. | |
Libraries: | |
RTC library: https://github.com/adafruit/RTClib/ | |
HTU21DF library: https://github.com/adafruit/Adafruit_HTU21DF_Library/ | |
Statistic: https://github.com/kiuz/Arduino-Statistic-Library | |
Hardware Requirements: | |
Shield https://www.adafruit.com/products/1141 | |
Sensor: https://www.adafruit.com/product/1899 | |
Wiring for HTU21DF to Arduino or Datalogger Shield | |
VIN to 5V | |
GND to Ground | |
SCL to SCL (or analog 5, the I2C bus) | |
SDA to SDA (or analog 4, the I2C bus) | |
3Vo not used | |
Jumper wires: from D4 to L1, and D5 to L2 on Shield | |
*/ | |
// include files | |
#include <SPI.h> | |
#include <SD.h> | |
#include <Wire.h> | |
#include "RTClib.h" | |
#include "Adafruit_HTU21DF.h" | |
#include "Statistic.h" | |
// ECHO_TO_SERIAL controls output to computers serial monitor | |
// turn on (1) for testing/troubleshooting,// turn off (0)during field deployment | |
#define ECHO_TO_SERIAL 1 // 1 = echo results to screen, 0 = no echo, unique | |
// digital pins that connect to the green and red LEDs on the datalogger shield | |
// run jumper wire from digital pins 4 and 5 to L1 and L2 connections on datalogger shield | |
#define greenLEDpin 4 // L1, flashing green indicates sampling | |
#define redLEDpin 5 // L2, solid red led indicates error | |
//class initialization | |
Adafruit_HTU21DF htu = Adafruit_HTU21DF(); // HTU21DF | |
RTC_DS1307 RTC; // define the Real Time Clock object | |
// for the data logging shield, we use digital pin 10 for the SD cs line | |
const int chipSelect = 10; | |
// the logging file for SD card | |
File logfile; | |
const unsigned long TRHSTEP = 5000UL; // Sensor query period, default 5000 ms or 5 sec, unique | |
const unsigned long LOGRATE = 10UL; // log and averaging period, default 10 minutes, unique | |
unsigned long trhMillis = 0; // Time interval tracking | |
//define global variables | |
float RH_htu, T_htu; // htu sensor output, RH and T | |
float T_dew; // dewpoint temperature | |
float avgT, avgTdew; // averages | |
float maxT, minT; // max and min T | |
int nT; // number of records for stats | |
int oldminute = 99; | |
//Statistics data | |
Statistic TStats; // Temperature, C | |
Statistic DStats; // dewpoint, C | |
//******************** Setup ******************** | |
void setup(void) | |
{ | |
Serial.begin(9600); | |
Serial.println(); | |
// LEDs on datalogger shield | |
pinMode(redLEDpin, OUTPUT); | |
pinMode(greenLEDpin, OUTPUT); | |
// initialize the SD card | |
#if ECHO_TO_SERIAL | |
Serial.print("Initializing SD card..."); | |
#endif | |
// 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"); | |
} | |
#if ECHO_TO_SERIAL | |
Serial.println("card initialized."); | |
#endif | |
// create a new file name | |
char filename[] = "RHlog_00.csv"; // "RHlog" is root name, must be 5 characters, unique | |
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"); | |
} | |
#if ECHO_TO_SERIAL | |
Serial.print("Logging to: "); | |
Serial.println(filename); | |
#endif | |
// connect to RTC | |
Wire.begin(); | |
if (!RTC.begin()) { | |
error("RTC failed"); | |
} | |
#if ECHO_TO_SERIAL | |
Serial.println("RTC initalized"); | |
#endif //ECHO_TO_SERIAL | |
// initialize HTU sensor | |
htu.begin(); | |
Wire.begin(); | |
if (!htu.begin()) { | |
error("HTU failed"); | |
} | |
#if ECHO_TO_SERIAL | |
Serial.println("HTU initalized"); | |
#endif //ECHO_TO_SERIAL | |
//clear data arrays | |
TStats.clear(); | |
DStats.clear(); | |
// delay until time is 0 second into 1 min interval | |
DateTime now; | |
#if ECHO_TO_SERIAL | |
Serial.println("waiting to start at O sec into 1 min"); | |
#endif //ECHO_TO_SERIAL | |
while(now.second() !=0) { | |
now = RTC.now(); | |
} | |
// write header to SD card and screen | |
logfile.println("datetime,unixtime,temp,RH,tdew,nT,avgT,avgtdew,maxT,minT"); | |
#if ECHO_TO_SERIAL | |
Serial.println("datetime, unixtime, temp, RH, tdew"); | |
#endif | |
} | |
//******************* Main Loop *********************** | |
void loop(void) | |
{ | |
DateTime now=RTC.now(); | |
unsigned long curMillis = millis(); // Get current time | |
// read sensor | |
if (curMillis - trhMillis >= TRHSTEP) { // Time for new measurements? | |
trhMillis = curMillis; | |
T_htu=htu.readTemperature(); // read temperature | |
RH_htu=htu.readHumidity(); // read humidity | |
T_dew=dewpoint(T_htu, RH_htu); // calc dewpoint | |
TStats.add(T_htu); // store var in array for stats | |
DStats.add(T_dew); | |
#if ECHO_TO_SERIAL | |
printData(); | |
#endif | |
digitalWrite(greenLEDpin, HIGH); // tutn on LED in sample loop | |
} // end sampling loop | |
if (curMillis - trhMillis >= 500) { // turn off green LED after 0.5 sec | |
digitalWrite(greenLEDpin, LOW); | |
} | |
// Calculate statistics and log to sd card | |
if ( (now.minute() % LOGRATE)==0 & now.minute() != oldminute) { | |
oldminute=now.minute(); | |
calcStat(); | |
logData(); // send data to sd card | |
} | |
} // end main loop | |
//****************************************** | |
//* subroutines and user defined functions * | |
//****************************************** | |
float dewpoint(float T, float RH) { | |
// Murray (1967) On the Computation of Saturation Vapor Pressure | |
float b,dp; | |
b = (log(RH / 100) + ((17.27 * T) / (237.3 + T))) / 17.27; | |
dp = (237.3 * b) / (1 - b); | |
return dp; | |
} | |
void calcStat() { | |
//Averages | |
avgT = TStats.average(); | |
avgTdew = DStats.average(); | |
//avgRH = RStats.average(); | |
maxT=TStats.maximum(); | |
minT=TStats.minimum(); | |
nT = TStats.count(); | |
//clear data arrays | |
TStats.clear(); | |
DStats.clear(); | |
} | |
void printData() { | |
DateTime now; | |
now = RTC.now(); | |
Serial.print(now.year(), DEC); | |
Serial.print(F("-")); | |
printDigits(now.month()); | |
Serial.print(F("-")); | |
printDigits(now.day()); | |
Serial.print(F(" ")); | |
printDigits(now.hour()); | |
Serial.print(F(":")); | |
printDigits(now.minute()); | |
Serial.print(F(":")); | |
printDigits(now.second()); | |
Serial.print(F(", ")); | |
Serial.print(now.unixtime()); // seconds since 1/1/1970 | |
Serial.print(F(", ")); | |
Serial.print(T_htu); | |
Serial.print(F(", ")); | |
Serial.print(RH_htu); | |
Serial.print(F(", ")); | |
Serial.print(T_dew); | |
Serial.println(); | |
} | |
void logData() { | |
DateTime now; | |
now = RTC.now(); | |
logfile.print(now.year(), DEC); | |
logfile.print(F("-")); | |
logDigits(now.month()); | |
logfile.print(F("-")); | |
logDigits(now.day()); | |
logfile.print(F(" ")); | |
logDigits(now.hour()); | |
logfile.print(F(":")); | |
logDigits(now.minute()); | |
logfile.print(F(":")); | |
logDigits(now.second()); | |
logfile.print(F(",")); | |
logfile.print(now.unixtime()); // seconds since 1/1/1970 | |
logfile.print(F(",")); | |
logfile.print(T_htu); | |
logfile.print(F(",")); | |
logfile.print(RH_htu); | |
logfile.print(F(",")); | |
logfile.print(T_dew); | |
logfile.print(F(",")); | |
logfile.print(nT); | |
logfile.print(F(",")); | |
logfile.print(avgT); | |
logfile.print(F(",")); | |
logfile.print(avgTdew); | |
logfile.print(F(",")); | |
logfile.print(maxT); | |
logfile.print(F(",")); | |
logfile.print(minT); | |
logfile.println(); | |
logfile.flush(); | |
} | |
void printDigits(int digits){ | |
// utility function for digital clock display: prints preceding colon and leading 0 | |
// Serial.print(":"); | |
if(digits < 10) | |
Serial.print('0'); | |
Serial.print(digits); | |
} | |
void logDigits(int digits){ | |
// utility function for digital clock display: prints preceding colon and leading 0 | |
// logfile.print(":"); | |
if(digits < 10) | |
logfile.print('0'); | |
logfile.print(digits); | |
} | |
// error subroutine, does this when error occurs | |
void error(char *str) | |
{ | |
#if ECHO_TO_SERIAL | |
Serial.print("error: "); | |
Serial.println(str); | |
#endif | |
// turn on red LED to indicate error | |
digitalWrite(redLEDpin, HIGH); | |
while(1); // halt program | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A radiation shield for the HTU21DF is available here
http://www.thingiverse.com/thing:1067700