Showing posts with label DHT11. Show all posts
Showing posts with label DHT11. Show all posts

Wednesday, May 27, 2015

Arduino Due + ESP8266 + DHT11, to update ThingSpeak

Here is a example to use Arduino Due read sensed data, humidity and temperature, from DHT11, send to ThingSpeak.com using WiFi module DSP8266.


ThingSpeak is an application platform for the Internet of Things (IoT). ThingSpeak allows you to build an application around data collected by sensors. Features of ThingSpeak include: real-time data collection, data processing, visualizations, apps, and plugins.

Before start,you have to sign-up ThingSpeak, visit: https://thingspeak.com/ to register, creat channel, get API Key. You can also try it using web browser.


Connection, refer to last post of "Arduino Due + ESP8266 + DHT11, to update dweet.io".

Arduino code, Due8266Client_ThingSpeak.ino
/*
Arduino Due + ESP 8266 WiFi Module
- As STA to Join AP
- Connect to thingspeak.com as client, 
  to update my thing of Humidity and Temperature
  (read from DHT11)

Serial (Tx/Rx) communicate to PC via USB
Serial3 (Tx3/Rx3) connect to ESP8266
Tx3 - ESP8266 Rx
Rx3 - ESP8266 Tx
ESP8266 CH_PD Connect to ESP8266 VCC

DHT11 connect to pin 2 of Arduino Due

for firmware:
"v0.9.5.2 AT Firmware"
(http://goo.gl/oRdG3s)
AT version:0.21.0.0
SDK version:0.9.5

*/
#define ESP8266 Serial3
#include "DHT.h"
#define DHTTYPE DHT11
#define DHTPIN 2  //pin 2 connect to DHT11
DHT dht(DHTPIN, DHTTYPE, 30);  //30 for Arduino Due

String SSID = "TestAP";
String PASSWORD = "12345678";

int LED = 13;

boolean FAIL_8266 = false;

#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];

void setup() {
  pinMode(LED, OUTPUT);
  
  digitalWrite(LED, LOW);
  delay(300);
  digitalWrite(LED, HIGH);
  delay(200);
  digitalWrite(LED, LOW);
  delay(300);
  digitalWrite(LED, HIGH);
  delay(200);
  digitalWrite(LED, LOW);

  do{
    //Serial.begin(9600);
    //ESP8266.begin(9600);
    Serial.begin(115200);
    ESP8266.begin(115200);
  
    //Wait Serial Monitor to start
    while(!Serial);
    Serial.println("--- Start ---");

    ESP8266.println("AT+RST");
    delay(1000);
    if(ESP8266.find("ready"))
    {
      Serial.println("Module is ready");
      
      ESP8266.println("AT+GMR");
      delay(1000);
      clearESP8266SerialBuffer();
      
      ESP8266.println("AT+CWMODE=1");
      //ESP8266.println("AT+CWMODE=3");
      delay(2000);
      
      //Quit existing AP, for demo
      Serial.println("Quit AP");
      ESP8266.println("AT+CWQAP");
      delay(1000);
      
      clearESP8266SerialBuffer();
      if(cwJoinAP())
      {
        Serial.println("CWJAP Success");
        FAIL_8266 = false;
        
        delay(3000);
        clearESP8266SerialBuffer();
        //Get and display my IP
        sendESP8266Cmdln("AT+CIFSR", 1000);  
        //Set multi connections
        sendESP8266Cmdln("AT+CIPMUX=1", 1000);
        //sendESP8266Cmdln("AT+CIPMUX=0", 1000);

        Serial.println("Setup finish");
      }else{
        Serial.println("CWJAP Fail");
        delay(500);
        FAIL_8266 = true;
      }
    }else{
      Serial.println("Module have no response.");
      delay(500);
      FAIL_8266 = true;
    }
  }while(FAIL_8266);
  
  digitalWrite(LED, HIGH);
  
  //set timeout duration ESP8266.readBytesUntil
  ESP8266.setTimeout(1000);
  
  dht.begin();
}

void loop(){
  
  float valHumidity;
  float valTemperature;
  do{
    valHumidity = dht.readHumidity();
    valTemperature = dht.readTemperature();
  }while(isnan(valHumidity) || isnan(valTemperature));
  
  Serial.println("Humidity=" + String(valHumidity));
  Serial.println("Temperature=" + String(valTemperature));
  
  /*
  AT+CIPSTART=id,"type","addr",port
  id = 0
  type = "TCP"
  addr = "www.example.com"
  port = 80
  */
  String TARGET_ID="0";
  String TARGET_TYPE="TCP";
  String TARGET_ADDR="184.106.153.149";  //ThingSpeak IP Address
  String TARGET_PORT="80";

  String cmd="AT+CIPSTART=" + TARGET_ID;
  cmd += ",\"" + TARGET_TYPE + "\",\"" + TARGET_ADDR + "\"";
  cmd += ","+ TARGET_PORT;

  Serial.println(cmd);
  ESP8266.println(cmd);
  delay(1000);
  //Assume OK
  //display and clear buffer
  clearESP8266SerialBuffer();
  
  /*
  POST /update?key=<API KEY>&field1=xx.xx&field2=xx.xx HTTP/1.1\r\n
  Host: api.thingspeak.com\r\n\r\n
  */
  
  String ThingSpeakMethod = "POST";  //GET should also work
  String ThingSpeakHost = "/update";
  String ThingSpeakApiKey = "42WKM35W3FR0OJUG";
  String ThingSpeakField1 = "field1";
  String ThingSpeakField2 = "field2";
  String ThingSpeakHttp = "HTTP/1.1";
  
  String ThingSpeak_2ndLine = "Host: api.thingspeak.com\r\n\r\n";
  
  String HTTP_RQS = ThingSpeakMethod;
  HTTP_RQS += " " + ThingSpeakHost;
  HTTP_RQS += "?key=" + ThingSpeakApiKey;
  HTTP_RQS += "&" + ThingSpeakField1 + "=" + valHumidity;
  HTTP_RQS += "&" + ThingSpeakField2 + "=" + valTemperature;
  HTTP_RQS += " " + ThingSpeakHttp + "\r\n";
  HTTP_RQS += ThingSpeak_2ndLine;
  
  String cmdSEND_length = "AT+CIPSEND=";
  cmdSEND_length += TARGET_ID + "," + HTTP_RQS.length() +"\r\n";
  
  ESP8266.print(cmdSEND_length);
  Serial.println(cmdSEND_length);
  
  Serial.println("waiting >");
  
  if(!ESP8266.available());
  
  if(ESP8266.find(">")){
    Serial.println("> received");
    ESP8266.println(HTTP_RQS);
    Serial.println(HTTP_RQS);
    
    boolean OK_FOUND = false;
    
    //program blocked untill "SEND OK" return
    while(!OK_FOUND){
      if(ESP8266.readBytesUntil('\n', buffer, BUFFER_SIZE)>0){
        Serial.println("...");
        Serial.println(buffer);
        
        if(strncmp(buffer, "SEND OK", 7)==0){
          OK_FOUND = true;
          Serial.println("SEND OK found");
        }else{
          Serial.println("Not SEND OK...");
        }
      }
    }

    if(OK_FOUND){
      delay(1000);
      //Dummy display received data
      while (ESP8266.available() > 0) {
        char a = ESP8266.read();
        Serial.write(a);
      }
    }
    
  }else{
    Serial.println("> NOT received, something wrong!");
  }
  
  //Close connection
  String cmdCIPCLOSE = "AT+CIPCLOSE=" + TARGET_ID; 
  ESP8266.println(cmdCIPCLOSE);
  Serial.println(cmdCIPCLOSE);
  
  delay(5000);
  
}

boolean waitOKfromESP8266(int timeout)
{
  do{
    Serial.println("wait OK...");
    delay(1000);
    if(ESP8266.find("OK"))
    {
      return true;
    }

  }while((timeout--)>0);
  return false;
}

boolean cwJoinAP()
{
  String cmd="AT+CWJAP=\"" + SSID + "\",\"" + PASSWORD + "\"";
  ESP8266.println(cmd);
  return waitOKfromESP8266(10);
}

//Send command to ESP8266, assume OK, no error check
//wait some time and display respond
void sendESP8266Cmdln(String cmd, int waitTime)
{
  ESP8266.println(cmd);
  delay(waitTime);
  clearESP8266SerialBuffer();
}

//Basically same as sendESP8266Cmdln()
//But call ESP8266.print() instead of call ESP8266.println()
void sendESP8266Data(String data, int waitTime)
{
  //ESP8266.print(data);
  ESP8266.print(data);
  delay(waitTime);
  clearESP8266SerialBuffer();
}

//Clear and display Serial Buffer for ESP8266
void clearESP8266SerialBuffer()
{
  Serial.println("= clearESP8266SerialBuffer() =");
  while (ESP8266.available() > 0) {
    char a = ESP8266.read();
    Serial.write(a);
  }
  Serial.println("==============================");
}


Monday, May 25, 2015

Arduino Due + ESP8266 + DHT11, to update dweet.io

This example combine the posts of "Arduino Due + ESP8266 as client, connect to website", "Temperature & Humidity monitor using Arduino NANO + DHT11 + 0.96 inch 128X64 I2C OLED" and "IoT experience: Arduino Uno + Ethernet Shield send data to dweet.io and freeboard.io": to read Humidity and Temperature from DHT11, and update my thing at dweet.io using ESP8266.



equivalent connection:



Due8266Client_Dweet.ino
/*
Arduino Due + ESP 8266 WiFi Module
- As STA to Join AP
- Connect to dweet.io as client, 
  to update my thing of Humidity and Temperature
  (read from DHT11)

Serial (Tx/Rx) communicate to PC via USB
Serial3 (Tx3/Rx3) connect to ESP8266
Tx3 - ESP8266 Rx
Rx3 - ESP8266 Tx
ESP8266 CH_PD Connect to ESP8266 VCC

DHT11 connect to pin 2 of Arduino Due

for firmware:
"v0.9.5.2 AT Firmware"
(http://goo.gl/oRdG3s)
AT version:0.21.0.0
SDK version:0.9.5

*/
#define ESP8266 Serial3
#include "DHT.h"
#define DHTTYPE DHT11
#define DHTPIN 2  //pin 2 connect to DHT11
DHT dht(DHTPIN, DHTTYPE, 30);  //30 for Arduino Due

String SSID = "TestAP";
String PASSWORD = "12345678";

int LED = 13;

boolean FAIL_8266 = false;

#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];

void setup() {
  pinMode(LED, OUTPUT);
  
  digitalWrite(LED, LOW);
  delay(300);
  digitalWrite(LED, HIGH);
  delay(200);
  digitalWrite(LED, LOW);
  delay(300);
  digitalWrite(LED, HIGH);
  delay(200);
  digitalWrite(LED, LOW);

  do{
    //Serial.begin(9600);
    //ESP8266.begin(9600);
    Serial.begin(115200);
    ESP8266.begin(115200);
  
    //Wait Serial Monitor to start
    while(!Serial);
    Serial.println("--- Start ---");

    ESP8266.println("AT+RST");
    delay(1000);
    if(ESP8266.find("ready"))
    {
      Serial.println("Module is ready");
      
      ESP8266.println("AT+GMR");
      delay(1000);
      clearESP8266SerialBuffer();
      
      ESP8266.println("AT+CWMODE=1");
      //ESP8266.println("AT+CWMODE=3");
      delay(2000);
      
      //Quit existing AP, for demo
      Serial.println("Quit AP");
      ESP8266.println("AT+CWQAP");
      delay(1000);
      
      clearESP8266SerialBuffer();
      if(cwJoinAP())
      {
        Serial.println("CWJAP Success");
        FAIL_8266 = false;
        
        delay(3000);
        clearESP8266SerialBuffer();
        //Get and display my IP
        sendESP8266Cmdln("AT+CIFSR", 1000);  
        //Set multi connections
        sendESP8266Cmdln("AT+CIPMUX=1", 1000);
        //sendESP8266Cmdln("AT+CIPMUX=0", 1000);

        Serial.println("Setup finish");
      }else{
        Serial.println("CWJAP Fail");
        delay(500);
        FAIL_8266 = true;
      }
    }else{
      Serial.println("Module have no response.");
      delay(500);
      FAIL_8266 = true;
    }
  }while(FAIL_8266);
  
  digitalWrite(LED, HIGH);
  
  //set timeout duration ESP8266.readBytesUntil
  ESP8266.setTimeout(1000);
  
  dht.begin();
}

void loop(){
  
  float valHumidity;
  float valTemperature;
  do{
    valHumidity = dht.readHumidity();
    valTemperature = dht.readTemperature();
  }while(isnan(valHumidity) || isnan(valTemperature));
  
  Serial.println("Humidity=" + String(valHumidity));
  Serial.println("Temperature=" + String(valTemperature));
  
  /*
  AT+CIPSTART=id,"type","addr",port
  id = 0
  type = "TCP"
  addr = "www.example.com"
  port = 80
  */
  String TARGET_ID="0";
  String TARGET_TYPE="TCP";
  String TARGET_ADDR="www.dweet.io";
  String TARGET_PORT="80";

  String cmd="AT+CIPSTART=" + TARGET_ID;
  cmd += ",\"" + TARGET_TYPE + "\",\"" + TARGET_ADDR + "\"";
  cmd += ","+ TARGET_PORT;

  Serial.println(cmd);
  ESP8266.println(cmd);
  delay(1000);
  //Assume OK
  //display and clear buffer
  clearESP8266SerialBuffer();
  
  /*
  GET /dweet/for/arduino-er?Humidity=xx.xx&Temperature=xx.xx HTTP/1.1\r\n
  Host: dweet.io:80\r\n\r\n
  */
  
  String DweetMethod = "GET";
  String DweetHost = "/dweet/for/";
  String DweetThingName = "arduino-er";
  String DweetKeyHumidity = "Humidity";
  String DweetKeyTemperature = "Temperature";
  String DweetVal1 = "world";
  String DweetHttp = "HTTP/1.1";
  
  String Dweet_2ndLine = "Host: dweet.io:80\r\n\r\n";
  
  String HTTP_RQS = DweetMethod;
  HTTP_RQS += " " + DweetHost + DweetThingName; 
  HTTP_RQS += "?" + DweetKeyHumidity + "=" + valHumidity;
  HTTP_RQS += "&" + DweetKeyTemperature + "=" + valTemperature;
  HTTP_RQS += " " + DweetHttp + "\r\n";
  HTTP_RQS += Dweet_2ndLine;
  
  String cmdSEND_length = "AT+CIPSEND=";
  cmdSEND_length += TARGET_ID + "," + HTTP_RQS.length() +"\r\n";
  
  ESP8266.print(cmdSEND_length);
  Serial.println(cmdSEND_length);
  
  Serial.println("waiting >");
  
  if(!ESP8266.available());
  
  if(ESP8266.find(">")){
    Serial.println("> received");
    ESP8266.println(HTTP_RQS);
    Serial.println(HTTP_RQS);
    
    boolean OK_FOUND = false;
    
    //program blocked untill "SEND OK" return
    while(!OK_FOUND){
      if(ESP8266.readBytesUntil('\n', buffer, BUFFER_SIZE)>0){
        Serial.println("...");
        Serial.println(buffer);
        
        if(strncmp(buffer, "SEND OK", 7)==0){
          OK_FOUND = true;
          Serial.println("SEND OK found");
        }else{
          Serial.println("Not SEND OK...");
        }
      }
    }

    if(OK_FOUND){
      delay(1000);
      //Dummy display received data
      while (ESP8266.available() > 0) {
        char a = ESP8266.read();
        Serial.write(a);
      }
    }
    
  }else{
    Serial.println("> NOT received, something wrong!");
  }
  
  //Close connection
  String cmdCIPCLOSE = "AT+CIPCLOSE=" + TARGET_ID; 
  ESP8266.println(cmdCIPCLOSE);
  Serial.println(cmdCIPCLOSE);
  
  delay(5000);
  
}

boolean waitOKfromESP8266(int timeout)
{
  do{
    Serial.println("wait OK...");
    delay(1000);
    if(ESP8266.find("OK"))
    {
      return true;
    }

  }while((timeout--)>0);
  return false;
}

boolean cwJoinAP()
{
  String cmd="AT+CWJAP=\"" + SSID + "\",\"" + PASSWORD + "\"";
  ESP8266.println(cmd);
  return waitOKfromESP8266(10);
}

//Send command to ESP8266, assume OK, no error check
//wait some time and display respond
void sendESP8266Cmdln(String cmd, int waitTime)
{
  ESP8266.println(cmd);
  delay(waitTime);
  clearESP8266SerialBuffer();
}

//Basically same as sendESP8266Cmdln()
//But call ESP8266.print() instead of call ESP8266.println()
void sendESP8266Data(String data, int waitTime)
{
  //ESP8266.print(data);
  ESP8266.print(data);
  delay(waitTime);
  clearESP8266SerialBuffer();
}

//Clear and display Serial Buffer for ESP8266
void clearESP8266SerialBuffer()
{
  Serial.println("= clearESP8266SerialBuffer() =");
  while (ESP8266.available() > 0) {
    char a = ESP8266.read();
    Serial.write(a);
  }
  Serial.println("==============================");
}


Related:
- Arduino Due + ESP8266 + DHT11, to update ThingSpeak

Friday, May 15, 2015

Temperature & Humidity monitor using Arduino NANO + DHT11 + 0.96 inch 128X64 I2C OLED

A simple Temperature & Humidity monitor using Arduino NANO + DHT11 + 0.96 inch 128X64 I2C OLED.

Reference:
- Hello World 0.96 inch 128X64 I2C OLED, on Arduino Uno, using u8glib library
Arduino Nano + DHT11, Temperature & Humidity sensors
- To convert the float returned by dht library to string (cahr array) for u8glib to display, function dtostrf() is used.
  • The dtostrf() function converts the double value passed in val into an ASCII representationthat will be stored under s. The caller is responsible for providing sufficient storage in s.
    Conversion is done in the format "[-]d.ddd". The minimum field width of the output string (including the '.' and the possible sign for negative values) is given in width, and prec determines the number of digits after the decimal sign. width is signed value, negative for left adjustment.
    The dtostrf() function returns the pointer to the converted string s.
- To display the degree sign (°C or °F) on the mini OLED using u8glib, use te string:
°C : "\260C"
°F : "\260F"



NANO_DHT11_I2C_OLED.ino
// Read DHT11 humidity/temperature sensors
// display on 0.96 inch 128X64 I2C OLED

#include "DHT.h"
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor for normal 16mhz Arduino
//DHT dht(DHTPIN, DHTTYPE);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
DHT dht(DHTPIN, DHTTYPE, 6);

char str[10];

void drawTest(void) {
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 20, "DHTxx test!");
}

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
  u8g.firstPage();  
  do {
    drawTest();
  } while( u8g.nextPage() );
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // 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
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index
  // Must send in temp in Fahrenheit!
  float hi = dht.computeHeatIndex(f, h);

  Serial.print("Humidity: "); 
  Serial.print(h);
  Serial.print(" %\t");
  
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  
  Serial.print("Heat index: ");
  Serial.print(hi);
  Serial.println(" *F");
  
  // picture loop
  u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_helvB08);
    
    u8g.drawStr( 0, 15, "Humidity:");
    u8g.drawStr( 80, 15, dtostrf(h, 5, 2, str));
    u8g.drawStr( 120, 15, "%");
    
    u8g.drawStr( 0, 30, "Temperature:");
    u8g.drawStr( 80, 30, dtostrf(t, 5, 2, str));
    u8g.drawStr( 120, 30, "\260C");
    
    u8g.drawStr( 80, 45, dtostrf(f, 5, 2, str));
    u8g.drawStr( 120, 45, "\260F");
    
    u8g.drawStr( 0, 60, "Heat index:");
    u8g.drawStr( 80, 60, dtostrf(hi, 5, 2, str));
    u8g.drawStr( 120, 60, "\260F");
    
  } while( u8g.nextPage() );
}


Related:
- Arduino Due + ESP8266 + DHT11, to update dweet.io


Monday, May 11, 2015

Arduino Nano + DHT11, Temperature & Humidity sensors

This example run on Arduino Nano, read DHT11 (Temperature & Humidity sensors), send data to PC via serial. The library adafruit/DHT-sensor-library is used to read DHT11.



The library adafruit/DHT-sensor-library is included in Arduino IDE library sources, so it's easy to add it to your project. Read the video to know how to add the library to Arduino IDE.


Once the library added, you can find a example in File -> Examples -> DHT sensor library -> DHTtester.


To make it work on Arduino Nano + DHT11, DHTtester.ino
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

#include "DHT.h"

#define DHTPIN 2     // what pin we're connected to

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11 
//#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor for normal 16mhz Arduino
//DHT dht(DHTPIN, DHTTYPE);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
DHT dht(DHTPIN, DHTTYPE, 6);

void setup() {
  Serial.begin(9600); 
  Serial.println("DHTxx test!");
 
  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // 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
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index
  // Must send in temp in Fahrenheit!
  float hi = dht.computeHeatIndex(f, h);

  Serial.print("Humidity: "); 
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: "); 
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hi);
  Serial.println(" *F");
}