Подробно прошиваем ESP32 под MicroPython и CircuitPython: выбираем правильную сборку, переводим плату в режим загрузчика, используем esptool и запускаем первый скрипт.
<p>ESP32 обычно ассоциируют с Arduino IDE и C++, но для прототипов, обучения и множества IoT-задач плату можно программировать на Python. Два популярных варианта — <strong>MicroPython</strong> и <strong>CircuitPython</strong>. Оба запускают Python-код непосредственно на микроконтроллере, однако отличаются экосистемой, набором поддерживаемых плат и подходом к работе с библиотеками.</p>
<p>В этой статье разберём установку обеих прошивок на ESP32. Сначала кратко выберем среду, затем подготовим компьютер и плату, а после прошивки проверим работу светодиодом.</p>
<blockquote>
<p>Важно: прошивка стирает содержимое flash-памяти платы. Сохраните важные файлы и исходники, если на ESP32 уже есть работающий проект.</p>
</blockquote>
<h2>Что выбрать: MicroPython или CircuitPython</h2>
<table>
<thead>
<tr>
<th>Критерий</th>
<th>MicroPython</th>
<th>CircuitPython</th>
</tr>
</thead>
<tbody>
<tr>
<td>Основная цель</td>
<td>Универсальный Python для микроконтроллеров</td>
<td>Упрощённая и дружелюбная экосистема Adafruit для электроники</td>
</tr>
<tr>
<td>ESP32</td>
<td>Поддерживается широкий набор чипов и generic-плат</td>
<td>Поддерживаются только конкретные платы из списка CircuitPython</td>
</tr>
<tr>
<td>Работа с файлами</td>
<td>Обычно через REPL, <code>mpremote</code>, Thonny, rshell, WebREPL</td>
<td>Обычно накопитель <code>CIRCUITPY</code>, файл <code>code.py</code> редактируется как на флешке</td>
</tr>
<tr>
<td>Библиотеки</td>
<td><code>mip</code>, community-модули, собственный код</td>
<td>Большая коллекция библиотек Adafruit, часто с готовыми примерами</td>
</tr>
<tr>
<td>Автоперезапуск кода</td>
<td>Зависит от используемого инструмента</td>
<td>Как правило, изменения <code>code.py</code> запускаются автоматически</td>
</tr>
<tr>
<td>Когда выбирать</td>
<td>Нужны гибкость, разные ESP32-модули, сетевые/IoT-проекты</td>
<td>У вас совместимая плата и нужна максимально удобная работа с датчиками и библиотеками Adafruit</td>
</tr>
</tbody>
</table>
<p><strong>Практическое правило:</strong> для типового ESP32-WROOM DevKit, ESP32-WROVER или безымянной платы из набора чаще выбирают MicroPython. Для Adafruit Feather ESP32-S3, QT Py ESP32-S3, совместимой Waveshare-платы и других моделей, которые есть в каталоге CircuitPython, стоит рассмотреть CircuitPython.</p>
<p>Не пытайтесь ставить случайный <code>.bin</code>-файл. У ESP32 есть несколько разных семейств: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6 и другие. Прошивка для ESP32-S3 не подойдёт обычному ESP32-WROOM, а расположение образа во flash может отличаться. Всегда скачивайте firmware именно для своего чипа и платы.</p>
<h2>Что потребуется</h2>
<ul>
<li>Плата ESP32.</li>
<li>USB-кабель <strong>с передачей данных</strong>. Многие дешёвые кабели предназначены только для зарядки.</li>
<li>Компьютер с Windows, macOS или Linux.</li>
<li>Python 3 и утилита <code>esptool</code> для варианта через командную строку.</li>
<li>Подходящий файл прошивки <code>.bin</code>.</li>
<li>Терминальная программа или IDE для работы с REPL: Thonny, <code>mpremote</code>, <code>screen</code>, PuTTY, minicom и т. п.</li>
</ul>
<p>Для плат с USB-UART преобразователем важно, чтобы в системе был драйвер для используемого чипа: часто встречаются CP2102/CP2104, CH340 и CH9102. Если последовательный порт не появляется, сначала проверьте кабель и драйвер.</p>
<h2>Шаг 1. Определяем порт платы</h2>
<p>Подключите ESP32 к компьютеру. Нужен последовательный порт, через который будет передаваться прошивка.</p>
<h3>macOS</h3>
<p>В терминале выполните:</p>
<pre><code class="language-bash">ls /dev/cu.*</code></pre>
<p>Обычно порт выглядит как один из вариантов:</p>
<pre><code class="language-text">/dev/cu.usbserial-0001
/dev/cu.SLAB_USBtoUART
/dev/cu.wchusbserial...</code></pre>
<p>Удобный приём: выполните команду до подключения платы и после него — новый элемент в списке обычно и есть нужный порт.</p>
<h3>Linux</h3>
<pre><code class="language-bash">ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null</code></pre>
<p>Частые варианты: <code>/dev/ttyUSB0</code> или <code>/dev/ttyACM0</code>.</p>
<p>Если возникает <code>Permission denied</code>, добавьте пользователя в группу <code>dialout</code>, затем выйдите из сеанса и войдите снова:</p>
<pre><code class="language-bash">sudo usermod -aG dialout $USER</code></pre>
<h3>Windows</h3>
<p>Откройте «Диспетчер устройств» → «Порты (COM и LPT)». Плата может отображаться, например, как <code>USB-SERIAL CH340 (COM5)</code> или <code>Silicon Labs CP210x USB to UART Bridge (COM7)</code>.</p>
<h2>Шаг 2. Устанавливаем esptool</h2>
<p><code>esptool</code> — официальная консольная утилита Espressif для работы с flash-памятью чипов ESP. Она умеет определять чип, стирать flash и записывать firmware.</p>
<p>Подробная установка для Windows, macOS и Linux вынесена в отдельную статью: <a href="/ustanovka-esptool-esp32/">Как установить и проверить esptool для ESP32</a>.</p>
<p>Быстрый вариант для уже установленного Python:</p>
<pre><code class="language-bash">python -m pip install --upgrade esptool</code></pre>
<p>Проверьте, что утилита доступна:</p>
<pre><code class="language-bash">python -m esptool version</code></pre>
<p>Использование формы <code>python -m esptool</code> удобно: она не зависит от того, добавлена ли папка Python Scripts в системный <code>PATH</code>.</p>
<h2>Шаг 3. Переводим ESP32 в режим загрузчика</h2>
<p>У многих DevKit-плат есть две кнопки:</p>
<ul>
<li><strong>BOOT</strong> или <strong>IO0</strong> — удерживает GPIO0 в низком уровне и включает режим загрузки;</li>
<li><strong>EN</strong>, <strong>RST</strong> или <strong>RESET</strong> — перезапускает чип.</li>
</ul>
<p>Если запись не стартует автоматически:</p>
<ol type="1">
<li>Нажмите и удерживайте <strong>BOOT</strong>.</li>
<li>Нажмите и отпустите <strong>EN/RESET</strong>.</li>
<li>Отпустите <strong>BOOT</strong>.</li>
<li>Повторите команду прошивки.</li>
</ol>
<p>На части плат автоматический сброс работает сам. Если в терминале появляется <code>Connecting...</code> и процесс стоит на месте, ручной вход в bootloader обычно решает проблему.</p>
<h2>Шаг 4. Прошиваем MicroPython</h2>
<h3>Скачиваем правильную сборку</h3>
<p>Откройте официальный каталог загрузок MicroPython и выберите конкретную плату или семейство чипа. Для распространённого ESP32-WROOM обычно подходит сборка <strong>ESP32_GENERIC</strong>. Для ESP32-S3 нужна отдельная <strong>ESP32_GENERIC_S3</strong>, а для ESP32-C3 — сборка для C3.</p>
<p>Выбирайте стабильный релиз для обычной работы. Daily/preview-сборка может содержать новые возможности, но подходит скорее для тестирования.</p>
<p>Сохраните файл, например, как:</p>
<pre><code class="language-text">ESP32_GENERIC-2026xxxx-v1.xx.x.bin</code></pre>
<h3>Проверяем соединение с чипом</h3>
<p>Замените порт на свой:</p>
<pre><code class="language-bash">python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 chip_id</code></pre>
<p>Для Windows пример будет таким:</p>
<pre><code class="language-powershell">python -m esptool --chip esp32 --port COM5 chip_id</code></pre>
<p>Если команда выводит информацию о чипе и MAC-адресе, связь установлена.</p>
<h3>Стираем flash</h3>
<p>Для первой установки или при переходе с Arduino/CircuitPython рекомендуется полностью очистить память:</p>
<pre><code class="language-bash">python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 erase_flash</code></pre>
<h3>Записываем MicroPython</h3>
<p>Для обычного ESP32 образ обычно записывают с адреса <code>0x1000</code>:</p>
<pre><code class="language-bash">python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 --baud 460800 write_flash -z 0x1000 ESP32_GENERIC-2026xxxx-v1.xx.x.bin</code></pre>
<p>Если на высокой скорости появляются ошибки, снизьте скорость до 115200:</p>
<pre><code class="language-bash">python -m esptool --chip esp32 --port /dev/cu.usbserial-0001 --baud 115200 write_flash -z 0x1000 ESP32_GENERIC-2026xxxx-v1.xx.x.bin</code></pre>
<blockquote>
<p>Для ESP32-S3 и некоторых других вариантов точка записи может быть <code>0x0</code>, а не <code>0x1000</code>. Не копируйте команду вслепую: смотрите инструкцию именно на странице скачанной прошивки MicroPython.</p>
</blockquote>
<p>После сообщения <code>Hash of data verified</code> нажмите кнопку RESET или переподключите плату.</p>
<h2>Шаг 5. Проверяем MicroPython через REPL</h2>
<p>REPL — интерактивная Python-консоль микроконтроллера. Самый удобный современный вариант — <code>mpremote</code>.</p>
<p>Установите его:</p>
<pre><code class="language-bash">python -m pip install --upgrade mpremote</code></pre>
<p>Подключитесь к плате:</p>
<pre><code class="language-bash">mpremote connect /dev/cu.usbserial-0001 repl</code></pre>
<p>В Windows:</p>
<pre><code class="language-powershell">mpremote connect COM5 repl</code></pre>
<p>После перезапуска ESP32 в терминале должно появиться приглашение <code>>>></code>. Выполните:</p>
<pre><code class="language-python">import sys
print(sys.implementation)</code></pre>
<p>Если вывод содержит <code>micropython</code>, прошивка работает.</p>
<h3>Первый пример: мигание светодиодом</h3>
<p>На многих ESP32 DevKit встроенный светодиод подключён к GPIO2, но это не универсальное правило. Если пример не мигает, проверьте схему своей платы и измените номер GPIO.</p>
<p>В REPL:</p>
<pre><code class="language-python">from machine import Pin
from time import sleep
led = Pin(2, Pin.OUT)
while True:
led.value(not led.value())
sleep(0.5)</code></pre>
<p>Остановить бесконечный цикл можно сочетанием <code>Ctrl+C</code> в терминале.</p>
<p>Чтобы перенести скрипт на плату, сохраните его локально под именем <code>main.py</code> и выполните:</p>
<pre><code class="language-bash">mpremote connect /dev/cu.usbserial-0001 fs cp main.py :main.py</code></pre>
<p>Файл <code>main.py</code> запускается при старте MicroPython. Для более глубокого разбора структуры файловой системы и работы с <code>mpremote</code> можно подготовить отдельную статью: <a href="/micropython-esp32-mpremote-fayly/">Как загрузить файлы и запустить проект в MicroPython на ESP32</a>.</p>
<h2>Шаг 6. Прошиваем CircuitPython</h2>
<p>CircuitPython доступен не для абстрактного «любого ESP32», а для определённых плат. Поэтому сначала откройте каталог загрузок CircuitPython и найдите <strong>точное название платы</strong>, напечатанное на текстолите или указанное в документации производителя.</p>
<p>Если ваша generic-плата отсутствует в списке, используйте MicroPython либо собирайте CircuitPython из исходников для своей аппаратной конфигурации. Не следует прошивать образ от похожей, но другой платы: разводка flash, PSRAM, USB и пинов может отличаться.</p>
<h3>Вариант A: Web Serial Installer</h3>
<p>Для совместимой платы самый простой вариант — официальный веб-установщик CircuitPython. Он требует браузер на Chromium с поддержкой Web Serial (например, Chrome или Edge) и прямого USB-подключения платы.</p>
<p>Общий порядок:</p>
<ol type="1">
<li>Откройте страницу загрузки нужной платы в CircuitPython.</li>
<li>Выберите вариант установки через Web Serial, если он доступен.</li>
<li>Подключите плату и выберите её последовательный порт.</li>
<li>При необходимости удерживайте BOOT и нажмите RESET, чтобы войти в режим загрузчика.</li>
<li>Дождитесь окончания записи и перезапуска.</li>
</ol>
<h3>Вариант B: esptool</h3>
<p>Если используете <code>.bin</code>-образ и командную строку, действуйте так:</p>
<ol type="1">
<li>Скачайте файл firmware для точной модели платы.</li>
<li>Переведите плату в bootloader.</li>
<li>При необходимости очистите flash.</li>
<li>Запишите образ по адресу, указанному на странице этой платы.</li>
</ol>
<p>Типовая структура команды выглядит так:</p>
<pre><code class="language-bash">python -m esptool --chip <chip> --port <port> --baud 460800 write_flash -z <offset> <firmware.bin></code></pre>
<p>Пример с условными значениями:</p>
<pre><code class="language-bash">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</code></pre>
<p>Здесь нельзя обещать единый <code>chip</code> и единый <code>offset</code>: они зависят от платы и формата конкретного образа. Копируйте параметры из инструкции к вашей модели на странице CircuitPython Downloads или из документации её производителя.</p>
<h2>Шаг 7. Проверяем CircuitPython</h2>
<p>После успешной установки совместимая плата обычно появляется в файловом менеджере как USB-накопитель <strong>CIRCUITPY</strong>. В его корне находится файл <code>code.py</code>.</p>
<p>Откройте <code>code.py</code> в редакторе и вставьте пример:</p>
<pre><code class="language-python">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)</code></pre>
<p>Сохраните файл. CircuitPython должен автоматически перезагрузить пользовательский код, и встроенный светодиод начнёт мигать. Символ <code>board.LED</code> предпочтительнее жёсткого номера GPIO: он использует описание конкретной поддерживаемой платы.</p>
<p>Если накопитель CIRCUITPY не появился:</p>
<ul>
<li>убедитесь, что плата действительно поддерживается CircuitPython;</li>
<li>используйте USB-кабель с линиями данных;</li>
<li>проверьте, завершилась ли прошивка без ошибок;</li>
<li>попробуйте переподключение, RESET и ручной режим BOOT;</li>
<li>внимательно сверьте выбранный <code>.bin</code> с моделью платы.</li>
</ul>
<h2>Типичные ошибки при прошивке</h2>
<h3><code>Failed to connect</code> или бесконечное <code>Connecting...</code></h3>
<p>Плата не вошла в загрузчик либо выбран неправильный порт. Удерживайте BOOT, кратко нажмите RESET и повторите команду. Также попробуйте другой USB-кабель и USB-порт.</p>
<h3><code>No serial data received</code></h3>
<p>Часто причиной становятся кабель без передачи данных, плохой контакт, неверный COM-порт или конфликт с программой, которая уже открыла порт. Закройте IDE и терминалы, затем повторите проверку через <code>chip_id</code>.</p>
<h3><code>Permission denied</code> в Linux</h3>
<p>Добавьте пользователя в <code>dialout</code>, перелогиньтесь и убедитесь, что обращаетесь к существующему <code>/dev/ttyUSB*</code> или <code>/dev/ttyACM*</code>.</p>
<h3><code>esptool</code> не найден</h3>
<p>Используйте запуск через Python:</p>
<pre><code class="language-bash">python -m esptool version</code></pre>
<p>Если и это не работает, проверьте установку Python и повторно установите пакет. Полный разбор есть в статье <a href="/ustanovka-esptool-esp32/">Установка esptool для ESP32</a>.</p>
<h3>После MicroPython нет <code>CIRCUITPY</code></h3>
<p>Это нормально. <code>CIRCUITPY</code> — типичный способ работы CircuitPython. В MicroPython файлы обычно передают отдельной утилитой, например <code>mpremote</code>, или через IDE Thonny.</p>
<h2>Итог</h2>
<p>MicroPython и CircuitPython позволяют быстро превратить ESP32 в Python-устройство для датчиков, реле, дисплеев, Wi-Fi и MQTT. Для обычной DevKit-платы и универсальных IoT-задач начните с MicroPython. Если у вас есть официально поддерживаемая плата CircuitPython и вы хотите редактировать <code>code.py</code> прямо на USB-диске, выбирайте CircuitPython.</p>
<p>После успешной прошивки следующий логичный шаг — подключить датчик, настроить Wi-Fi или отправить данные в MQTT-брокер. А фундаментальный инструмент для переустановки firmware — <code>esptool</code> — подробно разобран в следующем материале.</p>
<p><strong>Читайте также:</strong></p>
<ul>
<li><a href="/ustanovka-esptool-esp32/">Как установить esptool и прошить ESP32 из терминала</a></li>
<li><a href="/micropython-esp32-mpremote-fayly/">MicroPython на ESP32: работа с файлами через mpremote</a></li>
<li><a href="/esp32-micropython-wifi/">Первый проект на ESP32: подключаемся к Wi-Fi в MicroPython</a></li>
<li><a href="/esp32-pinout-strapping-pins/">ESP32: распиновка и опасные загрузочные GPIO</a></li>
</ul>