In this blog, we’ll learn how to read temperature and humidity from a DHT11 sensor using an ESP32, and display the values on a 128×32 OLED display using I2C.
This is a great beginner-friendly IoT project using Arduino IDE and minimal components!
🧰 Components Required
Component | Quantity |
---|---|
ESP32 Dev Board | 1 |
DHT11 Sensor | 1 |
0.91″ OLED Display (128×32, I2C) | 1 |
Jumper Wires | As needed |
Breadboard (optional) | 1 |
🔌 Circuit Diagram
DHT11 Wiring:
- VCC → 3.3V (or 5V on ESP32)
- GND → GND
- DATA → GPIO 4
OLED (I2C) Wiring:
- VCC → 3.3V
- GND → GND
- SDA → GPIO 21
- SCL → GPIO 22
⚠️ Note: GPIO 21 and 22 are default I2C pins on ESP32. Adjust if needed.
💽 Arduino Libraries Needed
Open Arduino IDE → Tools → Manage Libraries and install:
✅ Adafruit SSD1306
✅ Adafruit GFX Library
✅ DHT sensor library
by Adafruit
🧾 Full Arduino Code
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// === OLED Config ===
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// === DHT11 Config ===
#define DHTPIN 4 // GPIO pin for DHT11 data
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
// Initialize DHT
dht.begin();
// Initialize OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 init failed!");
while (1);
}
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Starting...");
display.display();
delay(1000);
}
void loop() {
float temp = dht.readTemperature();
float humi = dht.readHumidity();
if (isnan(temp) || isnan(humi)) {
Serial.println("Failed to read from DHT sensor!");
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(1);
display.println("Sensor Error!");
display.display();
delay(2000);
return;
}
// Display data
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0, 0);
display.print("Temp: ");
display.print((int)temp);
display.print((char)247); // Degree symbol
display.println("C");
display.setCursor(0, 18);
display.print("Humi: ");
display.print((int)humi);
display.println("%");
display.display();
delay(2000); // Update every 2 seconds
}
🖼️ OLED Output Preview
Temp: 29°C
Humi: 64%
🧪 Troubleshooting Tips
- If the display shows nothing, check I2C address (
0x3C
for most OLEDs). - If the sensor reads “nan”, check DHT11 wiring and pin number.
- Use a breadboard for clean, secure connections.
- Make sure your display is 128×32, not 128×64. Adjust height if needed.
💡 Ideas to Expand
- Add a button to toggle °C and °F
- Log data to SD card or Firebase
- Send data over Wi-Fi to a web dashboard
- Add real-time clock to log timestamps
Here’s a detailed explanation of the code section by section for displaying DHT11 temperature and humidity on a 128×32 OLED with an ESP32:
✅ 1. Library Inclusions
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
These libraries are essential:
Adafruit_GFX.h
– Core graphics functions (text, lines, shapes).Adafruit_SSD1306.h
– OLED driver for SSD1306 displays.DHT.h
– Handles communication with DHT11 sensors.
✅ 2. OLED Display Configuration
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
- OLED has a resolution of 128×32 pixels.
OLED_RESET -1
means we’re not using a dedicated reset pin.- The display uses the
Wire
object (I2C).
✅ 3. DHT11 Sensor Configuration
#define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
- We’re connecting the data pin of the DHT11 to GPIO 4.
DHT11
tells the library which sensor type we are using (you can also useDHT22
if you upgrade the sensor).
✅ 4. Setup Function
void setup() {
Serial.begin(115200);
dht.begin();
- Starts serial communication (for debugging).
- Initializes the DHT sensor.
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println("SSD1306 allocation failed");
while (1);
}
- Initializes the OLED at I2C address
0x3C
. If the display isn’t found, the loop stops.
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Starting...");
display.display();
delay(1000);
- Clears the display.
- Prints “Starting…” message as a confirmation that setup is working.
✅ 5. Loop Function – Reading & Displaying Data
a. Read Sensor Data
float temp = dht.readTemperature(); // in Celsius
float humi = dht.readHumidity(); // in Percent
- Reads the temperature and humidity from DHT11.
- Returns
NAN
(not a number) if there’s a problem.
b. Handle Read Failure
if (isnan(temp) || isnan(humi)) {
Serial.println("Failed to read from DHT sensor!");
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Sensor Error!");
display.display();
delay(2000);
return;
}
- Checks if readings are valid.
- Displays “Sensor Error!” if something goes wrong.
c. Serial Output for Debugging
Serial.print("Temp: ");
Serial.print(temp);
Serial.print(" °C | Humi: ");
Serial.print(humi);
Serial.println(" %");
- Shows readings in the Serial Monitor for testing.
d. Display on OLED
display.clearDisplay(); // Erase old display
display.setTextSize(2); // Set large font
display.setCursor(0, 0);
display.print("Temp: ");
display.print((int)temp); // Integer only
display.print((char)247); // Degree symbol
display.println("C");
- Displays temperature like:
Temp: 28°C
.
display.setCursor(0, 18);
display.print("Humi: ");
display.print((int)humi); // Integer only
display.println("%");
- Displays humidity like:
Humi: 60%
.
display.display(); // Push to screen
delay(2000); // Update every 2 seconds