Python для микроконтроллеров. Учимся программировать одноплатные компьютеры на языке высокого уровня

Шутники говорят, что после трудового дня за компьютером типичный программист едет домой, садится за ПК и таким образом отдыхает. А ведь истина на самом деле куда ужаснее этой шутки: многие из нас, приходя с работы, посвящают оставшееся до сна время... программированию микроконтроллеров. 🙂 Обывателям не понять, но Arduino, Teensy или ESP — действительно очень неплохое хобби. Их единственный недостаток — необходимость программировать на достаточно низком уровне, если не на Assembler, то на Arduino C или Lua. Но теперь в списке ЯП для микроконтроллеров появился Python. Точнее, MicroPython. В этой статье я постараюсь максимально продемонстрировать его возможности.

С чего все началось?

Все началось с кампании на Kickstarter. Дэмьен Джордж (Damien George), разработчик из Англии, спроектировал микроконтроллерную плату, предназначенную специально для Python. И кампания «выстрелила». Изначально была заявлена сумма в 15 тысяч фунтов стерлингов, но в результате было собрано в шесть с половиной раз больше — 97 803 фунта стерлингов.

А чем эта плата лучше?

Автор проекта приводил целый ряд преимуществ своей платформы в сравнении с Raspberry Pi и Arduino:

  • Мощность — MP мощнее в сравнении с микроконтроллером Arduino, здесь используются 32-разрядные ARM-процессоры типа STM32F405 (168 МГц Cortex-M4, 1 Мбайт флеш-памяти, 192 Кбайт ОЗУ).

  • Простота в использовании — язык MicroPython основан на Python, но несколько упрощен, для того чтобы команды по управлению датчиками и моторами можно было писать буквально в несколько строк.

  • Отсутствие компилятора — чтобы запустить программу на платформе MicroPython, нет необходимости устанавливать на компьютер дополнительное ПО. Плата определяется ПК как обычный USB-накопитель — стоит закинуть на него текстовый файл с кодом и перезагрузить, программа тут же начнет исполняться. Для удобства все-таки можно установить на ПК эмулятор терминала, который дает возможность вписывать элементы кода с компьютера непосредственно на платформу. Если использовать его, тебе даже не придется перезагружать плату для проверки программы, каждая строка будет тут же исполняться микроконтроллером.

  • Низкая стоимость — в сравнении с Raspberry Pi платформа PyBoard несколько дешевле и, как следствие, доступнее.

  • Открытая платформа — так же как и Arduino, PyBoard — открытая платформа, все схемы будут находиться в открытом доступе, что подразумевает возможность спроектировать и создать подобную плату самому в зависимости от потребностей.

И что, только официальная плата?

Нет. При всех своих достоинствах PyBoard (так называется плата от разработчика MicroPython) — довольно дорогое удовольствие. Но благодаря открытой платформе на многих популярных платах уже можно запустить MicroPython, собранный специально для нее. В данный момент существуют версии:

  • для BBC micro:bit — британская разработка, позиционируется как официальное учебное пособие для уроков информатики;
  • Circuit Playground Express — разработка известной компании Adafruit. Это плата, включающая в себя светодиоды, датчики, пины и кнопки. По умолчанию программируется с помощью Microsoft MakeCode for Adafruit. Это блочный (похожий на Scratch) редактор «кода»;
  • ESP8266/ESP32 — одна из самых популярных плат для IoT-разработки. Ее можно было программировать на Arduino C и Lua. А сегодня мы попробуем установить на нее MicroPython.
Плата ESP8266

Подготовка к работе

Перед тем как писать программы, нужно настроить плату, установить на нее прошивку, а также установить на компьютер необходимые программы.

INFO

Все примеры проверялись и тестировались на следующем оборудовании:

  • плата NodeMCU ESP8266-12E;
  • драйвер моторов L293D;
  • I2C-дисплей 0,96″ 128 × 64;
  • Adafruit NeoPixel Ring 16.

Прошивка контроллера

Для прошивки платы нам понадобится Python. Точнее, даже не он сам, а утилита esptool, распространяемая с помощью pip. Если у тебя установлен Python (неважно, какой версии), открой терминал (командную строку) и набери:

pip install esptool

После установки esptool надо сделать две вещи. Первое — скачать с официального сайта версию прошивки для ESP8266. И второе — определить адрес платы при подключении к компьютеру. Самый простой способ — подключиться к компьютеру, открыть Arduino IDE и посмотреть адрес в списке портов.

Для облегчения восприятия адрес платы в примере будет /dev/ttyUSB0, а файл прошивки переименован в esp8266.bin и лежит на рабочем столе.

Открываем терминал (командную строку) и переходим на рабочий стол:

cd Desktop

Форматируем флеш-память платы:

esptool.py --port /dev/ttyUSB0 erase_flash 

Если при форматировании возникли ошибки, значит, нужно включить режим прошивки вручную. Зажимаем на плате кнопки reset и flash. Затем отпускаем reset и, не отпуская flash, пытаемся отформатироваться еще раз.

И загружаем прошивку на плату:

esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 esp8266.bin

Взаимодействие с платой

Все взаимодействие с платой может происходить несколькими способами:

  • через Serial-порт;
  • через web-интерпретатор.

При подключении через Serial-порт пользователь в своем терминале (в своей командной строке) видит практически обычный интерпретатор Python.

Подключение через SerialPort

Для подключения по Serial есть разные программы. Для Windows можно использовать PuTTY или TeraTerm. Для Linux — picocom или minicom. В качестве кросс-платформенного решения можно использовать монитор порта Arduino IDE. Главное — правильно определить порт и указать скорость передачи данных 115200.

picocom /dev/ttyUSB0 -b115200

Кроме этого, уже создано и выложено на GitHub несколько программ, облегчающих разработку, например EsPy. Кроме Serial-порта, он включает в себя редактор Python-файлов с подсветкой синтаксиса, а также файловый менеджер, позволяющий скачивать и загружать файлы на ESP.

EsPy IDE

Но все перечисленные способы хороши лишь тогда, когда у нас есть возможность напрямую подключиться к устройству с помощью кабеля. Но плата может быть интегрирована в какое-либо устройство, и разбирать его только для того, чтобы обновить программу, как-то неоптимально. Наверное, именно для таких случаев и был создан WebREPL. Это способ взаимодействия с платой через браузер с любого устройства, находящегося в той же локальной сети, если у платы нет статического IP, и с любого компьютера, если такой IP присутствует. Давай настроим WebREPL. Для этого необходимо, подключившись к плате, набрать

import webrepl_setup

Появится сообщение о статусе автозапуска WebREPL и вопрос, включить или выключить его автозапуск.

WebREPL daemon auto-start status: enabled

Would you like to (E)nable or (D)isable it running on boot?
(Empty line to quit)
>

После ввода q появляется сообщение о выставлении пароля доступа:

To enable WebREPL, you must set password for it
New password (4-9 chars):   

Вводим его, а затем подтверждаем. Теперь после перезагрузки мы сможем подключиться к плате по Wi-Fi.

Так как мы не настроили подключение платы к Wi-Fi-сети, она работает в качестве точки доступа. Имя Wi-Fi-сeти — MicroPython-******, где звездочками я заменил часть MAC-адреса. Подключаемся к ней (пароль — micropythoN).

Открываем WebREPL и нажимаем на Connect. После ввода пароля мы попадаем в тот же интерфейс, что и при прямом подключении. Кроме этого, в WebREPL есть интерфейс для загрузки файлов на плату и скачивания файлов на компьютер.

WebRERL

INFO

Среди файлов, загруженных на плату, есть стандартные:

  • boot.py — скрипт, который загружается первым при включении платы. Обычно в него вставляют функции для инициализации модулей, подключения к Wi-Fi и запуска WebREPL;
  • main.py — основной скрипт, который запускается сразу после выполнения boot.py, в него записывается основная программа.

Начинаем разработку

Hello world

Принято, что первой написанной на новом языке программирования должна быть программа, выводящая Hello world. Не будем отходить от традиции и выведем это сообщение с помощью азбуки Морзе.

import machine
import time

pin = machine.Pin(2,machine.Pin.OUT)

def dot_show():
    pin.off()
    time.sleep(1)
    pin.on()

def dash_show():
    pin.off()
    time.sleep(2)
    pin.on()

Hello_world = '**** * *-** *-** ---    *-- --- *-* *-** -**'

for i in Hello_world:
    if i=="*":
        dot_show()
    elif i=='-':
        dash_show()
    else:
        time.sleep(3)
    time.sleep(0.5)

Итак, что же происходит? Сначала подключаются библиотеки: стандартная Python-библиотека time и специализированная machine. Эта библиотека отвечает за взаимодействие с GPIO. Стандартный встроенный светодиод располагается на втором пине. Подключаем его и указываем, что он работает на выход. Если бы у нас был подключен какой-нибудь датчик, то мы бы указали режим работы IN.

Следующие две функции отвечают за включение и выключение светодиода на определенный интервал времени. Наверное, интересно, почему я сначала выключаю светодиод, а потом включаю? Мне тоже очень интересно, почему сигнал для данного светодиода инвертирован... Оставим это на совести китайских сборщиков. На самом деле команда pin.off() включает светодиод, а pin.on() — отключает.

Ну а дальше все просто: заносим в переменную Hello_world нашу строчку, записанную кодом Морзе, и, пробегаясь по ней, вызываем ту или иную функцию.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


Комментарии (3)

  • В первом листинге ошибка - вызов функции dash_show() без скобок.

  • Ого! Теперь еще больше мотивации выучить Python...

Похожие материалы