Перейти к содержанию

412 уроков, 25 библиотек и челлендж «Что выведет код?» — бесплатно, код прямо в браузере

Начать обучение
Урок 18 из 20 Средний 15 мин 100 XP

MicroPython: Python для микроконтроллеров ESP32 и RP2040

Python, который живёт на чипе за пару долларов: интерпретатор в сотни килобайт, модуль machine для пинов и стандартная библиотека, ужатая до сути. Разбираем отличия от CPython и стиль кода под маленькую память.

Редакция Питоники

Вся таблица реализаций из урока 16 жила на компьютерах — больших или виртуальных. MicroPython спускает Python на землю, почти в буквальном смысле: интерпретатор, который помещается в сотни килобайт и живёт прямо на микроконтроллере — чипе за пару долларов. Урок про то, что остаётся от языка на чипе, чем MicroPython отличается от CPython и как выглядит код для железа.

Что такое MicroPython

MicroPython написал Дэмиен Джордж: проект собрался на Kickstarter в 2013 году и вырос в целое семейство портов. Сегодня официальный MicroPython работает на ESP32 и ESP8266, на RP2040 — чипе Raspberry Pi Pico, на платах micro:bit и линейке STM32. Интерпретатор компилируется под конкретный чип, зашивается в его флеш-память вместо прошивки, и после включения плата уже умеет исполнять Python: подача питания — и через секунды работает ваша программа.

Ключевое отличие от всего, что было в разделе раньше, — масштаб. CPython ставит на диск десятки мегабайт и живёт в гигабайтах оперативной памяти; MicroPython занимает сотни килобайт флеша и управляется килобайтами RAM. Из этого масштаба вырастает всё остальное: урезанная библиотека, свои модули для железа и особая экономия в коде.

СвойствоCPythonMicroPython
Размер интерпретатораДесятки мегабайтСотни килобайт
Память данныхГигабайты RAMКилобайты RAM
Стандартная библиотекаПолнаяПодмножество: json, math, sys и ещё десятки
Работа с железомЧерез внешние библиотекиМодуль machine: пины, ШИМ, ADC, I2C
Пакетыpip и PyPImip и заморозка в прошивку
ОбновлениеУстановка новой версииПерепрошивка устройства

Как код понимает, где он живёт

Модуль machine есть только на устройстве с прошивкой MicroPython. Отсюда переносимый способ определить среду: попытка импорта в try — на чипе она сработает, на обычном Python честно упадёт в except. Тот же приём, что с отсутствующими библиотеками в уроке про FileNotFoundError и импорты исключений:

machine есть только на микроконтроллере
try:
    import machine
    print('machine доступен: мы на микроконтроллере')
except ImportError:
    print('machine недоступен: обычный Python')
Вывод
machine недоступен: обычный Python

В песочнице и на десктопе ответ один: machine недоступен — и это правильный ответ среды о себе. На настоящей ESP32 первая ветка открылась бы, и дальше код работал бы с железом:

так выглядит работа с пином на устройстве
from machine import Pin

led = Pin(25, Pin.OUT)
led.value(1)
Пример выполняется только на устройстве с прошивкой MicroPython: в песочнице и на десктопе импорт machine упадёт с ImportError. На плате RP2040 пин 25 — встроенный светодиод.

Pin(25, Pin.OUT) объявляет пин двадцать пять выходом, а value(1) подаёт на него единицу — включённое состояние. Вся работа с железом в MicroPython построена на этом модуле: пины, ШИМ для управления яркостью и моторами, ADC для чтения аналоговых датчиков, шины I2C и SPI для внешних микросхем.

Что урезано: стандартная библиотека

Из стандартной библиотеки CPython на чипе живёт выбранное: json и math, sys и gc, time, struct и немного itertools. Тяжёлых модулей нет — никаких tkinter, multiprocessing или threading в полном виде. Есть и модули, которых в CPython не существует: у MicroPython свой sys без некоторых функций настольного Python. Проверка hasattr из урока 16 работает как зонд:

зондирование возможностей sys
import sys

print('есть implementation?', hasattr(sys, 'implementation'))
print('есть getsizeof?', hasattr(sys, 'getsizeof'))
print('есть maxsize?', hasattr(sys, 'maxsize'))
Вывод
есть implementation? True
есть getsizeof? True
есть maxsize? True

В песочнице все три ответа True: у CPython в sys есть и implementation, и getsizeof, и maxsize. На настоящем MicroPython третья строка тоже дала бы True, а вот getsizeof — измерение размера объекта в байтах — там не существует: код, который опирается на точные размеры, на чипе упадёт с AttributeError. Отсюда правило переносимости: возможности проверяются hasattr-ом, а не предполагаются.

Стиль кода под маленькую память

На чипе каждый килобайт на счету, и стиль кода меняется: кортежи вместо объектов с классами, bytes вместо str, генераторы вместо списков. Показания датчиков — пример данных, которые на настольном Python стали бы списком словарей, а на чипе живут компактным кортежем пар:

показания датчиков: компактный стиль
readings = [('temp', 21.5), ('hum', 48.0), ('press', 1013.0)]

for name, value in readings:
    print(name, '=', value)
Вывод
temp = 21.5
hum = 48.0
press = 1013.0

Заметьте: сам код — обычный Python. Распаковка пар в цикле, кортежи, печать — всё это работает и на CPython, и на MicroPython одинаково. Компактный стиль не является особым языком: это те же конструкции, применённые с экономией. Крупные словари с сотнями ключей на чипе не влезут — и правильный код заранее знает размер своих данных.

Второй приём экономии — bytes вместо строк там, где данные не текст. У bytes меньше накладных расходов, а перебирается он как последовательность чисел:

bytes дешевле строк
header = b'META'
print('bytes перебирается как числа:', [b for b in header])
Вывод
bytes перебирается как числа: [77, 69, 84, 65]

Четыре символа заголовка превратились в четыре кода: 77 — M, 69 — E, 84 — T, 65 — A. Для протоколов обмена с железом — команд, заголовков пакетов, сигнатур — bytes и есть правильный тип, и на настольном Python этот же код работает без правок.

Мигаем светодиодом логически

Каноническая первая программа на микроконтроллере — мигание светодиодом. На чипе в цикле стоит вызов machine, но каркас мигания — чистая логика переключения состояния. Вынесем логику отдельно и выполним её прямо здесь:

логика мигания без железа
led_on = False
for tick in range(6):
    led_on = not led_on
    print('тик', tick, '- светодиод', 'горит' if led_on else 'погашен')
Вывод
тик 0 - светодиод горит
тик 1 - светодиод погашен
тик 2 - светодиод горит
тик 3 - светодиод погашен
тик 4 - светодиод горит
тик 5 - светодиод погашен

Шесть тиков — шесть честных переключений. Логика на MicroPython — обычный Python: каркас циклов и словарей переносится на десктоп без правок. Чтобы превратить этот код в настоящее мигание, достаточно внутрь цикла добавить вызов led.value(1 if led_on else 0) и паузу sleep — структура программы не изменится ни на строку.

Как поставить MicroPython

  • скачать прошивку под свою плату с официального сайта micropython.org;
  • залить прошивку: для ESP32 — утилитой esptool, для RP2040 — файлом UF2, который просто переносится на диск платы;
  • открыть REPL: через Thonny или командой mpremote — питон-консоль прямо в чипе;
  • положить main.py в файловую систему устройства — он запускается при подаче питания.
работа с устройством через mpremote
mpremote cp main.py :main.py
mpremote repl
Команды терминала для машины с подключённой платой: первая копирует файл на устройство, вторая открывает REPL чипа. Утилита mpremote ставится pip-ом на обычный Python.

MicroPython доказывает: между языком и микроконтроллером — считанные сотни килобайт. Циклы, словари и функции живут на чипе, урезана только библиотека, а железо пришло своим модулем machine. Следующий урок — четыре платформенные реализации: Jython на JVM, IronPython на .NET, RustPython на Rust и Brython в браузере.

Что выведет код?

Сначала предскажи ответ в голове — это главный навык программиста.

try:
    import machine
    print('на чипе')
except ImportError:
    print('на обычном Python')
led_on = False
led_on = not led_on
led_on = not led_on
print('светодиод', 'горит' if led_on else 'погашен')
header = b'OK'
print([b for b in header])
Проверь себя
0 / 7

1. Что такое MicroPython?

2. Как обычный код узнаёт, что он работает не на чипе?

3. Чем модуль machine занимается в MicroPython?

4. Как на MicroPython ставятся библиотеки?

5. Почему для показаний датчиков на чипе берут кортежи, а не классы?

6. Что происходит с MemoryError на микроконтроллере?

7. Какая плата из перечисленных официально поддерживается MicroPython?

Карточки терминов
Запомнено: 0 / 7
Практика

Смоделируйте мигание светодиода: 4 переключения, начиная с выключенного. Печатайте строку вида тик N - вкл или тик N - выкл, где N начинается с 1.

practice.py
Вопросы и ответы по уроку

Чем MicroPython отличается от обычного Python?

Язык одинаковый, но интерпретатор ужат до сотен килобайт и живёт на микроконтроллере: стандартная библиотека — подмножество, работа с железом через модуль machine, pip и C-расширения отсутствуют, большие данные не влезают в RAM.

Урок 16: реализации Python

Какие платы поддерживают MicroPython?

Официальные порты: ESP32 и ESP8266, Raspberry Pi Pico на RP2040, micro:bit, платы STM32. Для RP2040 прошивка ставится файлом UF2 — его достаточно скопировать на появившийся диск платы.

Как написать мигание светодиодом на MicroPython?

Через machine: from machine import Pin — led = Pin(25, Pin.OUT), затем в цикле led.value(1 if led_on else 0) и пауза sleep. Логика переключения — обычный Python: её структуру можно отладить на настольном Python без железа.

Можно ли ставить pip-пакеты на MicroPython?

Обычный pip и PyPI не работают. Библиотеки ставятся через mip — он тянет только чистый Python, — а самые нужные модули вмораживаются в прошивку при её сборке. Код с C-расширениями не запустится вовсе.

Сколько памяти у MicroPython-устройства?

Порядка сотен килобайт RAM и мегабайты флеша: например, у Raspberry Pi Pico 264 килобайта RAM. Поэтому компактный стиль — кортежи, bytes, генераторы — не прихоть, а условие работы: большой список поднимает MemoryError.

Понравился урок? Сошлитесь на него

«Логика на MicroPython — обычный Python: каркас циклов и словарей переносится на десктоп без правок.»

Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.

TelegramVK

Что дальше

Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.

Похожие уроки по темам

Подобраны автоматически по пересечению тем и ключевых слов.