Сенсори
Початковий
Міні-метеостанція: температура й вологість DHT22 у браузері
Датчик DHT22 + ESP32 = жива сторінка з показами, яка оновлюється кожні 5 секунд без перезавантаження. Плюс JSON-API для інших пристроїв.
Ідея
ESP32 кожні кілька секунд опитує датчик DHT22 і віддає дві адреси:
/— гарна сторінка-дашборд з великими цифрами;/data— JSON на кшталт{"t":22.4,"h":48.0}, який можна забирати з Home Assistant, Node-RED чи скрипта.
Сторінка сама підтягує нові дані через fetch(), тому перезавантажувати її не треба.
Компоненти
- ESP32 DevKit
- Датчик DHT22 (AM2302) — точніший за DHT11 (±0.5 °C, 0–100 % RH)
- Резистор 10 кОм (не потрібен, якщо DHT22 уже на платі-модулі з трьома виводами)
- Макетна плата, дроти
Підключення
| DHT22 | ESP32 |
|---|---|
| VCC (1) | 3V3 |
| DATA (2) | GPIO 4 + підтяжка 10 кОм до 3V3 |
| NC (3) | — |
| GND (4) | GND |
Бібліотеки
У Library Manager встановіть:
- DHT sensor library (Adafruit)
- Adafruit Unified Sensor (підтягнеться як залежність)
Код
#include <WiFi.h>
#include <WebServer.h>
#include <DHT.h>
#define DHT_PIN 4
#define DHT_TYPE DHT22
const char* WIFI_SSID = "YOUR_SSID";
const char* WIFI_PASS = "YOUR_PASSWORD";
DHT dht(DHT_PIN, DHT_TYPE);
WebServer server(80);
float temperature = NAN;
float humidity = NAN;
unsigned long lastRead = 0;
const char PAGE[] = R"rawliteral(
<!doctype html><html><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>ESP32 Weather</title>
<style>
body{font-family:system-ui;background:#0f1720;color:#e8eef3;display:grid;place-items:center;min-height:100vh;margin:0}
.box{display:flex;gap:48px;text-align:center}
.v{font-size:3.5rem;font-weight:700}.l{opacity:.7}
</style></head><body>
<div class="box">
<div><div class="v" id="t">--</div><div class="l">°C</div></div>
<div><div class="v" id="h">--</div><div class="l">% RH</div></div>
</div>
<script>
async function update() {
const d = await (await fetch('/data')).json();
document.getElementById('t').textContent = d.t === null ? '--' : d.t.toFixed(1);
document.getElementById('h').textContent = d.h === null ? '--' : d.h.toFixed(0);
}
update();
setInterval(update, 5000);
</script></body></html>
)rawliteral";
String jsonNumber(float v) {
return isnan(v) ? String("null") : String(v, 1);
}
void readSensor() {
float t = dht.readTemperature();
float h = dht.readHumidity();
if (!isnan(t) && !isnan(h)) {
temperature = t;
humidity = h;
} else {
Serial.println("DHT read failed");
}
}
void setup() {
Serial.begin(115200);
dht.begin();
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println(WiFi.localIP());
server.on("/", [] { server.send(200, "text/html", PAGE); });
server.on("/data", [] {
String json = "{\"t\":" + jsonNumber(temperature) + ",\"h\":" + jsonNumber(humidity) + "}";
server.send(200, "application/json", json);
});
server.begin();
}
void loop() {
server.handleClient();
// DHT22 не можна опитувати частіше ніж раз на 2 секунди
if (millis() - lastRead > 2500) {
lastRead = millis();
readSensor();
}
}
Нюанси
- Не блокуйте
loop(): читання датчика винесене в неблокуючий таймер наmillis(), тож сервер відповідає миттєво. - Якщо бачите
DHT read failed— перевірте підтяжку 10 кОм і що живлення саме 3.3 В. - Не кладіть датчик поруч із платою: ESP32 гріється на 3–5 °C і завищує покази.
Ідеї для розвитку
- Замініть DHT22 на BME280 (I²C) — отримаєте ще й атмосферний тиск.
- Зберігайте історію в кільцевому буфері й малюйте графік на сторінці (Chart.js).
- Додайте OLED-дисплей з проєкту «Годинник NTP» — і станція працюватиме без телефона.