ESP32/ESP8266: DHT Temperature and Humidity Readings in OLED Display

Learn how to display temperature and humidity readings from a DHT11/DHT22 sensor in an SSD1306 OLED display using an ESP32 or an ESP8266 with Arduino IDE.

ESP32 ESP8266 Display DHT11 DHT22 Temperature and Humidity Readings in OLED Display

The idea of using the OLED display with the ESP32 or ESP8266 is to ilustrate how you can create a physical user interface for your boards.

Project Overview

In this project we’ll use an I2C SSD1306 128×64 OLED display as shown in the following figure.

I2C SSD1306 128x64 0.96 inch OLED display for ESP32 ESP8266

The temperature and humidity will be measured using the DHT22 temperature and humidity sensor (you can also use DHT11).

DHT11 DHT22 Temperature and Humidity Sensor for ESP32 ESP8266

If you’re not familiar with the DHT11/DHT22 sensor, we recommend reading the following guide:

Parts required

For this tutorial you need the following components:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Schematic

The OLED display we’re using communicates via I2C communication protocol, so you need to connect it to the ESP32 or ESP8266 I2C pins.

By default, the ESP32 I2C pins are:

  • GPIO 22: SCL
  • GPIO 21: SDA

If you’re using an ESP8266, the default I2C pins are:

  • GPIO 5 (D1): SCL
  • GPIO 4 (D2): SDA

Follow the next schematic diagram if you’re using an ESP32 board:

ESP32 OLED DHT11 DHT22 Sensor Circuit Diagram Schematics

Recommended reading: ESP32 Pinout Reference Guide

If you’re using an ESP8266 follow the next diagram instead.

ESP8266 OLED DHT11 DHT22 Sensor Circuit Diagram Schematics

In this case we’re connecting the DHT data pin to GPIO 14, but you can use any other suitable GPIO.

Recommended reading: ESP8266 Pinout Reference Guide

Installing Libraries

Before uploading the code, you need to install the libraries to write to the OLED display and the libraries to read from the DHT sensor.

Installing the OLED libraries

There are several libraries available to control the OLED display with the ESP8266. In this tutorial we’ll use the libraries from adafruit: the Adafruit_SSD1306 library and the Adafruit_GFX library. Follow the next steps to install these libraries:

1. Open your Arduino IDE and go to Sketch Include Library > Manage Libraries. The Library Manager should open.

2. Type “SSD1306” in the Search box and install the SSD1306 library from Adafruit.

Installing SSD1306 OLED Adafruit library in Arduino IDE

3. After installing the SSD1306 library from Adafruit, type “GFX” in the search box and install the library.

Installing GFX Adafruit library in Arduino IDE

Installing the DHT Sensor libraries

To read from the DHT sensor we’ll use the libraries from Adafruit.

1. Open your Arduino IDE and go to Sketch Include Library > Manage Libraries. The Library Manager should open.

2. Search for “DHT” on the Search box and install the DHT library from Adafruit.

Installing Adafruit DHT library in Arduino IDE

3. After installing the DHT library from Adafruit, type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.

Installing Adafruit Unified Sensor driver library in Arduino IDE

Installing the ESP boards

We’ll program the ESP32/ESP8266 using Arduino IDE, so you must have the ESP32/ESP8266 add-on installed in your Arduino IDE. If you haven’t, follow the next tutorial first that fits your needs:

Finally, restart your Arduino IDE.

Code

After installing the necessary libraries, you can copy the following code to your Arduino IDE and upload it to your ESP32 or ESP8266 board.

/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define DHTPIN 14     // Digital pin connected to the DHT sensor

// Uncomment the type of sensor in use:
//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);

  dht.begin();

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  delay(2000);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  delay(5000);

  //read temperature and humidity
  float t = dht.readTemperature();
  float h = dht.readHumidity();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
  }
  // clear display
  display.clearDisplay();
  
  // display temperature
  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");
  
  // display humidity
  display.setTextSize(1);
  display.setCursor(0, 35);
  display.print("Humidity: ");
  display.setTextSize(2);
  display.setCursor(0, 45);
  display.print(h);
  display.print(" %"); 
  
  display.display(); 
}

View raw code

How the code works

Let’s take a quick look on how the code works.

Importing libraries

The code starts by including the necessary libraries. The Wire, Adafruit_GFX and Adafruit_SSD1306 are used to interface with the OLED display. The Adafruit_Sensor and the DHT libraries are used to interface with the DHT22 or DHT11 sensors.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

Create a display object

Then, define your OLED display dimensions. In this case, we’re using a 128×64 pixel display.

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Then, initialize a display object with the width and height defined earlier with I2C communication protocol (&Wire).

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

The (-1) parameter means that your OLED display doesn’t have a RESET pin. If your OLED display does have a RESET pin, it should be connected to a GPIO. In that case, you should pass the GPIO number as a parameter.

Create a DHT object

Then, define the DHT sensor type you’re using. If you’re using a DHT22 you don’t need to change anything on the code. If you’re using another sensor, just uncomment the sensor you’re using and comment the others.

//#define DHTTYPE    DHT11     // DHT 11
#define DHTTYPE    DHT22     // DHT 22 (AM2302)
//#define DHTTYPE    DHT21     // DHT 21 (AM2301)

Initialize a DHT sensor object with the pin and type defined earlier.

DHT dht(DHTPIN, DHTTYPE);

setup()

In the setup(), initialize the serial monitor for debugging purposes.

Serial.begin(115200);

Initialize the DHT sensor:

dht.begin();

Then, initialize the OLED display.

if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
}

In this case, the address of the OLED display we’re using is 0x3C. If this address doesn’t work, you can run an I2C scanner sketch to find your OLED address. You can find the I2C scanner sketch here.

Add a delay to give time for the display to initialize, clear the display and set the text color to white:

delay(2000);
display.clearDisplay();
display.setTextColor(WHITE)

In the loop() is where we read the sensor and display the temperature and humidity on the display.

Get temperature and humidity readings from DHT

The temperature and humidity are saved on the t and h variables, respectively. Reading temperature and humidity is as simple as using the readTemperature() and readHumidity() methods on the dht object.

float t = dht.readTemperature();
float h = dht.readHumidity();

In case we are not able to get the readings, display an error message:

if (isnan(h) || isnan(t)) {
  Serial.println("Failed to read from DHT sensor!");
}

If you get that error message, read our troubleshooting guide: how to fix “Failed to read from DHT sensor”.

Display sensor readings on the OLED display

The following lines display the temperature on the OLED display.

  display.setTextSize(1);
  display.setCursor(0,0);
  display.print("Temperature: ");
  display.setTextSize(2);
  display.setCursor(0,10);
  display.print(t);
  display.print(" ");
  display.setTextSize(1);
  display.cp437(true);
  display.write(167);
  display.setTextSize(2);
  display.print("C");

We use the setTextSize() method to define the font size, the setCursor() sets where the text should start being displayed and the print() method is used to write something on the display.

To print the temperature and humidity you just need to pass their variables to the print() method as follows:

display.print(t);

The “Temperature” label is displayed in size 1, and the actual reading is displayed in size 2.

To display the º symbol, we use the Code Page 437 font. For that, you need to set the cp437 to true as follows:

display.cp437(true);

Then, use the write() method to display your chosen character. The º symbol corresponds to character 167.

display.write(167);

A similar approach is used to display the humidity:

display.setTextSize(1);
display.setCursor(0, 35);
display.print("Humidity: ");
display.setTextSize(2);
display.setCursor(0, 45);
display.print(h);
display.print(" %"); 

Don’t forget that you need to call display.display() at the end, so that you can actually display something on the OLED.

display.display(); 

Recommended reading: ESP32 with DHT11/DHT22 Temperature and Humidity Sensor using Arduino IDE

Demonstration

The following figure shows what you should get at the end of this tutorial. Humidity and temperature readings are displayed on the OLED.

DHT11 DHT22 sensor display temperature humidity readings in OLED display ESP8266 ESP32 using Arduino IDE

Troubleshooting

If your DHT sensor fails to get the readings or you get the message “Failed to read from DHT sensor”, read our DHT Troubleshooting Guide to help you solve that problem.

If you get the “SSD1306 allocation failed” error or if the OLED is not displaying anything in the screen, it can be one of the following issues:

Wrong I2C address

The I2C address for the OLED display we are using is 0x3C. However, yours may be different. So, make sure you check your display I2C address using an I2C scanner sketch.

SDA and SCL not connected properly

Please make sure that you have the SDA and SCL pins of the OLED display wired correctly. If you’re using:

  • ESP32: connect SDA pin to GPIO 21 and SCL pin to GPIO 22
  • ESP8266: connect SDA pin to GPIO 4 (D2) and SCL pin to GPIO 5 (D1)

Wrapping Up

We hope you’ve found this tutorial about displaying sensor readings on the OLED display useful. The OLED display is a great way to add a user interface to your projects. If you like this project, you may also like to know how to display sensor readings in your browser using an ESP Web Server:

You can learn more about the ESP32 and ESP8266 with our courses:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

41 thoughts on “ESP32/ESP8266: DHT Temperature and Humidity Readings in OLED Display”

  1. It might be useful to do a version of this using the BME280 sensor. Although more expensive than the DHT sensors, the BME is much more accurate and reliable.

    Reply
  2. I started with the BME280 and found that there was a problem with using on the ESP8266. It was a few years ago and the problem may have been resolved but I’m thinking it was a data transfer rate issue. I wish I could post pictures here. I have an arduino nano clone running the bme280 and a RTC module with an analog TFT displaying an analog clock with time, temp and date. Also, I have an ESP8266 with a DHT11 pulling its time from the web to display an analog clock on a tiny oled. Most of my projects I use is RandomNerd – some I pilfer from others. The analog clock I got from rinkydink (I think).
    Great stuff – thanks – keep it coming.

    Reply
  3. I have been on the seen before ESP 🙂 I want to get back on track. This ESP8266 is a WIFI thing. Could you do this project with one ESP8266 outside in the wind and snow and another indoor with a LCD screen to retrieve this info?

    Kind regards
    Leslie

    Reply
  4. Hello! For web server with esp32 that you have published on your website: you can access the web’s data only from the local network or from all internet??
    Thanks

    Reply
  5. thanks you for the project , i am starting with esp8266 and i really need help on a personal project.
    i want the servo motor to be controlled by an LDR and a esp8266.
    thanks for the help.

    Reply
  6. Rui and Sara!
    I have just started with Arduino and ESP8266 this Random Nerd Tutorials
    as education för beginners as me.
    Keep up going with more useful stuff. THANKS

    Reply
  7. Another great project-If I want to use a BME280 do I need to wire it to diferent gpios to the oled or is the address definition sufficient ?

    Reply
  8. I come across the function isnan in the code and I couldn’t find what it does.
    Can you explain it please?
    Thank you.

    Reply
  9. Guess I have a slow OLED display. I could see text, but it was all over the display. Sometimes it was readable, sometimes not. So I added a slight delay at the bottom above display.display();

    display.print(” %”);

    delay(1000); // <<<<< added this line to make display readable

    display.display();
    }

    Reply
  10. Hi Sara und Rui,
    this was a perfect project for me.
    I build a ESP8266 with DHT22 and a Telegram Bot.
    When i send a Codeword from Mobilephone via Telegram to my Bot he will send me the Temperature and Humidity.
    Then i found this OLED Display and your Website and then i have copy your code into my Telegram Bot Code and it works perfectly.
    I get all time the Data on Display and when i want to my Telegram Bot.
    Thank you for this.

    Daniel

    Reply
  11. Hi Sara & Rui,
    Thanks for the project.
    I plugged all the components, loaded the libraries into Arduino IDE, but when I’m trying to verify the copied and pasted sketch , i have an error message.
    ( i choose Generic ESP8266 for the board, and the correct USBport).

    Any ideas how to help me ?
    Thank you in advance

    Reply
  12. Hi,
    The error messages are :
    WARNING : Category ‘Network’ in library 1wIP_enc28j60 is not valid. Setting to ‘uncategorized’
    WARNING : Category ‘Network’ in library 1wIP_w5500 is not valid. Setting to ‘uncategorized’

    Regards

    Reply
  13. Hi,

    Actually the full error message is :

    WARNING: Category ‘Network’ in library lwIP_PPP is not valid. Setting to ‘Uncategorized’
    WARNING: Category ‘Network’ in library lwIP_enc28j60 is not valid. Setting to ‘Uncategorized’
    WARNING: Category ‘Network’ in library lwIP_w5500 is not valid. Setting to ‘Uncategorized’
    WARNING: Category ‘Network’ in library lwIP_w5500 is not valid. Setting to ‘Uncategorized’
    Build options changed, rebuilding all
    Multiple libraries were found for “DHT.h”
    In file included from C:\Users\p******\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_GrayOLED.cpp:20:
    Used: C:\Users\p******\Documents\Arduino\libraries\DHT_sensor_library
    C:\Users\p******\Documents\Arduino\libraries\Adafruit_GFX_Library\Adafruit_GrayOLED.h:30:10: fatal error: Adafruit_I2CDevice.h: No such file or directory
    Not used: C:\Users\p******\Documents\Arduino\libraries\Grove_Temperature_And_Humidity_Sensor
    30 | #include <Adafruit_I2CDevice.h>
    | ^~~~~~~~~~~~~~~~~~~~~~
    compilation terminated.

    Any help would be appreciated, as i am a beginner 🙂
    Thank you

    Reply
    • Hi Pascual it may not be my place to say this but this is what I think you should do.

      Start a new project in IDE , delete the lines at the top that come with a new file.
      Go to the project in RNT below the code is a button “raw code” click on that and the code opens in a new page. Copy and paste that into your new project.
      You cannot copy code off a web page as you can get all sorts of weird errors.

      Hope that helps Iain.

      Reply
  14. Code…this fixes degree & percent symbols…
    Also configures for multi displays…

    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>

    #define SCREEN_WIDTH 128 // OLED display width, in pixels
    #define SCREEN_HEIGHT 64 // OLED display height, in pixels

    // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
    Adafruit_SSD1306 Display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
    Adafruit_SSD1306 Display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

    void setup() {
    if(!Display1.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F(“SSD1306 allocation failed”));
    for(;;);
    }
    delay(10);
    Display1.cp437(true);
    Display1.clearDisplay();
    Display1.setTextColor(WHITE,BLACK);

    if(!Display2.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);

    }
    delay(10);
    Display1.cp437(true);
    Display2.clearDisplay();
    Display2.setTextColor(WHITE,BLACK);
    }

    void loop() {
    // Correction: 248 is code for Degree Symbol…not 167
    Display1.write(248);
    // Correction: 37 is code for Percent Symbol…
    Display1.write(37);
    }

    Reply
  15. Is there a way to update changes in the temperature & humidity without issuing the
    display.clearDisplay(); command?
    How could I clear just a row, or any previous values at a location specified by the
    display.setCursor(column, row); command?

    Thanks for any assistance

    Reply
  16. Hi Sara and Rui, thanks for the nice project. But why everything works and shows how it is powered by a cable with a plug connected to the programming. Note!!, and the display does not show anything when the voltage of 3.3 V or 5 V is connected to the ESP 32 board.
    Tiles and display as in your photos. Thanks for the good advice on this problem.

    Reply

Leave a Reply to David Cancel reply

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.