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


8 comments:

  1. Works a treat - rare to find a sketch which compiles without errors and runs straight away !
    Thank you
    - Terry Reynolds

    ReplyDelete
  2. I try to use, but mine is DHT 22 in a conection plac, and i got this error:

    Arduino:1.6.3 (Windows 8.1), Placa:"Arduino Nano, ATmega328"

    dht22oled.ino: In function 'void loop()':

    dht22oled.ino:71:18: error: 'class DHT' has no member named 'computeHeatIndex'

    Error de compilación

    This report would have more information with
    "Show verbose output during compilation"
    activala desde Archivo > Preferencias

    ReplyDelete
  3. Ok i got an old library to the DHT

    ReplyDelete
  4. Sorry, but to me the character "%" does not look good, there is a conversion as "°" in "\ 260".
    Thanks a lot

    ReplyDelete
  5. This code does not work anymore with latest Adafruit DHT Unified drivers. The float funtion is not valid and I struggle to get the values displayed on my OLED screen now.

    ReplyDelete
    Replies
    1. ??? but I use is adafruit/DHT-sensor-library, not DHT Unified drivers! (refer http://arduino-er.blogspot.com/2015/05/arduino-nano-dht11-temperature-humidity.html)

      May be I have to re-test it later.

      Delete
  6. Really works... thanks a lot. With a base I can "hack" this code to implement more things..... this is awasome

    ReplyDelete
  7. Why do i get differant readings from the dht11 when i use 3.3v and 5v?

    ReplyDelete