Проект · Погода · Улица
Полная метеостанция, которая действительно ваша
Настоящая метеостанция — это две сборки в одной: простая домашняя половина — BME280 + свет — и уличная мачта с дождемером, анемометром и UV-датчиком. В этом гайде обе на одном ESP32, с живым статусом «Ясно / Облачно / Дождь», алертами шторма и жары и дашбордом, который чип отдаёт сам — без погодного облака, ваши данные остаются вашими.
Сенсоры — что чем меряется
| Сенсор | Меряет | Интерфейс | Заметка |
|---|---|---|---|
| BME280 | темп · влажность · давление | I²C | ядро — тренд давления предсказывает дождь |
| Дождемер-качалка | осадки (мм) | импульс | каждый кувырок = фикс. объём |
| Чашки анемометра | ветер / порывы | импульс (прерывание) | геркон, раз за оборот |
| Флюгер | направление | аналог | резисторная лесенка по румбам |
| GY-ML8511 | UV-индекс | аналог | солнечная экспозиция |
| LDR / BH1750 | свет (лк) | аналог / I²C | питает логику день/ночь |
BME280 подключается как любой I²C-сенсор — SDA/SCL плюс питание. Импульсные сенсоры (дождь, ветер) — на GPIO с прерываниями; флюгер, UV и LDR — на ADC-пины.
Считаем ветер — прерывание, а не loop
Анемометр замыкает геркон раз за оборот. Опрашивать его в loop — терять счёт, как только дашборд вздохнёт; поэтому считаем в прерывании и конвертируем раз в секунду:
// Anemometer: a reed switch pulses once per rotation -> count on an interrupt.
volatile uint32_t pulses = 0;
void IRAM_ATTR onPulse() { pulses++; }
// setup: pinMode(WIND_PIN, INPUT_PULLUP); attachInterrupt(WIND_PIN, onPulse, FALLING);
// each second: wind = pulses * KMH_PER_HZ; pulses = 0; (KMH_PER_HZ from the cup datasheet) Дашборд — мачту закрывает один пресет
dash.sensor("weather", …) разворачивается в полный набор анемометр + флюгер + дождемер
с правильными единицами и диапазонами; остальное — шкала, бейдж и журнал:
dash.layout("Weather", RICON_WATER);
dash.sensor("weather", &wind, &gust, &dir, &rain); // anemometer · vane · rain preset
dash.gauge("UV index", &uv, 0, 12);
dash.badge("Conditions", &sky).labels("Clear", "Cloudy", "Rain");
dash.led("Weather alert", &alarmOut); // red LED + buzzer outside
evlog = &dash.log("Alerts", 5);
dash.layout("Ambient", RICON_THERMOMETER);
dash.sensor("bme280", &temp, &hum, &pres).chart(); // T / RH / hPa with history
dash.metric("Light", &lux, "lx"); // LDR or BH1750
dash.beginAP("RisalDash-Weather", "12345678"); Статус и алерты — мало логики, много пользы
«Идёт дождь?» — это просто тикающий счётчик осадков. «Облачно?» — свет ниже порога. Штормовой порыв или жара включают алерт-LED (на тот же пин вешается зуммер) и пишут строку в журнал:
// Conditions: raining if the bucket is ticking, else clear vs dim by daylight.
bool raining = rain - rainPrev > 0.01f;
rainPrev = rain;
sky = raining ? 2 : (lux < 8000 ? 1 : 0);
// Alerts: a storm gust or extreme heat trips the LED/buzzer + a log line.
bool trip = gust > 60 || temp > 40;
if (trip && !alarmOut && evlog)
evlog->print(gust > 60 ? "STORM - gusts over 60 km/h" : "HEAT - over 40 C");
alarmOut = trip; Пример из библиотеки (examples/04_Templates/WeatherStation) гоняет всё это без железа: порывистый ветер, проходящие ливни, UV и свет по виртуальному солнцу. Посмотрите сегодня, как срабатывают бейдж «Rain» и штормовой алерт, а потом меняйте фейки на реальные драйверы посенсорно — workflow фейк-сенсоров.
Развитие
Добавьте deep sleep и LiFePO4
— получите солнечную мачту на месяцы; подтяните живой прогноз Open-Meteo (библиотечный
RisalWeather.h, без ключа) рядом со своими данными; публикуйте в
MQTT для Home Assistant. Для экрана на столе подойдёт любой дисплей
из гайда по дисплеям — от тех же переменных.
Вся станция уже работает на фейках — мачта может приезжать посенсорно.