Точный прогноз дождя: Arduino-станция с Python и Keras — полный цикл от датчиков до нейросети
Компоненты и материалы
- Пластиковый корпус с съёмной крышкой (11×7×5 см) — 1 шт.
- Корпус для 3×ААА батарей — 1 шт.
- 3×ААА NiMH аккумулятора — 1 компл.
- Солнечная панель 6В — 1 шт.
- Arduino Pro Mini 328P 5V/16MHz — 1 шт.
- Диод 1N4004 (защита от обратного тока) — 1 шт.
- NPN-транзистор + 1 кОм (коммутация питания периферии) — 1 шт.
- Датчик дождя — 1 шт.
- Модуль HC-12 (передатчик) — 1 шт.
- Модуль HC-12 USB (приёмник базовой станции) — 1 шт.
- BME280 (температура, влажность, давление) — 1 шт.
- BH1750 (освещённость) — 1 шт.
- Печатная плата, провода, припой, разъёмы KF301-2P, клей — 1 компл.
- Стабилизатор 3.3В — 1 шт.
- Базовая станция: ПК/SBC (Raspberry Pi, ноутбук) под Linux — 1 шт.
Необходимые инструменты
- USB-UART адаптер FT232RL (прошивка Pro Mini)
- Arduino IDE
- Дрель, тонкая пила, отвёртки, паяльник, бокорезы
О проекте
Цель — предсказать дождь за 6 часов вперёд (булево: будет/не будет). Проект охватывает весь цикл: автономнаяmeteoстанция с солнечным питанием и глубоким сном (≈50 µA), сбор данных каждые 10 минут, передача по радиоканалу HC-12 на базовую станцию, запись в MongoDB, предобработка Pandas, обучение нейросети Keras, прогноз и уведомление по email.
С ~600 дней данных точность достигает ~80%. Все этапы реализованы без внешних API — полностью локально.
Шаг 1: Детали и инструменты
Полный список приведён выше. Навыки: пайка, базовый Arduino, настройка Linux-сервисов, Python.
Шаг 2: Сборка станции
- В корпусе просверлите 4 отверстия: для проводов панели и трёх датчиков (BME280, BH1750, дождь). Приклейте панель снаружи, выведите провода внутрь.
- На печатной плате распаяйте: гнезда для Pro Mini, HC-12, стабилизатор 3.3В, диод, транзистор с резистором, два разъёма KF301 (панель и батареи), три гнезда для датчиков. Важно: снимите или перережьте ножку встроенного LED на Pro Mini — он потребляет заметный ток.
- Установите заряженные аккумуляторы в корпус, подключите к разъёму.
- Подключите датчики снаружи к соответствующим гнездам. Датчик дождя распаяйте на трёхпроводном шлейфе (GND, VCC, сигнал).
- Закрепите станцию в месте, защищённом от прямых осадков (для основного блока). Датчик дождя вынесите отдельно на устойчивую стойку под открытым небом.
Шаг 3: Код Arduino
Скетч каждые 10 минут: пробуждает периферию, опрашивает датчики, передаёт пакет через SoftwareSerial (HC-12), усыпляет периферию и уходит в глубокий сон (LowPower.powerDown на 8-секундных циклах). Если напряжение >4.2В — использует обычный delay для разряда (защита от перезаряда).
Формат пакета: H1:78|T1:12|PS1:1022|L1:500|R1:0|V1:4010| (влажность %, температура °C, давление гПа, освещённость люкс, дождь 0/100, напряжение мВ).
Необходимые библиотеки: LowPower, SoftwareSerial, Wire, Adafruit_Sensor, Adafruit_BME280, BH1750. Ссылки на GitHub в исходнике.
Важно: перед загрузкой удалите строку transmitSenzorData("V", sensors.voltage); — она дублирует передачу напряжения.
Шаг 4: Базовая станция (Linux)
- Установите Anaconda (Python 3.6.2), MongoDB (v3.4+), клонируйте репозиторий
https://github.com/danionescu0/home-automation. - Создайте окружение
weather, установите зависимости:pip install -r requirements.txt(Keras, pandas, pymongo, sklearn). - Настройте
config.py: хост/порт MongoDB, последовательный порт HC-12 USB (обычно/dev/ttyUSB0, 9600 бод).
Шаг 5: Работа с данными
- Импорт тестовых данных:
mongoimport -d weather -c weather_station --file sample_data/weather_station.json - Сбор своих данных:
conda activate weather && python serial_listener.py(видите входящие пакеты каждые 10 мин). - Обучение модели:
python train.py --days_behind 600 --test-file-percent 10 --datapoints-behind 8 --hour-granularity 6 - Графики за 10 дней:
python graphs --days-behind 10 - Прогноз с email:
python predict.py --datapoints-behind 8 --hour-granularity 6 --from-addr gmail --from-password pass --to-addr to_addr(в Gmail включите «менее безопасные приложения»). - Пакетный тест:
python predict_batch.py -f sample_data/test_data.csv
Шаг 6: Как это работает (внутренности)
Архитектура
Разделение станции и базы даёт: низкое потребление, портативность, масштабируемость (можно добавить станции), низкую стоимость. MongoDB выбрана за schemaless, простоту, бесплатность. Данные агрегируются по минутам.
Подготовка данных (ключевой этап)
- Сырые точки → очистка (drop NaN).
- Группировка в 6-часовые окна. Для каждого датчика считаются: min, max, mean, перцентили 10/30/70/90, число подъёмов/спадов/плоских участков.
- Добавление целевой колонки
has_rain(1 еслиrain_avg > 0.1). - Удаление дат, строк с
temperature_min < 0(нет снегоизмерителя). - Лаговые признаки: для каждого параметра добавляются значения за 8 предыдущих окон (48 часов) — оптимально по экспериментам.
- Удаление строк с NaN (первые окна) и текущих значений (кроме
has_rain). - Случайный split train/test (sklearn), разделение на X/y, масштабирование StandardScaler (сохранение scaler'а через joblib).
Нейросеть (Keras)
model = Sequential([
Input(shape=(n_features,)),
Dense(n_features//2, activation='relu'), Dropout(0.05),
Dense(n_features//2, activation='relu'), Dropout(0.05),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='rmsprop', loss='mean_absolute_error', metrics=['accuracy'])
model.fit(X, y, batch_size=1, epochs=50)
model.save('model.h5')
Гиперпараметры (слои, нейроны, dropout, optimizer, loss, batch, epochs) требуют подбора. Скрипт train.py --grid-search перебирает комбинации.
Шаг 7: Бонус — официальные данные Dark Sky API
Использование исторических данных Dark Sky (ветра, UV, видимость и др.) повышает точность с ~80% до ~90%. Инструкции по загрузке/импорту и обучению с флагом --data-source darksky в репозитории.
Код
Основные фрагменты: скетч станции (weatherStation), скрипты Python (serial_listener.py, train.py, predict.py, graphs.py), конфиг, требования. Полный код на GitHub: weatherStation и weather-predict.
Схемы

Fritzing-файл: sketch_KAtDa2VReF.fzz в репозитории.
Производственный процесс
- Создание удалённого датчика температуры на Raspberry Pi и Python — пошаговое руководство
- DIY-консоль управления Photoshop на Arduino Nano RP2040 Connect
- Переименование файлов и директорий в Python с os.rename() — пошаговое руководство
- Надежная система учета рабочего времени на Arduino с RFID и Python
- Универсальный Android-пульт на Arduino, 1Sheeld и ИК-управлении
- Умный вольтметр на Arduino и смартфоне — простое DIY-проект
- Надежный ИК-датчик пульса на Arduino: пошаговое руководство
- Точное измерение частоты и коэффициента заполнения на Arduino UNO
- Сборка вольтметра на Arduino с дисплеем Nokia 5110 — Пошаговое руководство
- Измерение расстояния в реальном времени: Ардуино-сонар с визуализацией в Processing