Built-in project · ESP32 DevKit V1

ESP32 DHT22 weather web server

ESP32 DHT22 weather web server: the board serves its own page with the temperature in C and F and the humidity, plus the same reading as JSON. The whole build, an ESP32 DevKit and 1 more part, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.

Teaching? Assign it to your class in one click.

Intermediate Runs in your browser. Free, and no account needed.

The parts retail for about $13. On Mokxi they're free.

ESP32 DHT22 weather web server · ESP32 DevKit V1live0.000 s 0.00x
Click to open it in the editor
The circuit itself, running here on the simulator. Press what can be pressed; click anything else to open it in the editor.

The code

The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.

sketch.ino · ESP32 DevKit V1
/*
 * ESP32 weather web server: a DHT22 on GPIO 4, and a web page that shows the
 * temperature and humidity, served by the ESP32 itself.
 *
 *   DHT22   VCC -> 3V3, DATA -> GPIO 4 (D4), GND -> GND
 *           (the module has its own pull-up on DATA; a bare sensor needs
 *           a 10 k resistor from DATA to 3V3)
 *
 * Press Run, wait for "open http://..." on the Serial Monitor, then open the
 * Web tab. The page reloads itself every 10 seconds. /data answers the same
 * reading as JSON, for another program to read.
 *
 * # Reading the sensor without stalling the server
 *
 * A DHT22 can only be read once every two seconds, and a read takes a few
 * milliseconds. So loop() reads it on a timer, keeps the last good reading,
 * and serves that. A request never waits for the sensor, and a failed read
 * (NaN) keeps the last good value instead of showing "nan" on the page.
 *
 * The network is SIMULATED: there is no 802.11, no TCP and no real internet,
 * and the only thing that can reach this server is the Web tab in this page.
 * On a real ESP32 the same sketch serves any phone or laptop on your WiFi.
 */
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>

const char *SSID = "Mokxi-Lab";
const char *PASSWORD = "breadboard";

const int DHT_PIN = 4;
DHT dht(DHT_PIN, DHT22);
WebServer server(80);

float temperatureC = NAN;
float humidity = NAN;
unsigned long readAt = 0;
unsigned long readings = 0;

void readSensor()
{
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    if (isnan(t) || isnan(h)) {
        Serial.println("DHT22 read failed: check the DATA wire");
        return;
    }
    temperatureC = t;
    humidity = h;
    readings++;
    Serial.print("temperature ");
    Serial.print(temperatureC, 1);
    Serial.print(" C, humidity ");
    Serial.print(humidity, 1);
    Serial.println(" %");
}

void handleRoot()
{
    String page("<!doctype html><html><head><meta charset=\"utf-8\">");
    page += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    page += "<meta http-equiv=\"refresh\" content=\"10\">";
    page += "<title>ESP32 weather station</title></head><body>";
    page += "<h1>ESP32 weather station</h1>";
    if (isnan(temperatureC)) {
        page += "<p>Waiting for the first reading...</p>";
    } else {
        page += "<p>Temperature: <b>";
        page += String(temperatureC, 1);
        page += " &deg;C</b> (";
        page += String(temperatureC * 9.0 / 5.0 + 32.0, 1);
        page += " &deg;F)</p>";
        page += "<p>Humidity: <b>";
        page += String(humidity, 1);
        page += " %</b></p>";
    }
    page += "<p><a href=\"/\">Refresh</a> &middot; <a href=\"/data\">JSON</a></p>";
    page += "</body></html>";
    server.send(200, "text/html", page);
}

void handleData()
{
    String json("{\"temperature\":");
    json += isnan(temperatureC) ? String("null") : String(temperatureC, 1);
    json += ",\"humidity\":";
    json += isnan(humidity) ? String("null") : String(humidity, 1);
    json += ",\"readings\":";
    json += String(readings);
    json += "}";
    server.send(200, "application/json", json);
}

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

    WiFi.begin(SSID, PASSWORD);
    Serial.print("joining ");
    Serial.print(SSID);
    while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(250);
    }
    Serial.println();
    Serial.print("open http://");
    Serial.print(WiFi.localIP());
    Serial.println("/ in the Web tab");

    server.on("/", handleRoot);
    server.on("/data", handleData);
    server.begin();
    readSensor();
    readAt = millis();
}

void loop()
{
    server.handleClient();
    if (millis() - readAt >= 2000) {
        readAt = millis();
        readSensor();
    }
    delay(2);
}

Parts list

3 parts, plus the jumper wires. They retail for about $13; on Mokxi they're free.

How it is wired

3 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.

  • ESP32 DevKit V1 pin D4; Temperature and humidity, DHT22 pin DATA
  • 3.3 V: Temperature and humidity, DHT22 pin VCC
  • Ground: Temperature and humidity, DHT22 pin GND

Change it and keep it

Open it in the editor, change the circuit or the code, and keep your version in a free account.