Given the high cost of running air conditioners, was kicking around the idea of being able to automatically determine when is the right time to use a desert cooler (aka evaporative cooler or swamp cooler) vs an air conditioner. Can across some papers on Humidex / Heat Index which could be used to determine the same, therefore decided to implement the basic sensing and calculations in Arduino using DHT11 and BMP085 sensors for humidity and temperature respectively, thereafter using a local instance of Mango M2M server to record data and generate alerts
Some more details at : http://blog.sundeepgoel.com/humidex-calculator-using-arduino/
Will update the code and construction details soon.
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <SPI.h>
#include <util.h>
#include <DHT11.h>
#include <math.h>
// BM035 Connections
// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
// Connect GND to Ground
// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
// EOC is not used, it signifies an end of conversion
// XCLR is a reset pin, also not used here
//DH11 Connections
//LM035 Connections
//Dex point and humidex calculator
//Humidex = (air temperature) + h
// h = (0.5555)*(e - 10.0);
// e = 6.11 * exp(5417.7530 * ((1/273.16) - (1/dewpoint)))
// http://www.physlink.com/reference/weather.cfm
// heat index (HI) or humiture
// http://en.wikipedia.org/wiki/Heat_index
// http://www.nws.noaa.gov/os/heat/index.shtml#heatindex
//HI = -42.379 + 2.04901523T + 10.14333127R - 0.22475541TR - 6.83783x10
// -3T2 - 5.481717x10 - 2R2 + 1.22874x10 -3T2R + 8.5282x10
// -4TR2 - 1.99x10-6T2R2
// where T = ambient dry bulb temperature (°F)
// R = relative humidity (integer percentage).
// http://www.4wx.com/wxcalc/formulas/heatIndex.php
//Heat Index = -42.379 + (2.04901523 x T) + (10.14333127 x R) - (0.22475541 x T x R) - (6.83783x10-3 x T2) - (5.481717x10-2 x R2) + (1.22874x10-3 x T2 x R) + (8.5282x10-4 x T x R2) - (1.99x10-6 x T2 x R2)
// Where,
//T = Temperature in ?F
// R = Relative Humidity in %
// Heat index is utilized only in warm weather >=70° F
// http://www.gorhamschaffler.com/humidity_formulas.htm
Adafruit_BMP085 bmp;
dht11 DHT11;
#define DHTTYPE DHT11 // DHT 11
#define DHT11PIN 2 // what pin we're connected to
#define aref_voltage 1.1 // reference voltage given to LM35, Using basic config of LM35 this is for 2-150 C @ 0mv + 10mv per degree centigrade
double a = 17.271;
double b = 237.7;
double bmp_temperature;
double bmp_pressure;
double DH11_temperature;
double DH11_humidity;
double LM35_temperature;
void setup() {
analogReference(INTERNAL); // sets ref voltage for conversion to 1.1 vs the default 5 V
Serial.begin(9600);
bmp.begin();
}
void loop() {
DH11_temperature = readDH11Temperature();
printSensorReadingToSerial("DH11Temp", DH11_temperature);
bmp_temperature = readBMPTemperature();
printSensorReadingToSerial("BMPTemp", bmp_temperature );
bmp_pressure = readBMPPressure();
printSensorReadingToSerial("BMPPressure", bmp_pressure);
LM35_temperature = readLM35Temperature();
printSensorReadingToSerial("LM35Temp", LM35_temperature);
delay(1000);
DH11_humidity = readDH11Humidity();
printSensorReadingToSerial("DH11Humidity", DH11_humidity);
double dewpoint = calculatDEWpoint(bmp_temperature,DH11_humidity );
printSensorReadingToSerial("DewPoint", dewpoint);
double humidex = calculateHumidexValue(bmp_temperature, dewpoint);
printSensorReadingToSerial("Humidex", humidex);
delay(59000);
}
double readBMPTemperature() {
return bmp.readTemperature();
}
double readBMPPressure() {
return bmp.readPressure();
// Calculate altitude assuming 'standard' barometric
// pressure of 1013.25 millibar = 101325 Pascal
//Serial.print("Altitude = ");
//Serial.print(bmp.readAltitude());
//Serial.println(" meters");
// you can get a more precise measurement of altitude
// if you know the current sea level pressure which will
// vary with weather and such. If it is 1015 millibars
// that is equal to 101500 Pascals.
//Serial.print("Real altitude = ");
//Serial.print(bmp.readAltitude(101500));
//Serial.println(" meters");
//Serial.println();
}
double readDH11Temperature() {
int chk = DHT11.read(DHT11PIN);
//Serial.print("Read sensor: ");
switch (chk) {
//case 0: Serial.println("OK"); break;
case 0:
break;
case -1:
Serial.println("Checksum error");
break;
case -2:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
}
// Serial.print("Humidity (%): ");
//Serial.print((float) DHT11.humidity, 2);
//Serial.print(" ");
// Serial.print("Temperature (oC): ");
return DHT11.temperature;
}
double readDH11Humidity() {
int chk = DHT11.read(DHT11PIN);
switch (chk) {
//case 0: Serial.println("OK"); break;
case 0:
break;
case -1:
Serial.println("Checksum error");
break;
case -2:
Serial.println("Time out error");
break;
default:
Serial.println("Unknown error");
break;
}
return DHT11.humidity;
}
double readLM35Temperature() {
int tempPin = 0; // Analog pin used for measusing LM35 output
float tempC;
float voltage;
int sensorReading = analogRead(tempPin); //read the value from the sensor i.e. 0-1023 after a ADC conversion
// Serial.print("Sensor Reading = ");
// Serial.println (sensorReading);
voltage = (sensorReading * aref_voltage * 1000) / 1024.0; // Convert sensor
// print out the voltage
/// Serial.print(" Voltage from sensor : ");
// Serial.print(voltage);
// Serial.println(" milli volts");
tempC = (voltage * 100.0) /1000; //convert the analog data to temperature
return tempC;
}
double calculatDEWpoint(double temp, double RH)
{
// for dewpoint see: http://en.wikipedia.org/wiki/Dew_point
double gammavalue = calculateDewPointGammaValue(temp, RH);
double dewpoint = (b * gammavalue) / (a - gammavalue);
// Serial.print("Dewpoint = ");
// Serial.println(dewpoint);
return dewpoint;
}
double calculateDewPointGammaValue (double temp, double RH)
{
double gamma = ((a*temp)/(b+temp)) + log (RH/100);
return gamma;
}
double calculateHumidexValue (double temp, double DewPoint)
{
double h = temp + 0.5555 * ( 6.11 * exp ( calculateHumidexEValue(DewPoint)) - 10);
// Serial.print("Humidex = ");
// Serial.println(h);
return h;
}
double calculateHumidexEValue (double DewPoint)
{
double e = 5417.7530*((1/273.16)-(1/(273.16 + DewPoint)));
// Serial.print("evalue = ");
// Serial.println(e);
return e;
}
void printSensorReadingToSerial(String key, double value) {
Serial.print(key);
Serial.print("=");
Serial.println(value);
}