Skip to content

Прошивка через программатор

Обычные 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-чип. Это требует:

  1. Питание 3.3V на ESP (VCC + EN/CH_PD).
  2. Общий GND между ESP и программатором.
  3. TX программатора → RX ESP, RX программатора → TX ESP (cross).
  4. 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:

pio run -e esp01s -t upload --upload-port /dev/ttyUSB0

Прогресс должен идти от 0% до 100% за ~30–45 секунд. После Hash of data verified плата делает soft-reset.

4. Залить FS

ESP-01S вышла из bootmode после reset → передёрни USB (с перемычкой GPIO0 на месте) для повторного входа в bootmode:

pio run -e esp01s -t uploadfs --upload-port /dev/ttyUSB0

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'ится):

pio device monitor -e esp01s --baud 74880
# нажать reset, увидеть banner

Расшифровка 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.

После прошивки:

  1. Сними перемычку GPIO0→GND на ESP-01S.
  2. Сними перемычку EN→GND на NodeMCU (чтобы её ESP-чип ожил, если хочешь использовать NodeMCU дальше).
  3. Передёрни 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

  1. Один раз прошить через программатор (firmware + FS).
  2. Дальше плата живёт. Конфиг настраивается через API-рецепты.
  3. Для миграции на новую плату (или после factory-reset) — backup-фича: GET /api/v1/backup → файл → POST /api/v1/backup на новой плате. См. бэкап.
  4. Когда захочется новую версию прошивки — снова через программатор.

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 — её и регистрируешь в облачном проекте.