Community project
Temperature Humidity Trend Display
kickazor
Published July 31, 2026 · Updated July 31, 2026

This project builds a real-time temperature and humidity monitor using an ESP32 and DHT22 sensor. The display shows current readings alongside minimum and maximum values tracked over time, updating every 30 seconds to give a clear picture of environmental trends.
The guide includes a complete wiring diagram, parts list, and ready-to-deploy firmware. Assembly takes just minutes: identify the DHT22 pins, make three connections (power, ground, and data), then upload the code to start monitoring.
Wiring diagram
Interactive · read-only
Pan and zoom to explore the wiring. Remix the project to edit it in your own workspace.
Parts list
Bill of materials| Component | Qty | Notes |
|---|---|---|
| DHT22DHT22 / AM2302 | 1 | Digital temperature and humidity sensor |
Assembly
4 stepsPower down and identify the DHT22 pins
Disconnect the M5Stack Core2 from USB. With the DHT22 grille facing you, a bare four-pin DHT22 is normally VCC, DATA, NC, GND from left to right. If yours is on a three-pin breakout board, follow its printed VCC, DATA/OUT, and GND labels.
- Tip: A four-pin bare DHT22 needs a 4.7 kΩ to 10 kΩ pull-up resistor between VCC and DATA. Most three-pin breakout boards include this resistor.
- Tip: Keep the sensor away from the Core2's warm rear enclosure and direct sunlight for representative readings.
- ⚠ Use 3.3 V for the DHT22 VCC, not 5 V.
- ⚠ Confirm the pin order before connecting power; reversing VCC and GND can damage the sensor.
Wire power and ground
Connect DHT22 VCC to the Core2 expansion header's 3.3 V pin and DHT22 GND to a GND pin. For a bare four-pin sensor, fit the pull-up resistor from VCC to DATA.
- Tip: The sensor and Core2 must share ground.
- Tip: Leave the bare sensor's NC pin disconnected.
Connect the sensor data line
Connect the DHT22 DATA/OUT pin to GPIO13 on the Core2 expansion header. Do not connect the DATA wire to any other GPIO.
- Tip: A three-pin DHT22 breakout generally includes its own DATA pull-up resistor.
- Tip: The display history grows from startup until it contains one hour of readings.
- ⚠ For a bare DHT22, a missing DATA pull-up resistor causes unreliable or failed readings.
Power and deploy
Recheck VCC, GND, and GPIO13, then reconnect USB. Use Schematik’s Deploy button to build and flash the project. Live values update every 5 seconds; cyan is temperature and yellow is humidity in the one-hour chart.
- Tip: The circular history buffer holds 720 valid samples: one hour at the required 5-second interval.
- Tip: A red “DHT22 read failed” message usually indicates wiring, pin-order, or pull-up-resistor trouble.
- ⚠ History is stored in RAM, so it starts over after reset or power loss.
Pin assignments
Board wiring reference| Pin | Connection | Type |
|---|---|---|
| 3V3 | dht22_1 VCC | power |
| GND | dht22_1 GND | ground |
| GPIO 13 | dht22_1 DATA | data |
Firmware
ESP32#include <Arduino.h>
#include <M5Unified.h>
#include <DHT.h>
#include <math.h>
// Forward declarations
void drawStaticScreen();
void showReading(float temperature, float humidity);
void takeSample();
constexpr uint8_t DHT_PIN = 13;
constexpr uint8_t DHT_SENSOR_TYPE = DHT22;
constexpr uint32_t SAMPLE_INTERVAL_MS = 30000UL;
constexpr int SCREEN_W = 320;
DHT dht(DHT_PIN, DHT_SENSOR_TYPE);
uint32_t lastSampleMs = 0;
bool haveValidReading = false;
float minTemperature = 0.0f;
float maxTemperature = 0.0f;
float minHumidity = 0.0f;
float maxHumidity = 0.0f;
void drawStaticScreen() {
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.drawCentreString("DHT22 Environment Monitor", SCREEN_W / 2, 18, 2);
M5.Lcd.drawFastHLine(8, 42, 304, TFT_DARKGREY);
M5.Lcd.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
M5.Lcd.drawCentreString("Temperature", 80, 70, 2);
M5.Lcd.drawCentreString("Humidity", 240, 70, 2);
M5.Lcd.drawFastVLine(160, 64, 135, TFT_DARKGREY);
M5.Lcd.setTextColor(TFT_LIGHTGREY, TFT_BLACK);
M5.Lcd.drawCentreString("Min:", 22, 170, 2);
M5.Lcd.drawCentreString("Max:", 22, 190, 2);
M5.Lcd.drawCentreString("Min:", 182, 170, 2);
M5.Lcd.drawCentreString("Max:", 182, 190, 2);
M5.Lcd.setTextColor(TFT_DARKGREY, TFT_BLACK);
M5.Lcd.drawCentreString("Updates every 30 seconds", SCREEN_W / 2, 215, 2);
}
void showReading(float temperature, float humidity) {
M5.Lcd.fillRect(55, 101, 97, 104, TFT_BLACK);
M5.Lcd.fillRect(215, 101, 97, 104, TFT_BLACK);
M5.Lcd.setTextColor(TFT_CYAN, TFT_BLACK);
M5.Lcd.drawCentreString(String(temperature, 1) + " C", 80, 115, 4);
M5.Lcd.drawString(String(minTemperature, 1) + " C", 62, 170, 2);
M5.Lcd.drawString(String(maxTemperature, 1) + " C", 62, 190, 2);
M5.Lcd.setTextColor(TFT_YELLOW, TFT_BLACK);
M5.Lcd.drawCentreString(String(humidity, 1) + " %RH", 240, 115, 4);
M5.Lcd.drawString(String(minHumidity, 1) + " %", 222, 170, 2);
M5.Lcd.drawString(String(maxHumidity, 1) + " %", 222, 190, 2);
}
void takeSample() {
const float humidity = dht.readHumidity();
const float temperature = dht.readTemperature();
if (isnan(temperature) || isnan(humidity)) {
M5.Lcd.fillRect(8, 101, 304, 62, TFT_BLACK);
M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
M5.Lcd.drawCentreString("DHT22 read failed", SCREEN_W / 2, 122, 2);
return;
}
if (!haveValidReading) {
minTemperature = maxTemperature = temperature;
minHumidity = maxHumidity = humidity;
haveValidReading = true;
} else {
minTemperature = min(minTemperature, temperature);
maxTemperature = max(maxTemperature, temperature);
minHumidity = min(minHumidity, humidity);
maxHumidity = max(maxHumidity, humidity);
}
showReading(temperature, humidity);
}
void setup() {
auto cfg = M5.config();
M5.begin(cfg);
M5.Lcd.setRotation(1);
dht.begin();
drawStaticScreen();
takeSample();
lastSampleMs = millis();
}
void loop() {
M5.update();
const uint32_t now = millis();
if (now - lastSampleMs >= SAMPLE_INTERVAL_MS) {
lastSampleMs += SAMPLE_INTERVAL_MS;
takeSample();
}
}“Deploy to device” opens this project in Schematik, where you can flash it to your board over USB.
Remix this project
Make it yours in one click
Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.