Как прошить ESP32: MicroPython или CircuitPython — полное руководство

Как прошить ESP32: MicroPython или CircuitPython — полное руководство

Подробно разбираем прошивку ESP32 под MicroPython и CircuitPython: выбираем правильную сборку, переводим плату в режим загрузчика, используем esptool и запускаем первый скрипт.

ESP32 обычно ассоциируют с Arduino IDE и C++, но для прототипов, обучения и множества IoT-задач плату можно программировать на Python. Два популярных варианта — MicroPython и CircuitPython. Оба запускают Python-код непосредственно на микроконтроллере, однако отличаются экосистемой, набором поддерживаемых плат и подходом к работе с библиотеками.

В этой статье разберём установку обеих прошивок на ESP32. Сначала кратко выберем среду, затем подготовим компьютер и плату, а после прошивки проверим работу светодиодом.

Важно: прошивка стирает содержимое flash-памяти платы. Сохраните важные файлы и исходники, если на ESP32 уже есть работающий проект.

Что выбрать: MicroPython или CircuitPython

КритерийMicroPythonCircuitPython
Основная цельУниверсальный Python для микроконтроллеровУпрощённая и дружелюбная экосистема Adafruit для электроники
ESP32Поддерживается широкий набор чипов и generic-платПоддерживаются только конкретные платы из списка CircuitPython
Работа с файламиОбычно через REPL, mpremote, Thonny, rshell, WebREPLОбычно накопитель CIRCUITPY, файл code.py редактируется как на флешке
Библиотекиmip, community-модули, собственный кодБольшая коллекция библиотек Adafruit, часто с готовыми примерами
Автоперезапуск кодаЗависит от используемого инструментаКак правило, изменения code.py запускаются автоматически
Когда выбиратьНужны гибкость, разные ESP32-модули, сетевые/IoT-проектыУ вас совместимая плата и нужна максимально удобная работа с датчиками и библиотеками Adafruit

Практическое правило: для типового ESP32-WROOM DevKit, ESP32-WROVER или безымянной платы из набора чаще выбирают MicroPython. Для Adafruit Feather ESP32-S3, QT Py ESP32-S3, совместимой Waveshare-платы и других моделей, которые есть в каталоге CircuitPython, стоит рассмотреть CircuitPython.

Не пытайтесь ставить случайный .bin-файл. У ESP32 есть несколько разных семейств: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 и другие. Прошивка для ESP32-S3 не подойдёт обычному ESP32-WROOM, а расположение образа во flash может отличаться. Всегда скачивайте firmware именно для своего чипа и платы.

Что потребуется

  • Плата ESP32.
  • USB-кабель с передачей данных. Многие дешёвые кабели предназначены только для зарядки.
  • Компьютер с Windows, macOS или Linux.
  • Python 3 и утилита esptool для варианта через командную строку.
  • Подходящий файл прошивки .bin.
  • Терминальная программа или IDE для работы с REPL: Thonny, mpremote, screen, PuTTY, minicom и т. п.

Для плат с USB-UART преобразователем важно, чтобы в системе был драйвер для используемого чипа: часто встречаются CP2102/CP2104, CH340 и CH9102. Если последовательный порт не появляется, сначала проверьте кабель и драйвер.

Шаг 1. Определяем порт платы

Подключите ESP32 к компьютеру. Нужен последовательный порт, через который будет передаваться прошивка.

macOS

В терминале выполните:

ls /dev/cu.*

Обычно порт выглядит как один из вариантов:

/dev/cu.usbserial-0001
/dev/cu.SLAB_USBtoUART
/dev/cu.wchusbserial...

Удобный приём: выполните команду до подключения платы и после него — новый элемент в списке обычно и есть нужный порт.

Linux

ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null

Частые варианты: /dev/ttyUSB0 или /dev/ttyACM0.

Если возникает Permission denied, добавьте пользователя в группу dialout, затем выйдите из сеанса и войдите снова:

sudo usermod -aG dialout $USER

Windows

Откройте «Диспетчер устройств» → «Порты (COM и LPT)». Плата может отображаться, например, как USB-SERIAL CH340 (COM5) или Silicon Labs CP210x USB to UART Bridge (COM7).

Шаг 2. Устанавливаем esptool

esptool — официальная консольная утилита Espressif для работы с flash-памятью чипов ESP. Она умеет определять чип, стирать flash и записывать firmware.

Подробная установка для Windows, macOS и Linux вынесена в отдельную статью: .

Быстрый вариант для уже установленного Python:

python -m pip install --upgrade esptool

Проверьте, что утилита доступна:

python -m esptool version

Использование формы python -m esptool удобно: она не зависит от того, добавлена ли папка Python Scripts в системный PATH.

Шаг 3. Переводим ESP32 в режим загрузчика

У многих DevKit-плат есть две кнопки:

  • BOOT или IO0 — удерживает GPIO0 в низком уровне и включает режим загрузки;
  • EN, RST или RESET — перезапускает чип.

Если запись не стартует автоматически:

  1. Нажмите и удерживайте BOOT.
  2. Нажмите и отпустите EN/RESET.
  3. Отпустите BOOT.
  4. Повторите команду прошивки.

На части плат автоматический сброс работает сам. Если в терминале появляется Connecting... и процесс стоит на месте, ручной вход в bootloader обычно решает проблему.

Шаг 4. Прошиваем MicroPython

Скачиваем правильную сборку

Откройте официальный каталог загрузок MicroPython и выберите конкретную плату или семейство чипа. Для распространённого ESP32-WROOM обычно подходит сборка ESP32_GENERIC. Для ESP32-S3 нужна отдельная ESP32_GENERIC_S3, а для ESP32-C3 — сборка для C3.

Выбирайте стабильный релиз для обычной работы. Daily/preview-сборка может содержать новые возможности, но подходит скорее для тестирования.

Сохраните файл, например, как:

ESP32_GENERIC-2026xxxx-v1.xx.x.bin

Проверяем соединение с чипом

Замените порт на свой:

python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 chip_id

Для Windows пример будет таким:

python -m esptool --chip esp32 --port COM5 chip_id

Если команда выводит информацию о чипе и MAC-адресе, связь установлена.

Стираем flash

Для первой установки или при переходе с Arduino/CircuitPython рекомендуется полностью очистить память:

python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 erase_flash

Записываем MicroPython

Для обычного ESP32 образ обычно записывают с адреса 0x1000:

python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-2026xxxx-v1.xx.x.bin

Если на высокой скорости появляются ошибки, снизьте скорость до 115200:

python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 --baud 115200 write_flash -z 0x1000 ESP32_GENERIC-2026xxxx-v1.xx.x.bin

Для ESP32-S3 и некоторых других вариантов точка записи может быть 0x0, а не 0x1000. Не копируйте команду вслепую: смотрите инструкцию именно на странице скачанной прошивки MicroPython.

После сообщения Hash of data verified нажмите кнопку RESET или переподключите плату.

Шаг 5. Проверяем MicroPython через REPL

REPL — интерактивная Python-консоль микроконтроллера. Самый удобный современный вариант — mpremote.

Установите его:

python -m pip install --upgrade mpremote

Подключитесь к плате:

mpremote connect /dev/cu.usbserial-0001 repl

В Windows:

mpremote connect COM5 repl

После перезапуска ESP32 в терминале должно появиться приглашение >>>. Выполните:

import sys
print(sys.implementation)

Если вывод содержит micropython, прошивка работает.

Первый пример: мигание светодиодом

На многих ESP32 DevKit встроенный светодиод подключён к GPIO2, но это не универсальное правило. Если пример не мигает, проверьте схему своей платы и измените номер GPIO.

В REPL:

from machine import Pin
from time import sleep

led = Pin(2, Pin.OUT)

while True:
    led.value(not led.value())
    sleep(0.5)

Остановить бесконечный цикл можно сочетанием Ctrl+C в терминале.

Чтобы перенести скрипт на плату, сохраните его локально под именем main.py и выполните:

mpremote connect /dev/cu.usbserial-0001 fs cp main.py :main.py

Файл main.py запускается при старте MicroPython. Для более глубокого разбора структуры файловой системы и работы с mpremote можно подготовить отдельную статью: .

Шаг 6. Прошиваем CircuitPython

CircuitPython доступен не для абстрактного «любого ESP32», а для определённых плат. Поэтому сначала откройте каталог загрузок CircuitPython и найдите точное название платы, напечатанное на текстолите или указанное в документации производителя.

Если ваша generic-плата отсутствует в списке, используйте MicroPython либо собирайте CircuitPython из исходников для своей аппаратной конфигурации. Не следует прошивать образ от похожей, но другой платы: разводка flash, PSRAM, USB и пинов может отличаться.

Вариант A: Web Serial Installer

Для совместимой платы самый простой вариант — официальный веб-установщик CircuitPython. Он требует браузер на Chromium с поддержкой Web Serial (например, Chrome или Edge) и прямого USB-подключения платы.

Общий порядок:

  1. Откройте страницу загрузки нужной платы в CircuitPython.
  2. Выберите вариант установки через Web Serial, если он доступен.
  3. Подключите плату и выберите её последовательный порт.
  4. При необходимости удерживайте BOOT и нажмите RESET, чтобы войти в режим загрузчика.
  5. Дождитесь окончания записи и перезапуска.

Вариант B: esptool

Если используете .bin-образ и командную строку, действуйте так:

  1. Скачайте файл firmware для точной модели платы.
  2. Переведите плату в bootloader.
  3. При необходимости очистите flash.
  4. Запишите образ по адресу, указанному на странице этой платы.

Типовая структура команды выглядит так:

python -m esptool --chip <chip> --port <port> --baud 460800 write_flash -z <offset> <firmware.bin>

Пример с условными значениями:

python -m esptool --chip esp32s3 --port /dev/cu.usbserial-0001 --baud 460800 write_flash -z 0x0 adafruit-circuitpython-boardname-en_US-10.x.x.bin

Здесь нельзя обещать единый chip и единый offset: они зависят от платы и формата конкретного образа. Копируйте параметры из инструкции к вашей модели на странице CircuitPython Downloads или из документации её производителя.

Шаг 7. Проверяем CircuitPython

После успешной установки совместимая плата обычно появляется в файловом менеджере как USB-накопитель CIRCUITPY. В его корне находится файл code.py.

Откройте code.py в редакторе и вставьте пример:

import time
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

while True:
    led.value = not led.value
    time.sleep(0.5)

Сохраните файл. CircuitPython должен автоматически перезагрузить пользовательский код, и встроенный светодиод начнёт мигать. Символ board.LED предпочтительнее жёсткого номера GPIO: он использует описание конкретной поддерживаемой платы.

Если накопитель CIRCUITPY не появился:

  • убедитесь, что плата действительно поддерживается CircuitPython;
  • используйте USB-кабель с линиями данных;
  • проверьте, завершилась ли прошивка без ошибок;
  • попробуйте переподключение, RESET и ручной режим BOOT;
  • внимательно сверьте выбранный .bin с моделью платы.

Типичные ошибки при прошивке

Failed to connect или бесконечное Connecting...

Плата не вошла в загрузчик либо выбран неправильный порт. Удерживайте BOOT, кратко нажмите RESET и повторите команду. Также попробуйте другой USB-кабель и USB-порт.

No serial data received

Часто причиной становятся кабель без передачи данных, плохой контакт, неверный COM-порт или конфликт с программой, которая уже открыла порт. Закройте IDE и терминалы, затем повторите проверку через chip_id.

Permission denied в Linux

Добавьте пользователя в dialout, перелогиньтесь и убедитесь, что обращаетесь к существующему /dev/ttyUSB* или /dev/ttyACM*.

esptool не найден

Используйте запуск через Python:

python -m esptool version

Если и это не работает, проверьте установку Python и повторно установите пакет. Полный разбор есть в статье 

После MicroPython нет CIRCUITPY

Это нормально. CIRCUITPY — типичный способ работы CircuitPython. В MicroPython файлы обычно передают отдельной утилитой, например mpremote, или через IDE Thonny.

Итог

MicroPython и CircuitPython позволяют быстро превратить ESP32 в Python-устройство для датчиков, реле, дисплеев, Wi-Fi и MQTT. Для обычной DevKit-платы и универсальных IoT-задач начните с MicroPython. Если у вас есть официально поддерживаемая плата CircuitPython и вы хотите редактировать code.py прямо на USB-диске, выбирайте CircuitPython.

После успешной прошивки следующий логичный шаг — подключить датчик, настроить Wi-Fi или отправить данные в MQTT-брокер. А фундаментальный инструмент для переустановки firmware — esptool — подробно разобран в следующем материале.