ESP32 DevKit v1 · pinport
готово
⋮

Автополив и фитолампа на ESP32: панель на GyverLibs/Settings

Четвёртый вариант прибора: веб-админка не написана руками, а собрана библиотекой GyverLibs/Settings — скетч только перечисляет виджеты. Часы, климат, лампа и насосы обновляются на лету, расписание правится слайдерами и полями времени, есть журнал событий и файлы LittleFS. Экран и ручка остались.

Что на схеме

Плата ESP32 DevKit v1, к ней подключены:

  • Реле — rl1
  • Реле — rl2
  • Реле — rl3
  • Ввод 230 В — in
  • Автоматический выключатель — qf1
  • Выключатель одноклавишный — sw1
  • Светильник 230 В — la1, тип: импульсный
  • Блок питания 12 В — ps
  • Тумблер — sw2
  • Тумблер — sw3
  • Мотор 12 В — m1
  • Мотор 12 В — m2
  • LCD 16x2 (I2C) — lcd1
  • Часы реального времени DS3231 (I2C) — rtc1
  • Датчик HTU21D: температура и влажность (I2C) — ht1, влажность 45 %, температура 23.5 °C
  • Энкодер KY-040 (ручка с кнопкой) — enc1

Задействованы выводы платы: 3V3, GND, D21, D22, D18, D19, D5, D25, D26, D27. Всего соединений на схеме: 43.

Панель на Settings

В примере с веб-админкой страница написана руками: HTML, JavaScript и пять адресов /api/… — около сотни строк, которые к самому поливу отношения не имеют. Здесь их нет. Страницу рисует библиотека GyverLibs/Settings, а скетч только перечисляет в функции build(), что на ней стоит:

if (b.beginGroup("Фитолампа")) {
  uint32_t on = cfg.lampOn * 60UL;
  if (b.Time("Включение", &on)) { cfg.lampOn = on / 60; changed = true; }
  ...
}

Та же функция и принимает действия со страницы: виджет, который тронули, возвращает true и уже записал новое значение по указателю. Кнопка — тоже виджет: if (b.Button("Полить")) startPump(…).

Откройте панель кнопкой «Веб-интерфейс» над схемой (на железе — по адресу с последнего экрана LCD). На ней:

  • Сейчас — часы, климат, лампа (индикатор) и оба насоса: через сколько дней полив, а во время полива — обратный отсчёт. Эти поля обновляются сами раз в две секунды: страница спрашивает, onUpdate отвечает тем, что поменялось;
  • Фитолампа — время включения и выключения;
  • Насос P1, P2 — слайдер секунд, период, «осталось дней», час полива и кнопки «Полить» и «Стоп»;
  • Часы DS3231 — дата и время в поясе браузера: поменяли — часы встали;
  • Журнал — всё, что прибор пишет в монитор порта: включения лампы, поливы, сохранения.

Любая правка сразу пишется в NVS — там же, где её сохраняет ручка, так что экран и страница показывают одно и то же. В меню панели (☰) есть файловый менеджер: это LittleFS платы.

Пароль — константа ADMIN_PASSWORD; пустая строка — без пароля. Если своя сеть не подключилась за 15 секунд, плата поднимает точку доступа Greenhouse (пароль greenhouse), и панель открывается по адресу 192.168.4.1.

Библиотека в модели

Settings — сложная библиотека: страница приходит сжатой (gzip), общается с платой двоичным BSON, держит свои настройки в localStorage браузера и пользуется LittleFS. Всё это в PinPort работает с 1.8.44. Ставить её не нужно — вместе с зависимостями (GyverDB, GTL, StringUtils, GyverHTTP, BSON, Stamp, Table, StreamIO, FOR_MACRO) она уже на сервере сборки.

При первом запуске в мониторе порта будут строки Corrupted dir pair и mount failed — это LittleFS находит чистую флеш-память и размечает её (LittleFS.begin(true)). На новой плате будет то же самое.

Модель медленнее настоящей платы, а панель ждёт ответа две секунды. Если на медленном компьютере она показывает «нет связи», прибавьте sett.config.requestTout в startNetwork().

Экран и ручка

Всё как у остальных версий. Верхняя строка — часы, температура, влажность; нижняя листается поворотом:

  • L 07:00-21:00 ON — фитолампа;
  • 1 100s 3d(2) 20h — насос P1: качать 100 секунд, раз в 3 дня, осталось 2 дня (0 — сегодня), в 20:00;
  • 2 60s 2d(1) 08h — насос P2;
  • адрес страницы.

Нажатие — правка: мигает поле, поворот меняет его, следующее нажатие — следующее поле, после последнего настройки сохраняются. Долгое нажатие во время правки — отмена; на экране насоса — полить сейчас или остановить. Правка со страницы вытесняет правку с ручки.

В модели ручкой удобнее управлять с пульта в правом нижнем углу схемы: щёлкните по нему — стрелки ← → поворачивают, пробел нажимает.

Как считается полив

«Осталось дней» уменьшается при смене суток; номер последних суток хранится в NVS вместе с настройками, поэтому сутки, пропущенные выключенным прибором, тоже засчитываются. Когда счётчик дошёл до нуля и наступил час полива, реле насоса включается на заданное число секунд, а счётчик снова становится равен периоду.

Силовая часть

Та же, что у других версий: фитолампа — от сети через автомат qf1, выключатель sw1 и реле rl1; насосы — от блока 12 В через выключатели sw2, sw3 и реле rl2, rl3. Свободные реле модуля — на выводах 32, 33 и 14: третий насос — третий вывод в RELAY_PUMP и строка в DEFAULT_PUMPS, и панель сама покажет для него ещё одну группу.

Чем модель отличается от устройства

  • Питание. Модули I2C и реле в модели запитаны от 3V3. На железе LCD 1602 и модуль реле обычно просят 5 В: питайте их от VIN, а входы IN реле и шина I2C 3,3 В им подходят.
  • Уровень включения реле. В модели — высокий. Модули с оптронами часто включаются низким — поменяйте RELAY_ON.
  • Строки об ошибке LittleFS при первом запуске. «Corrupted dir pair» и «mount failed (-84)» в мониторе порта — это нормально: флеш-память чистая, LittleFS.begin(true) сама её размечает и монтирует заново. На настоящей плате при первой прошивке выводится то же самое; при следующем запуске строк уже нет.
  • Память. Прошивка с Settings занимает около 930 КБ — на ESP32 с обычной разметкой (1,2 МБ под программу) места хватает, но OTA-разметку «минимальный SPIFFS» выбирать не придётся.

Библиотеки

Пример собирается с библиотеками:

  • WiFi
  • Preferences
  • LittleFS
  • LiquidCrystal I2C
  • RTClib
  • Adafruit BusIO
  • Settings

Они уже установлены на сервере сборки — отмечать их в проекте вручную не нужно, список приезжает вместе с примером.

Как это устроено в коде

Основное, чем пользуется скетч:

  • Preferences — хранение настроек во flash, переживает перезапуск
  • RTClib — работа с часами реального времени
  • LiquidCrystal_I2C — текстовый экран 16×2 по двум проводам
  • DS3231 — точные часы с собственным термокомпенсированным генератором
  • digitalRead() — читает уровень на выводе
  • delay() — пауза, на время которой ядро занято ожиданием
  • constrain() — зажимает значение в границах
  • Serial.println() — печатает строку в монитор порта
  • millis() — миллисекунды с запуска: на них строят работу без остановки
  • digitalWrite() — выставляет на выводе высокий или низкий уровень
  • WiFi.begin() — подключается к точке доступа виртуального Wi-Fi
  • WiFi.softAP() — поднимает собственную точку доступа

В скетче 560 строк; свои функции: loadSettings(), saveSettings(), onEncoder(), htuRead(), readClimate(), note(), lampShouldBeOn(), startPump(); подключено заголовков: 7. Сам скетч открыт на соседней вкладке — его можно менять и запускать заново.

Что попробовать изменить

  1. Нажмите «Запустить»: сценарий дождётся сети, поставит часы на 19:59:40, переведёт ручкой насос P1 на «полить сегодня» — в 20:00 насос на схеме закрутится.
  2. Откройте «Веб-интерфейс»: панель Settings с часами, климатом, лампой и насосами. Нажмите «Полить» у насоса P2 — на схеме закрутится второй мотор, а в «Сейчас» пойдёт обратный отсчёт.
  3. Сдвиньте время выключения лампы на ближайшее — лампа погаснет, экран LCD покажет новое расписание, а в журнале появится «настройки сохранены (страница)».
  4. Поверните ручку на пульте и поменяйте период насоса — после сохранения панель покажет новое значение.
  5. Впишите пароль в ADMIN_PASSWORD и запустите снова: панель сначала спросит его.
Схема подключения: Автополив и фитолампа на ESP32: панель на GyverLibs/Settings (ESP32 DevKit v1)
Схема подключения: Автополив и фитолампа на ESP32: панель на GyverLibs/Settings (ESP32 DevKit v1)

Смотрите также

← Все примеры галереи

Схема
Проект из галереи — запускать можно, менять нельзя.

      
Сборка ещё не запускалась.

    Печатайте в Serial числа — они станут графиком. Serial.println(t); — один ряд, Serial.printf("t:%.1f h:%.1f\n", t, h); — два с подписями. Формат тот же, что понимает плоттер Arduino IDE.