Прошивка через программатор¶
Обычные dev-платы (NodeMCU, ESP32 DevKit) имеют USB-UART chip на борту — прошивка идёт штатным pio run -t upload, ничего лишнего не нужно. Эта страница — про случаи когда USB на плате нет и приходится подключаться внешним программатором: типично ESP-01S, а также bare-модули ESP-12 без обвязки.
Что такое программатор¶
Программатор — это адаптер между USB-портом компьютера и UART-пинами целевой ESP. Внутри стоит чип USB-UART моста (CH340, CP2102, FT232, и т.п.), который превращает USB-поток в TX/RX на 3.3V уровне.
ESP во время прошивки получает данные по UART и пишет их в свой Flash-чип. Это требует:
- Питание 3.3V на ESP (
VCC+EN/CH_PD). - Общий
GNDмежду ESP и программатором. TX программатора → RX ESP,RX программатора → TX ESP(cross).- GPIO0 = LOW в момент power-on → ESP заходит в bootloader-режим и ждёт прошивку.
Типы программаторов¶
1. Специализированный для ESP-01¶
Маленький адаптер с DIP-разъёмом 2×4 под пины ESP-01. Втыкается прямо в USB. Самый удобный вариант.
Плюсы:
- Pin-to-pin совместимость, не надо думать о проводах.
- Часто есть кнопка/перемычка GPIO0→GND для входа в bootmode.
Минусы:
- LDO 3.3V обычно слабый (50–100 mA). ESP8266 на пиках тянет до 220 mA → просадка напряжения → плата отваливается в середине flash. Симптом: esptool читает chip_id успешно, но
write_flashпадает сSerialException: Input/output errorчерез минуту-другую. - Не у всех есть кнопка GPIO0 — иногда нужно паять перемычку.
Если виснет на flash
Самый простой фикс — добавить электролитический конденсатор 100µF–470µF между VCC и GND ESP-01S. Сглаживает броски тока, в большинстве случаев решает.
2. USB-TTL адаптер (CH340G / CP2102 / FT232)¶
Обычный «свисток» USB-A или micro-USB ↔ 4–6 пинов. Универсальный, дешёвый, в наличии у любого радиолюбителя.
Плюсы:
- LDO 3.3V у нормальных модулей выдаёт 300–500 mA — питания хватает.
- Гибкое подключение — провода куда хочешь.
Минусы:
- Подключение вручную (4 провода: VCC, GND, TX, RX) + перемычка GPIO0→GND.
- Некоторые дешёвые модели не имеют 3.3V вообще (только 5V) — подавать 5V на ESP-01 нельзя, сгорит. Проверить мультиметром перед подключением.
3. Другая ESP-плата как UART-мост¶
Если есть рабочая NodeMCU/ESP32 dev-board — она же по сути «программатор для самой себя» (CH340 на борту). Можно использовать её как мост к ESP-01S:
- Замкнуть
EN/CH_PDпин на NodeMCU на GND → её ESP-чип спит, CH340 проксирует USB к UART-пинам. - Подключить ESP-01S к NodeMCU без cross-а (TX→TX, RX→RX) — CH340 уже cross'нул внутри своей платы.
Подробная схема — ниже в разделе Аварийный вариант через NodeMCU.
Плюсы:
- LDO у NodeMCU — AMS1117-3.3, 800 mA, держит ESP-01S с большим запасом. Самый стабильный вариант когда специализированный программатор виснет.
Минусы:
- Дольше подключать (5 проводов + перемычка EN).
Прошивка ESP-01S — стандартная процедура¶
Предполагаем что есть рабочий программатор (вариант 1 или 2).
1. Подключить¶
| Программатор | ESP-01S | Назначение |
|---|---|---|
VCC 3.3V |
VCC + CH_PD |
питание |
GND |
GND |
земля |
TX |
RX (GPIO3) |
data PC → ESP |
RX |
TX (GPIO1) |
data ESP → PC |
GND (или кнопка/перемычка) |
GPIO0 |
bootmode при power-on |
2. Сборка прошивки¶
cd ctrl-board
pio run -e esp01s # firmware ~525KB, env с NO_WEB_UI
pio run -e esp01s -t buildfs # FS image (только /config, ~3KB)
Verify в выводе: Flash: ~55% (used 538K from 958K), RAM: ~74%.
3. Залить firmware¶
С установленной перемычкой GPIO0→GND, воткни программатор в USB:
Прогресс должен идти от 0% до 100% за ~30–45 секунд. После Hash of data verified плата делает soft-reset.
4. Залить FS¶
ESP-01S вышла из bootmode после reset → передёрни USB (с перемычкой GPIO0 на месте) для повторного входа в bootmode:
FS заливается за пару секунд (на NO_WEB_UI build он крошечный).
5. Запустить прошивку¶
Сними перемычку GPIO0→GND, передёрни USB → плата стартует прошивку, поднимает AP или подключается к сохранённой Wi-Fi сети.
Troubleshooting¶
Failed to connect to ESP8266: Timed out waiting for packet header¶
ESP не отвечает на esptool sync. Возможные причины:
- GPIO0 не на GND во время power-on. Проверь перемычку, передёрни USB.
- Программатор не передаёт UART. Проверь что вставлен в правильный USB-порт,
pio device listего видит. Попробуйesptool.py --port /dev/ttyUSB0 chip_id— должно работать. - TX/RX перепутаны. На специализированных программаторах для ESP-01 — обычно correct, на USB-TTL — проверь cross.
- GPIO0 работает только при power-on. Если плата уже загружена в normal mode —
pio run -t uploadне разбудит её в bootmode. Передёрни USB с уже стоящей перемычкой.
SerialException: Input/output error в середине flash¶
ESP-01S отвалилась от просадки питания. См. Специализированный программатор — конденсатор или внешнее питание.
Hard resetting via RTS pin есть, но плата не стартует¶
Не все программаторы подключают RTS к RST ESP-01. Тогда --after hard_reset ничего не делает физически и плата висит в stub-running. Передёрни USB вручную (с перемычкой СНЯТОЙ для normal boot).
Boot ROM-banner мусором в Serial Monitor¶
Boot ROM ESP8266 печатает первое сообщение на baud 74880, потом приложение переключается на свой baud (обычно 115200). Если открыть монитор на 115200 — banner будет нечитаем.
Чтобы посмотреть boot mode:(N,M) (для проверки что GPIO0 правильно read'ится):
Расшифровка boot mode:
(3, x)— normal flash boot, GPIO0=HIGH. Ожидаемо.(1, x)— UART download mode, GPIO0=LOW. Перемычка ещё стоит.
NodeMCU bridge¶
Когда специализированный программатор виснет от просадки питания, можно использовать NodeMCU/ESP32 dev-board как USB-UART мост. LDO у NodeMCU мощнее и держит ESP-01S без проблем.
Подключение¶
| NodeMCU | ESP-01S | Назначение |
|---|---|---|
EN (CH_PD) → GND |
— | держит чип NodeMCU в reset (CH340 свободно проксирует USB) |
3V3 |
VCC + CH_PD |
питание |
GND |
GND |
земля |
RX (пин RXD0) |
RX (GPIO3) |
БЕЗ cross! CH340 уже cross внутри NodeMCU |
TX (пин TXD0) |
TX (GPIO1) |
БЕЗ cross! |
GND (через перемычку) |
GPIO0 |
bootmode |
Внимание: маркировка RX/TX на NodeMCU указана с точки зрения ESP-чипа. Когда мы держим ESP в reset, пины RX/TX физически становятся TX/RX программатора (тока через ESP нет). CH340 уже cross'нул сигналы внутри платы, поэтому с ESP-01S подключаем 1-в-1.
Прошивка¶
После сборки схемы — стандартная процедура: pio run -e esp01s -t upload + -t uploadfs с power-cycle (передёргиванием USB всей NodeMCU) перед каждой попыткой flash.
После прошивки:
- Сними перемычку GPIO0→GND на ESP-01S.
- Сними перемычку EN→GND на NodeMCU (чтобы её ESP-чип ожил, если хочешь использовать NodeMCU дальше).
- Передёрни USB → ESP-01S стартует прошивку.
OTA на ESP-01S — не поддерживается¶
Решено: ESP-01S прошивается только UART через программатор. Cloud не публикует esp01s_*.bin артефакты намеренно (CB-138).
Почему¶
- ESP8266 Update API требует место ВНЕ текущей firmware-partition для записи нового image, потом swap указателей.
- Layout
eagle.flash.1m64.ld(наш) — одна app-partition 940KB + 64KB FS = занято всё. Свободных секторов под temp-image нет → попытка OTA отвечаетNot Enough Space. - Альтернатива — half-half layout
eagle.flash.1m192.ldс двумя app partitions по ~400KB. Текущая прошивка 538KB не влезает в 400KB. Урезание фичей до 400KB (CB-135) сделает «другую» плату с резко урезанным функционалом — лучше просто прошить полную версию через программатор и забыть.
Защита от brick'а¶
Если бы cloud публиковал esp01s_*.bin, и юзер по ошибке выбрал в OTA dropdown'е esp8266_*.bin (538KB firmware + 230KB FS) для ESP-01S — плата с 1MB Flash не вместит и зальёт мусор. Поэтому cloud /api/v1/firmwares?platform=esp01s возвращает пустой список — OTA-dropdown для ESP-01S всегда пуст.
Workflow для ESP-01S¶
- Один раз прошить через программатор (firmware + FS).
- Дальше плата живёт. Конфиг настраивается через API-рецепты.
- Для миграции на новую плату (или после factory-reset) — backup-фича:
GET /api/v1/backup→ файл →POST /api/v1/backupна новой плате. См. бэкап. - Когда захочется новую версию прошивки — снова через программатор.
FS-OTA (/api/v1/ota с filename .littlefs.bin) технически работал бы (FS image маленький), но cloud публикует пары firmware+FS, по отдельности не отдаёт — это не использовать.
После первой прошивки¶
ESP-01S в эфире, IP в твоей сети. Дальнейшая настройка — через REST API. Полный набор сценариев (UUID, login, пароль, cloud-binding, devices, tasks, mesh, backup) — в API-рецепты (без UI).
Краткий sanity-check:
# Login
curl -X POST http://10.x.x.x/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"1234"}'
# → {"access_token":"1:...", ...}
# Создать relay на GPIO2 (со встроенным LED, inverted=true для active-LOW)
TOK="<токен из login>"
curl -X POST http://10.x.x.x/api/v1/devices \
-H "Authorization: Bearer $TOK" \
-H 'Content-Type: application/json' \
-d '{"name":"Реле","type":"relay","pin":2,"inverted":true}'
# Привязать к облаку
curl -X POST http://10.x.x.x/api/v1/cloud \
-H "Authorization: Bearer $TOK" \
-H 'Content-Type: application/json' \
-d '{"enabled":true,"url":"https://cloud.kavlev.ru/","api_key":"<ключ из проекта>","interval_sec":30,"mqtt_enabled":true}'
UUID платы доступен через GET /api/v1/system/info — её и регистрируешь в облачном проекте.