У каждого датчика температуры и влажности в даташите написана своя погрешность. Но честная проверка -не читать даташит, а положить несколько штук в один и тот же воздух и снять показания в один и тот же момент. Я взял четыре популярных копеечных модуля с AliExpress — BME280, BMP280, AHT20 и HDC1080 — посадил их на одну шину I2C к одной ESP-шке и вывел всё на одну веб-страницу: у каждого датчика живое значение и график тренда, рядом.
Температуры совпали в пределах полуградуса. А вот с влажностью получилось интересно: один датчик показал на почти 10 процентных пунктов больше соседнего, который лежал в пяти миллиметрах от него. Ниже — как это выглядело, почему так вышло и на чём собран сам дашборд (спойлер: это несколько строк C++, без единой строчки фронтенда).

Зачем вообще сравнивать датчики
Если вы логируете теплицу, серверную, террариум или просто следите за микроклиматом в комнате, сдвиг влажности в 10% — это разница между «норма» и «тревога». Проблема в том, что по одному голому модулю вы никогда не узнаете, врёт он или нет: цифра выглядит правдоподобно, график ровный, всё «работает». Расхождение вылезает только когда рядом стоит второй датчик и показывает другое.
Так что цель была простая: поставить четыре разных чипа бок о бок и посмотреть, кто с кем согласен.
Железо
Всё подключение — это буквально четыре провода. В этом и весь смысл I2C: все датчики делят одни и те же SDA, SCL, 3V3 и GND, а различаются только адресом на шине.

— ESP8266 (Wemos D1 mini) или ESP32 — 200–400 ₽
— BME280 (0x76) — температура + влажность + давление
— BMP280 (0x77) — давление + температура, влажности нет
— AHT20 (0x38) — температура + влажность
— HDC1080 (0x40) — температура + влажность
На ESP8266 шина — это SDA = D2 (GPIO4), SCL = D1 (GPIO5); на ESP32 — GPIO21 / GPIO22. Адреса у всех четырёх разные, так что конфликта нет.
Отдельная история — вот эта фиолетовая плата:

Классическая ловушка AliExpress: на шелкографии написано сразу пять названий — SI7021 / HTU21D / SHT21 / SHT20 / HDC1080. Это одна и та же печатная плата, на которую распаивают любой из пяти разных чипов, и у них разные драйверы. Если не знаете, что вам приехало, — сканер I2C покажет адрес, а по адресу уже можно опознать чип. У меня на 0x40 сидел HDC1080 (библиотека ClosedCube HDC1080).
Результаты
Все четыре вышли на связь одновременно. Вот что показал живой дашборд:
| Датчик | Адрес | Температура | Влажность | Давление |
|—————|———|—————-|————-|—————|
| BME280 | 0x76 | 28.5 °C | 30.3 % | 967 hPa |
| BMP280 | 0x77 | 29.0 °C | — | 968 hPa |
| AHT20 | 0x38 | 28.6 °C | 32.3 % | — |
| HDC1080 | 0x40 | 28.7 °C | 39.7 % | — |
Температуры — плотная кучка в пределах 0.5 °C. Два датчика давления (BME280 и BMP280) сошлись до 1 hPa. А влажность разбежалась: BME280, AHT20 и BMP-компания держались около 30–32%, а HDC1080 сел на 39.7% — почти на десять пунктов выше.
Кто из них «прав»? Честный ответ — без эталонного гигрометра не сказать. Это ровно тот межэкземплярный разброс, который производитель закладывает в ±2…3% RH по даташиту, плюс разница в прогреве, самонагреве чипа и свежести калибровки. Ни один из них не сломан — просто им нельзя слепо доверять поодиночке. Отсюда практический вывод: если влажность у вас что-то решает, калибруйте по эталону, а не по одному голому модулю. И да — держать несколько датчиков рядом и смотреть на них вместе оказалось на удивление залипательно.
Код: дашборд в несколько строк
Теперь самое интересное для Хабра — как это выведено в браузер. Никакого HTML, CSS, JS и вебсокетов руками я не писал. Весь UI описывается декларативно: объявляешь виджет — библиотека сама генерит разметку, стили, скрипт и WebSocket-протокол, и всё это отдаёт сама ESP, без интернета и без облака.
Я использовал свою open-source библиотеку RisalDash (MIT). Вот, по сути, весь скетч — по блоку на датчик:
```cpp
#include <RisalDash.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_AHTX0.h>
#include <ClosedCube_HDC1080.h>
RisalUI dash("Sensor Compare");
Adafruit_BME280 bme; // 0x76
Adafruit_BMP280 bmp; // 0x77
Adafruit_AHTX0 aht; // 0x38
ClosedCube_HDC1080 hdc; // 0x40
bool bmeOK, bmpOK, ahtOK, hdcOK;
float bmeT, bmeH, bmeP, bmpT, bmpP, ahtT, ahtH, hdcT, hdcH;
void setup() {
Wire.begin();
bmeOK = bme.begin(0x76); // авто-детект: воткнул — вышел на связь
bmpOK = bmp.begin(0x77);
ahtOK = aht.begin(); // 0x38
hdcOK = i2cPresent(0x40);
if (hdcOK) hdc.begin(0x40);
dash.separator("BME280 · 0x76");
dash.led("BME280 online", &bmeOK);
dash.metric("BME280 temp", &bmeT, "°C").decimals(1);
dash.chart("BME280 temp trend", &bmeT, "°C");
dash.metric("BME280 humidity", &bmeH, "%").decimals(1);
dash.metric("BME280 pressure", &bmeP, "hPa").decimals(0);
// ...ещё три таких же блока: BMP280, AHT20, HDC1080
dash.enableOTA();
dash.apName("SensorCompare");
dash.begin(); // captive-portal, затем подключается к вашему Wi-Fi
}
```
Виджет привязывается к переменной по указателю (&bmeT) — а в loop() вы просто раз в пару секунд обновляете эти переменные, и каждый открытый браузер синхронно перерисовывается по WebSocket:
```cpp
void loop() {
dash.update();
static uint32_t last = 0;
if (millis() - last > 2000) {
last = millis();
if (bmeOK) { bmeT = bme.readTemperature();
bmeH = bme.readHumidity();
bmeP = bme.readPressure() / 100.0f; }
// ...остальные датчики, с проверками isnan()
}
}
```
dash.led("... online", &bmeOK) — тот же приём: булев флаг от begin() и управляет индикатором на карточке. Сняли датчик с шины — карточка гаснет в «offline», остальные работают дальше.
Wi-Fi без хардкода
Пароль от сети в код я не зашивал. При первом включении плата не находит сохранённой сети и поднимает точку доступа с captive-порталом (SensorCompare). Подключаешься телефоном — страница настройки открывается сама, выбираешь домашний Wi-Fi, вводишь пароль. ESP сохраняет данные, перезагружается и дальше подключается к сети сама. Дашборд ждёт по своему IP в локалке. Всё отдаётся с устройства — наружу ничего не уходит.
А поскольку в скетче включён dash.enableOTA(), следующие прошивки летят по воздуху прямо из браузера — USB-кабель нужен ровно один раз.
Итог
Четыре датчика, одна шина, одна страница — и наглядная картинка того, насколько по-разному копеечные модули видят один и тот же воздух. Температуре можно верить, давлению — тем более, а вот влажность стоит проверять хотя бы вторым датчиком, а лучше эталоном.
Полный, собранный и проверенный на ESP32 и ESP8266 исходник лежит здесь:
— Пример Sensor Compare: https://github.com/ziyarago/RisalDash/tree/main/examples/06_Projects/SensorCompare
— Библиотека RisalDash (MIT):
https://github.com/ziyarago/RisalDash
— Сайт с примерами и живым демо: dash.risal.io
Если тоже ловили расхождения между модулями — расскажите в комментариях, какой чип у вас оказался самым честным. Мне интересно, HDC1080 всегда так завышает или это мне попался конкретно бодрый экземпляр.
ссылка на оригинал статьи https://habr.com/ru/articles/1061456/