🌡️ ESP32 Weather Monitoring Station over LAN

Using the DHT22 Temperature & Humidity Sensor with a Non-Blocking millis() Timer instead of delay()

1. Introduction

In the previous lesson we built a simple device control system over the Local Area Network (LAN), where the ESP32 acted as a small web server that we could access from any browser connected to the same Wi-Fi network.

In this lesson, we take the exact same LAN-based web server concept and re-purpose it for a new goal: weather monitoring. Instead of turning a relay or an LED on and off, the ESP32 will now read the surrounding temperature and humidity from a DHT22 sensor and display the live readings on a web page hosted directly on the board.

💡 Key Idea: The underlying LAN web-server architecture does not change at all. Only the "payload" changes — instead of sending an ON/OFF command, the ESP32 now sends live sensor data to the browser.

The biggest code change compared to the device-control project is that the old delay() based timing has been replaced with a non-blocking millis() timer. This means the ESP32 web server stays responsive while the DHT22 sensor is read periodically in the background, without freezing the whole program.

2. Understanding the DHT22 Sensor

The DHT22 (also sold under the name AM2302) is a low-cost digital sensor that measures both temperature and relative humidity. The DHT11/DHT22 is a sensor which measures relative humidity and temperature sensor, and it provides a calibrated digital output with a 1-wire protocol.

📏 Wider Range

Improved accuracy and range compared to DHT11, with a wider measurement range.

🔌 Single-Wire Bus

Single-wire communication allows simple interfacing with microcontrollers.

💧 Capacitive Sensing

It uses a capacitive humidity sensor and a thermistor for reliable data collection.

⏱️ Sampling Rate

The DHT22 has a sampling rate of once every 2 seconds — do not read it faster than that.

Physically, the sensor looks just like a small black plastic block with a grid front face — it is often confused with a simple connector, but it is a fully functional digital transducer. It is available either as a bare 4-pin component or mounted on a small breakout module (PCB) that already includes supporting circuitry.

3. Wiring Diagram: DHT22 → ESP32

The DHT22 has 4 pins when viewed from the front, numbered left to right: VCC, DATA, NC (not connected), GND.

DHT22 Sensor (front view, grid facing you)

DHT22 Sensor

  • Pin 1 → VCC
  • Pin 2 → DATA
  • Pin 3 → NC
  • Pin 4 → GND

ESP32 Board

  • 3.3V pin
  • GPIO 27
  • — (unused)
  • GND pin

Pull-up resistor: 10kΩ between DATA (Pin 2) and VCC (Pin 1)

DHT22 PinFunctionConnect To (ESP32)
Pin 1VCC (Power)3.3V
Pin 2DATA (Signal)GPIO 27
Pin 3Not Connected
Pin 4GND (Ground)GND
⚠️ Why the pull-up resistor matters: The Data out pin is connected with a GPIO pin of the microcontroller through a pull-up resistor, which is responsible for ensuring the data pin stays HIGH in order to establish a successful communication between the sensor and the microcontroller. Without it, the DATA line floats and the ESP32 cannot reliably distinguish between logic HIGH and LOW.

If you are using a bare 4-pin sensor, you must add this resistor yourself. However, if using a DHT22 module with only three exposed pins (VCC, Data, GND), the Data pin is usually already internally connected to a 10k ohm pull-up resistor, so no external resistor is required.

4. Required Libraries

To communicate with the DHT22 over its single-wire protocol, two Arduino libraries are needed:

LibraryPurpose
DHT sensor library (by Adafruit)Simplifies communication with the sensor and supports both the DHT11 and DHT22 sensors.
Adafruit Unified SensorServes as a required dependency for the DHT library.

Installing via Arduino IDE Library Manager

Both libraries can be installed the same way you installed libraries in the previous LAN control project:

Open Arduino IDE Sketch Include Library Manage Libraries... Search "DHT sensor library" Click Install Search "Adafruit Unified Sensor" Click Install

5. The Arduino Sketch

Below is the simplified sketch. Compared to the device-control example, notice two changes: the DHT22 setup lines, and the replacement of delay() with a millis()-based non-blocking timer so the web server keeps responding to browser requests.

#include <WiFi.h>
#include <DHT.h>

#define DHTPIN   27       // GPIO connected to DHT22 DATA pin
#define DHTTYPE  DHT22    // Sensor model

DHT dht(DHTPIN, DHTTYPE);

const char* ssid     = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

WiFiServer server(80);

float temperature = 0;
float humidity    = 0;

unsigned long previousMillis = 0;
const long interval = 2000;      // Read sensor every 2 seconds (non-blocking)

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

  WiFi.begin(ssid, password);
  Serial.print("Connecting to WiFi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
    Serial.print(".");
  }
  Serial.println();
  Serial.print("IP Address: ");
  Serial.println(WiFi.localIP());

  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();

  // Non-blocking sensor read every 2 seconds
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    humidity    = dht.readHumidity();
    temperature = dht.readTemperature();
  }

  WiFiClient client = server.available();
  if (client) {
    String request = client.readStringUntil('\r');
    client.flush();

    client.println("HTTP/1.1 200 OK");
    client.println("Content-type:text/html");
    client.println();
    client.println("<!DOCTYPE html><html><body>");
    client.println("<h1>ESP32 Weather Station</h1>");
    client.print("<p>Temperature: ");
    client.print(temperature);
    client.println(" &deg;C</p>");
    client.print("<p>Humidity: ");
    client.print(humidity);
    client.println(" %</p>");
    client.println("</body></html>");
    client.stop();
  }
}
💡 What changed from the device-control sketch? The delay() calls used to pause the loop are gone. Instead, millis() tracks elapsed time so the sensor is read on schedule while the web server remains free to answer incoming browser requests at any moment.

6. Uploading and Testing

Step-by-step upload procedure

Connect ESP32 board via USB Select correct Board in Tools menu Select correct COM Port in Tools menu Click Upload button Wait for "Connecting..." message Wait for compilation to finish Wait for upload to complete Open Serial Monitor Set baud rate to 115200

Once uploaded, the ESP32 will restart and attempt to join your Wi-Fi network. The Serial Monitor will show connection progress dots, followed by the assigned IP address — exactly like in the LAN device-control lesson.

Viewing the results

Copy IP address from Serial Monitor Open any web browser Paste IP address into address bar Press Enter View live temperature and humidity readings Refresh page to update readings

This works identically from a desktop browser or a smartphone browser, as long as the device is connected to the same LAN / Wi-Fi network as the ESP32.

7. Live Demo: Watching the Values React

A nice way to prove the sensor is actually working (rather than showing a static/fake value) is to gently change the temperature around it and watch the browser page update on refresh.

Example experiment sequence observed on the browser page:

ActionReading
Baseline27.7 °C
Heat source brought near sensor29.0 °C
Heat source held closer/longer31.6 °C
Heat source removed, cooling begins31.5 °C → 31.2 °C → 30.9 °C
⚠️ Safety Note: If experimenting with a heat source (soldering iron, hair dryer, hot-air gun) near the sensor, never let it directly touch the DHT22, and keep a safe distance to avoid damaging the sensor or causing burns.

Because the DHT22 only refreshes internally every 2 seconds, remember to wait a couple of seconds between browser refreshes to see a genuinely new reading rather than a cached one.

8. Troubleshooting Common Issues

SymptomLikely CauseFix
Web page shows NaN or blank values Missing pull-up resistor or wrong GPIO Double-check all connections, ensure the pull-up resistor is in place, and confirm the GPIO pin matches your wiring.
"Failed to read from DHT sensor" in Serial Monitor Reading too frequently, bad wiring, unstable power Wiring, power supply, or initialization issues — try increasing the time between sensor readings since the DHT22 only samples once every 2 seconds.
ESP32 randomly resets while reading Wi-Fi + sensor Insufficient USB power The ESP32 can brown-out during Wi-Fi transmission, so power the board with a reliable 5V/2A USB adapter rather than a weak laptop USB port.
Data pin appears to "float" without a resistor No pull-up on DATA line A 10 kΩ pull-up resistor is crucial for stable communication; some modules include this built-in, otherwise it must be added externally.

9. Credits & Further Reading

The original wiring concept and code base used in this lesson were adapted and simplified from tutorials published by Random Nerd Tutorials, a well-known resource for ESP32 and ESP8266 projects.

Their guide covers how to use the DHT11 and DHT22 temperature and humidity sensors with ESP32 using Arduino IDE, including wiring, circuit diagram, and Arduino sketch.

👉 Visit randomnerdtutorials.com for the full original tutorial and many more ESP32/ESP8266 project guides.