ESP32 UNO - DHT11 Temperature Humidity Sensor - OLED
How warm and how humid is your room right now? Put an ESP32 Uno DHT11 OLED combo on your desk and read the answer in large white digits. The DHT11 temperature humidity module samples the air, and the ESP32 Uno form board draws both numbers in the middle of a small SSD1306 I2C screen, with a copy sent to the Serial Monitor.
By the end, you can:
- Hook up the DHT11 sensor plus an SSD1306 screen on the ESP32 Uno headers
- Add the Adafruit SSD1306, GFX and DHT libraries in Arduino IDE
- Get °C and % values with readTemperature() and readHumidity()
- Center two lines of text on an OLED screen with getTextBounds()

Components You Need
Or you can buy the following kits:
| 1 | × | DIYables Sensor Kit (18 sensors/displays) |
Additionally, some of these links are for products from our own brand, DIYables .
Buy Note: If you want a bigger OLED display, use the 2.42 inch OLED Display 128x64 .
Sensor and Screen at a Glance
After this part, you know what each module brings to the build.
| Part | Role | Interface | Supply |
|---|---|---|---|
| DHT11 module | Senses air temperature and humidity | Single data wire | 3.3V to 5V |
| SSD1306 OLED | Draws the two values in pixels | I2C, address 0x3C | 3.3V to 5V |
The DHT11 reads 0 to 50°C with about ±2°C error, and 20 to 90% RH with about ±5% error. The Adafruit DHT library converts its raw bits into float values. The OLED has no backlight, since every pixel makes its own light, so the text stays sharp even in a dark room.
Want the pinout and a basic sketch for each part first? Open these guides:
ESP32 Uno Pinout
A sketch on this board needs GPIO numbers, not the D labels printed next to the headers. Look up D2, SDA and SCL in the picture below so your code and your jumpers agree.

How to Connect
At the end of this step, the DHT11 talks on D2 and the OLED sits on the I2C header.

This image is created using Fritzing. Click to enlarge image
| Component Pin | ESP32 Uno Pin |
|---|---|
| DHT11 VCC (+) | 3.3V |
| DHT11 GND (-) | GND |
| DHT11 DATA (OUT) | D2 (GPIO26) |
| OLED VCC | 3.3V |
| OLED GND | GND |
| OLED SDA | SDA (GPIO21) |
| OLED SCL | SCL (GPIO22) |
Good to know: the A4 and A5 holes on the ESP32 Uno are input-only analog pins with no I2C function. Plug the OLED into the separate SDA and SCL header pins.
Good to know: the DHT11 module carries its own pull-up resistor. A bare 4-pin DHT11 needs a 10 kΩ resistor from DATA to 3.3V.
WARNING
ESP32 Uno pins run at 3.3V and are NOT 5V tolerant. Feed both modules from the 3.3V pin. If the DHT11 gets 5V, its pull-up raises DATA to 5V, and that can damage GPIO26 over time.
ESP32 Uno Code
The sketch reads the DHT11 over and over, prints the values to the Serial Monitor, and redraws them in large centered text on the OLED.
Upload and Test
- First time with this board? Set it up with ESP32 Uno - Getting Started before you continue.
- Build the circuit by following the wiring table above.
- Plug in the USB Type-C cable between the ESP32 Uno and your computer.
- Select the board in Arduino IDE: pick ESP32 Dev Module and the COM port of the board (CH340).
- Open the Library Manager from the Libraries icon in the left bar.
- Add the screen driver: type "SSD1306", choose the SSD1306 library from Adafruit, and press Install.
- Search for Adafruit SSD1306 created by Adafruit and click the Install button.
- Accept its helpers: a box lists extra libraries such as Adafruit GFX. Press Install All.
- Search for Adafruit GFX Library created by Adafruit and click the Install button.
- Add the sensor driver: type "DHT", choose the DHT sensor library from Adafruit, and press Install.
- Search for DHT sensor library created by Adafruit and click the Install button.
- Accept its helpers too: press Install All to add Adafruit Unified Sensor.
- Search for Adafruit Unified Sensor created by Adafruit
and click the Install button.
- Paste the sketch into a new Arduino IDE window.
- Press Upload (Upload button) and wait for "Done uploading".
- Make the values move: pinch the sensor between two fingers, or set it next to a glass of iced water.
- Watch both outputs: the OLED shows the big numbers, and the Serial Monitor (9600 baud) shows lines like these.
- Pro tip: the text is redrawn on every loop, so the screen can flicker a little. Add delay(2000); at the end of loop() to match the DHT11 refresh rate and get a calm display.
※ NOTE THAT:
You never set the text position by hand. The sketch measures each string and puts it in the middle of the screen, both across and down.
Video Tutorial
See the ESP32 Uno build in action in the video below.
Code Explanation
After this part, you can adjust the font, the pin or the screen size without guessing.
| Code Part | What It Does |
|---|---|
| #define DHT11_PIN 26 | Uses D2 (GPIO26) as the DHT11 data pin |
| oled.begin(SSD1306_SWITCHCAPVCC, 0x3C) | Starts the OLED at I2C address 0x3C, or stops with an error message |
| String(tempC, 1) + char(247) | Builds text like 24.6°C with one decimal and a degree sign |
| isnan(humi) or isnan(tempC) | Swaps the numbers for the word "Failed" when the sensor gives no data |
| getTextBounds(...) | Measures the text width and height in pixels |
| setCursor((SCREEN_WIDTH - width) / 2, ...) | Puts the temperature above the middle line and the humidity below it |
The result is two large lines, temperature on top and humidity below, always in the center of the 128x64 screen.
ESP32 Uno vs UNO R4 for This Project
Here is what changes when you move this weather screen from the UNO R4 to the ESP32 Uno.
| Item | Arduino UNO R4 | ESP32 Uno |
|---|---|---|
| Logic voltage | 5V | 3.3V |
| DHT11 data pin in code | 2 (D2) | 26 (D2 header) |
| OLED I2C pins | SDA and SCL (A4 and A5 also work) | SDA GPIO21 and SCL GPIO22 only |
| Module supply | 5V or 3.3V | 3.3V recommended |
| Libraries | Adafruit SSD1306, GFX and DHT | Same libraries, no change |
| Wireless | WiFi on the R4 WiFi only | WiFi plus Bluetooth Classic and BLE |
| Arduino IDE board | Arduino UNO R4 WiFi or Minima | ESP32 Dev Module |
The wiring positions stay the same. Only the pin number in code changes, and the modules should run from 3.3V instead of 5V.
Go Wireless: Room Climate on Your Phone
After this part, you have an idea for checking the readings from another room.
The ESP32 Uno has WiFi and Bluetooth on board. Keep the OLED as a local display, and send the same two values to a phone or a browser. A live chart also shows how fast the humidity climbs when you boil water or open a window.
Try These Next
- Switch the top line to Fahrenheit with dht11.readTemperature(true) and print "F".
- Make the 128x32 OLED work: set SCREEN_HEIGHT to 32 and use setTextSize(2).
- Invert the screen with oled.invertDisplay(true) when the humidity goes above 70%.
Troubleshooting
| Problem | Possible Cause | Solution |
|---|---|---|
| Arduino IDE lists no COM port | CH340 driver not installed or a charge-only cable | Install the CH340 driver and switch to a USB cable that carries data |
| Upload ends with "Failed to connect" or "Waiting for download" | Board is not in download mode | Hold the BOOT button while the upload starts, then release it |
| Screen stays black | OLED wired to A4 and A5, or no power on VCC | Move SDA to GPIO21 and SCL to GPIO22 and check the 3.3V and GND wires |
| Serial Monitor prints SSD1306 allocation failed | No OLED answers at 0x3C | Run an I2C scanner, then put the found address (often 0x3D) in oled.begin() |
| Both lines say Failed | DHT11 sends no valid data | Check DATA on D2 (GPIO26), the 3.3V and GND wires, and the pull-up on a bare sensor |
| Serial Monitor shows nan°C | Wrong pin number in DHT11_PIN | Set DHT11_PIN to 26, not 2 |
| Humidity line sits a bit left of center | The second getTextBounds() call measures the temperature string again | Pass humidity instead of temperature in that second call |
| Garbled characters in Serial Monitor | Baud rate mismatch | Choose 9600 baud in the Serial Monitor |
FAQ
Is the DHT11 good enough for a home weather screen?
For a quick room check, yes. It is off by about ±2°C and ±5% RH, and it updates about once per second. For finer values, use a DHT22 with the same wiring.
Should I power the DHT11 and the OLED from 3.3V or 5V on the ESP32 Uno?
Use 3.3V for both. They work fine at 3.3V, and the signal lines then stay at a level the ESP32 Uno pins can take.
Why are the OLED wires not on A4 and A5?
On the ESP32 Uno, A4 (GPIO36) and A5 (GPIO39) are input-only analog pins. The I2C bus sits on the SDA (GPIO21) and SCL (GPIO22) header pins, which Wire.begin() uses by default.
Why does the sketch say 26 when the wire goes to D2?
Each Uno header label maps to a GPIO number on this board. Header D2 is GPIO26, and the code always needs the GPIO number.
Which other header pins can read the DHT11?
Most digital pins work, for example D3 (GPIO25), D6 (GPIO27) or D7 (GPIO14). Avoid D8 (GPIO12), D10 (GPIO5) and A0 (GPIO2), because they are boot strapping pins, and avoid D0/D1, which carry the USB serial data.
Can I use the 128x32 OLED from the parts list?
Yes. Set SCREEN_HEIGHT to 32 and lower the text size to 2, so both lines fit in the shorter screen.
How do I swap the DHT11 for a DHT22?
Change the type in DHT dht11(DHT11_PIN, DHT11); to DHT22. The wiring, the pin and the libraries stay the same.
Do I need a different driver for the ESP32 Uno than for the UNO R4?
Yes. The ESP32 Uno uses a CH340 USB-to-serial chip, so your computer may need the CH340 driver before the COM port appears.
Will my UNO shields fit on the ESP32 Uno for this project?
The header shape is the same, so shields fit. Check that the shield works with 3.3V logic and does not need A4/A5 for I2C.
Can I see the temperature in a web browser too?
Yes. The ESP32 Uno has WiFi, so you can send the same readings to a web page while the OLED keeps showing them. See the Go Wireless links above.
What if my project needs more pins than the Uno headers give?
The ESP32 Uno has extra holes near the power header. GPIO32 and GPIO33 give I/O, PWM and analog on ADC1, so they read analog values even with WiFi on. GPIO15 gives I/O, PWM and analog on ADC2. Solder pin headers there and write the GPIO number in code. For a second DHT11 or an extra button, GPIO32 or GPIO33 is a good pick. Two warnings: GPIO15 and GPIO0 (the IO0 pin at the unused Uno NC spot) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code, so use GPIO32/33 first. Never use the six holes under the digital header (SD0 to SD3, CMD, CLK = GPIO6 to GPIO11), because they connect to the flash chip and using them crashes the board.