Humidex (Heat Index) Calculator

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);

}

Hi, sounds intreasting ...
I gat a 404 on the link u posted ... u might want to chekc it out ...

interesting, didn't know this humidex index and a quick google brought up this graph - http://www.ccacac.com/wp-content/uploads/2010/06/Humidex-Graph.pdf -

dewpoint I know and I have written code for it in - Arduino Playground - DHT11Lib -

I like to add this humidex & heat index code to this lib too

refactored the humidex in two steps:

double humidex(double tempC, double DewPoint)
{
  double e = 5417.7530*((1/273.16)-(1/(273.16 + DewPoint)));
  double h = tempC + 0.5555 * ( 6.11 *  exp (e) - 10);
  return h;
}

=> 

double humidex(double tempC, double DewPoint)
{
  double e = 19.833625 - 5417.753 /(273.16 + DewPoint);
  double h = tempC + 3.3941 * exp(e) - 5.555;
  return h;
}

A quick try for the heatIndex -> note the temp is in Fahrenheit
(code not tried)

// http://en.wikipedia.org/wiki/Heat_index
double heatIndex(double tempF, double humidity)
{
  double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6 ; 
  double T = tempF;
  double R = humidity;
  double T2 = T*T;
  double R2 = R*R;
  double TR = T*R;

  double rv = c1 + c2*T + c3*R + c4*T*R + c5*T2 + c6*R2 + c7*T*TR + c8*TR*R + c9*T2*R2;
  return rv;
}

==>

double heatIndex(double tempF, double humidity)
{
  double c1 = -42.38, c2 = 2.049, c3 = 10.14, c4 = -0.2248, c5= -6.838e-3, c6=-5.482e-2, c7=1.228e-3, c8=8.528e-4, c9=-1.99e-6  ;
  double T = tempF;
  double R = humidity;

  double A = (( c5 * T) + c2) * T + c1;
  double B = ((c7 * T) + c4) * T + c3;
  double C = ((c9 * T) + c8) * T + c6;

  double rv = (C * R + B) * R + A;
  return rv;
}
// from 15 float multiplies to 8 float multiplies. 

I assume that by only using the c1..c4 one can get a real fast (1st order) approximation

talofer99:
Hi, sounds intreasting ...
I gat a 404 on the link u posted ... u might want to chekc it out ...

thanks, corrected it to : http://blog.sundeepgoel.com/humidex-calculator-using-arduino/

robtillaart:
interesting, didn't know this humidex index and a quick google brought up this graph - http://www.ccacac.com/wp-content/uploads/2010/06/Humidex-Graph.pdf -

dewpoint I know and I have written code for it in - Arduino Playground - HomePage -

I like to add this humidex & heat index code to this lib too

refactored the humidex in two steps:

Thats brilliant ...
Note : I have found DHT11 to be a very unreliable (read inaccurate), so have ordered the DHT22. Will the same library work for the DHT22 as well ?

Will the same library work for the DHT22 as well

The DHT22 handshake is identical but the interpretation of the dataformat is different.
Try this lib - Arduino Playground - HomePage -

very unreliable (read inaccurate)

The DHT11 / 22 need time between readings (2 seconds) and in the datasheet there is a separate chapter about (re)calibration.

For temperature I prefer the DS18B20 as you can use multiple of them on one pin.

I stumbled onto this thread while trying to get a heat index project going and it was a big help. But now that it's up and running, taking readings and doing math, my numbers don't remotely match up to the actual heat index chart. Did any of you have this same problem?

old thread come alive...

Can you post the code you used?
What temp scale did you use (F or C or ...)