Старт прошивки на ядре¶
На этой странице вы создаёте проект прошивки, доводите ESP32 до состояния Online на портале и проверяете, что сетевая часть работает. Датчики и логику нагрева добавим на следующих шагах.
Подход построен на фасаде iDryer::Link. Вы описываете устройство одной структурой iDryer::Config, вызываете link.begin() и link.loop() — всё подключение к сети ядро делает само.
1. Подготовьте инструменты¶
Понадобится:
- VS Code с расширением PlatformIO;
- USB-кабель;
- Wi-Fi-сеть
2.4 GHz(ESP32 не работает с сетями только5 GHz); - смартфон с приложением iDryer (App Store, Google Play), в котором вы вошли в свой аккаунт портала iDryer: через него устройство получит сеть Wi-Fi и привяжется к аккаунту;
- библиотека ядра idryer-core;
- готовый проект этой главы — example/09-cabinet в репозитории учебника: оттуда берутся драйвер датчика и другие файлы, которые дальше предлагается скопировать.
Что такое прошивка контроллера и как она попадает в плату — Прошивка контроллера.
2. Создайте проект¶
В PlatformIO проект — это папка с фиксированной структурой. Создайте папку проекта (например my-cabinet) и откройте её в VS Code. Внутри должны быть такие файлы:
my-cabinet/
├── platformio.ini # настройки сборки (заполним в шаге 4)
├── lib/
│ └── idryer-core/ # библиотека ядра (симлинк или копия)
└── src/
└── main.cpp # код устройства: Config + setup() + loop()
Все фрагменты кода ниже кладутся именно в эти файлы — у каждого шага указано, в какой. Папки include/, lib/ и src/ создайте вручную, если их нет.
Библиотеку idryer-core положите в lib/ — PlatformIO находит библиотеки там автоматически. Проще всего сделать симлинк на скачанную библиотеку:
git clone https://github.com/pavluchenkor/idryer-core.git ~/idryer-core
ln -s ~/idryer-core lib/idryer-core
Вместо симлинка можно просто скопировать папку библиотеки в lib/idryer-core — работает так же.
Это же требуется для генерации меню (глава 6) — хук ищет генератор внутри lib/idryer-core/.
3. Wi-Fi и привязка — не в коде¶
В прошивке нет ни пароля от сети, ни данных аккаунта. При первом запуске у устройства нет Wi-Fi, и оно ждёт настроек: приложение iDryer передаёт их по воздуху (ESPTouch), а затем привязывает устройство к вашему аккаунту одноразовым токеном привязки. Всё это ядро делает внутри s_link.begin() и s_link.loop(), вам остаётся пройти шаги в приложении — раздел 9.
Как сеть попадает в устройство. Плата без сохранённой сети слушает эфир, как приёмник без настройки на станцию. Телефон в это время «выстукивает» имя сети и пароль в воздух — примерно как азбукой Морзе, только пакетами Wi-Fi. Плата ловит эту передачу, подключается к сети и дальше выходит в неё сама при каждом включении. Отдельных выводов и проводов для этого не нужно: работает штатная антенна платы, включается само, пока сети нет, и длится до 90 секунд.
Если по воздуху не получилось, есть проводной путь: веб-установщик install.idryer.org передаёт плате сеть и токен привязки по USB — то же самое, что делает приложение, только по кабелю. Помогает и обычная перезагрузка платы: после неё она снова ждёт настроек.
4. Настройте platformio.ini¶
Заполните platformio.ini в корне проекта:
[env:cabinet]
platform = espressif32
framework = arduino
board = esp32-c3-devkitm-1
; Библиотеки ядра (MQTT, ArduinoJson, WebSockets, Improv) приходят
; сами из lib/idryer-core/library.json.
; ESPAsyncTCP — транспорт ESP8266 из зависимостей espMqttClient:
; на ESP32 он не собирается, его нужно исключить.
lib_ignore = ESPAsyncTCP
build_flags =
-DIDRYER_API_BASE='"https://portal.idryer.org/api"'
-DMQTT_BROKER='"mqtt.idryer.org"'
-DMQTT_PORT=8883
-DMQTT_USE_TLS=1
Замените board на свою плату (например, esp32-s3-devkitc-1). Саму idryer-core указывать в lib_deps не нужно — она лежит в lib/ (шаг 2).
Что делают эти строки
Зависимости ядра перечислять не нужно: PlatformIO берёт их из lib/idryer-core/library.json. lib_ignore = ESPAsyncTCP обязателен — без него сборка падает в ESPAsyncTCP.cpp. Флаги MQTT_BROKER и MQTT_PORT тоже обязательны — без них ядро не скомпилируется ('MQTT_BROKER' was not declared).
5. Опишите устройство в Config¶
Дальше всё происходит в одном файле — src/main.cpp. Откройте его и запишите код этого и следующих шагов.
iDryer::Config — это паспорт устройства. Флаги has* сообщают порталу, что у устройства есть, и определяют, какие поля телеметрии публикуются.
Для обогреваемого шкафа в начало src/main.cpp
#include <iDryer.h>
static const iDryer::Config CFG = {
.deviceType = iDryer::DeviceType::Unknown, // своё устройство: карточку собирает манифест
.unitsCount = 1,
.telemetryPeriodMs = 5000,
.statusPeriodMs = 10000,
.hardwareVersion = "1.0",
.firmwareVersion = "0.1.0",
.model = "DIY Storage Cabinet",
};
static iDryer::Link s_link(CFG);
Флаги has* — это контракт с порталом
Поле телеметрии, у которого соответствующий флаг false, не публикуется. Например, без hasAirHumidity = true влажность не попадёт в облако, даже если вы запишете её в код. Включайте только то, что физически есть в устройстве.
Перечень компонентов и флагов — Состав системы.
6. Минимальный основной¶
В том же файле после блока Config добавьте функции setup() и loop(). Для первого запуска достаточно завести ссылку и крутить ее в loop():
void setup() {
Serial.begin(115200);
s_link.begin();
// Устройство отвязали на портале: стереть секрет, ждать новой привязки.
s_link.onCommand("revoke", [](JsonObjectConst) { s_link.handleRevoke(); });
}
void loop() {
s_link.loop();
}
s_link.begin() поднимает Wi-Fi, привязку и связь с порталом. Команда revoke приходит с портала, когда устройство отвязывают от аккаунта: handleRevoke() стирает секрет устройства, и оно ждёт новой привязки. Датчики добавим на шаге Датчики.
Полный src/main.cpp после этой главы¶
Возьмите оба блока выше в один файл — это весь src/main.cpp на данном шаге:
#include <iDryer.h>
static const iDryer::Config CFG = {
.deviceType = iDryer::DeviceType::Unknown, // своё устройство: карточку собирает манифест
.unitsCount = 1,
.telemetryPeriodMs = 5000,
.statusPeriodMs = 10000,
.hardwareVersion = "1.0",
.firmwareVersion = "0.1.0",
.model = "DIY Storage Cabinet",
};
static iDryer::Link s_link(CFG);
void setup() {
Serial.begin(115200);
s_link.begin();
// Устройство отвязали на портале: стереть секрет, ждать новой привязки.
s_link.onCommand("revoke", [](JsonObjectConst) { s_link.handleRevoke(); });
}
void loop() {
s_link.loop();
}
Предыдущий глава показывает, что добавить и полный src/main.cpp после изменений, чтобы вы всегда видели целую картину, а не разрозненные куски.
7. Прошейте¶
8. Откройте Serial Monitor¶
Пока у устройства нет Wi-Fi, лог молчит: ядро держит последовательный порт для веб-установщика (Improv). Логи включаются, как только поднялся Wi-Fi. У ещё не привязанного устройства лог заканчивается так:
[BOOT] WiFi ok, logs enabled
[INFO ] CLOUD: WiFi connected, IP: 192.168.1.42, RSSI: -55 dBm, …
…
[INFO ] CLOUD: binding-v3: no secret — awaiting pairing token (SETUP)
Последняя строка — то, что и нужно на этом шаге: сеть есть, секрета привязки нет, устройство ждёт токен из приложения. Оставьте монитор открытым и переходите к приложению.
9. Подключите Wi-Fi и привяжите устройство в приложении¶
- Подключите телефон к той сети Wi-Fi, в которой будет работать устройство (
2.4 GHz), и войдите в приложение iDryer под своим аккаунтом портала. - На главном экране нажмите Подключить новое устройство — откроется шаг Wi-Fi.
- Проверьте название сети (приложение подставляет его само, если включена геолокация), введите пароль и нажмите Подключить устройство. Приложение передаёт настройки до 90 секунд; когда устройство подключится к сети, появится Устройство подключено. Нажмите Далее.
- На шаге Привязка нажмите Привязать. Приложение найдёт устройство в сети, получит у портала одноразовый токен привязки, передаст его устройству и дождётся, пока портал подтвердит, что устройство вышло на связь.
- После Устройство привязано оно появится в списке устройств на портале и в приложении.
Если устройство уже в сети, сразу откройте шаг Привязка — нажмите его чип вверху окна.
Шаг Wi-Fi: приложение передаёт сеть устройству по воздуху.
Шаг Привязка: приложение нашло устройство в сети по его серийному номеру. Чужие устройства помечены как занятые.
Готово: устройство привязано к аккаунту и сейчас появится в списке.
В логе видна привязка:
[INFO ] CLOUD: binding-v3: pairing token received (… chars)
[INFO ] CLOUD: binding-v3: activating with pairing token (serial=DEVICE_… mcu=-)
[INFO ] CLOUD: binding-v3: activated, deviceId=… -> Ready
…
[INFO ] MQTT: Connected! …
Проверка результата¶
На этом этапе устройство должно быть Online на портале. Данных датчиков пока нет — это ожидаемо: Config ещё ничего о них не объявил, и карточке нечего показать.
Устройство на портале: имя, состояние Idle, значок связи. Показаний нет — они появятся в следующей главе.
Имя Device DEVICE_… — заводское. Переименуйте устройство карандашом рядом с именем: дальше в примерах оно называется «Storage cabinet».
Если что-то пошло не так:
- приложение не дождалось подключения устройства к сети — проверьте пароль и что сеть
2.4 GHz; при неверном пароле устройство снова ждёт настроек, перезагрузите плату и повторите шаг Wi-Fi; - сеть так и не передаётся по воздуху — сделайте то же самое по USB через веб-установщик install.idryer.org;
- на шаге Привязка приложение не нашло устройство — телефон и устройство должны быть в одной сети, и сеть не должна блокировать обнаружение устройств (гостевые сети часто блокируют);
- устройство перезагружается — проверьте питание ESP32 (просадки напряжения при старте — частая причина сбросов);
- сборка падает с ошибкой — спросите в сообществе: Telegram, Discord;
- см. Ошибки питания и Ошибки контроллера.
Что дальше¶
Сетевая часть работает. Переходите к Датчикам: подключим SHT31 и термистор и увидим их данные на портале.