RisalDash RisalDash

Проект · Погода · Улица

Полная метеостанция, которая действительно ваша

Настоящая метеостанция — это две сборки в одной: простая домашняя половина — BME280 + свет — и уличная мачта с дождемером, анемометром и UV-датчиком. В этом гайде обе на одном ESP32, с живым статусом «Ясно / Облачно / Дождь», алертами шторма и жары и дашбордом, который чип отдаёт сам — без погодного облака, ваши данные остаются вашими.

ПроектПогодаBME280АнемометрESP32
Проект метеостанции на ESP32: ветер, дождь, UV, свет, BME280 и штормовые алерты

Сенсоры — что чем меряется

СенсорМеряетИнтерфейсЗаметка
BME280темп · влажность · давлениеI²Cядро — тренд давления предсказывает дождь
Дождемер-качалкаосадки (мм)импульскаждый кувырок = фикс. объём
Чашки анемометраветер / порывыимпульс (прерывание)геркон, раз за оборот
Флюгернаправлениеаналогрезисторная лесенка по румбам
GY-ML8511UV-индексаналогсолнечная экспозиция
LDR / BH1750свет (лк)аналог / I²Cпитает логику день/ночь

BME280 подключается как любой I²C-сенсор — SDA/SCL плюс питание. Импульсные сенсоры (дождь, ветер) — на GPIO с прерываниями; флюгер, UV и LDR — на ADC-пины.

BME280 подключён к ESP32 по I²C
Домашняя половина — 4 провода. Собрано в BoardLab.

Считаем ветер — прерывание, а не 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. Для экрана на столе подойдёт любой дисплей из гайда по дисплеям — от тех же переменных.

Вся станция уже работает на фейках — мачта может приезжать посенсорно.