Возможно, вы заметили по моим статьям, я большой фанат контроллера ESP32, а одним из его достоинств является огромное количество плат на его основе. А благодаря своей популярности, он всё больше и больше попадает в образовательное пространство STEM.
В прошлом году я не удержался и заказал плату Magicbit, разработчики которой позиционировали её как образовательную. Давайте посмотрим, что она из себя представляет.
Внешний вид
Сама по себе плата выполнена в очень оригинальном форм-факторе - это правильный шестиугольник, который с учётом жёлто-горчичного цвета очень напоминает соты. На самой плате расположены:
Сам контроллер ESP32
Четыре светодиода: синий, зелёный, жёлтый и красный
Коннекторы и расширения для внешних модулей
Драйвер моторов
OLED дисплей
Две кнопки
Потенциометр
Зуммер
Коннектор для подключения батарейного или аккумуляторного блока
Порт MicroUSB для программирования (непонятно, почему не перейти на Type-C)
А кроме этого, в той конфигурации, что я заказал, в комплекте идут дополнительные модули и датчики. С частью из них мы познакомимся.
На первый, да и на второй взгляд, даже базовой комплектации хватит что бы сделать множество обучающих проектов. Кстати, разработчики в описании упоминают "50+ проектов", которые можно сделать. А кроме этого, есть возможность докупить специальную колёсную платформу MagicBot, чтобы сделать собственного робота.
Кодинг
Теперь давайте посмотрим, с помощью чего это устройство можно программировать. Раз всё базируется на ESP32 - то все дефолтные способы, такие как Arduino, Micropython и т.д. - очевидны. Что же предлагают нам разработчики кроме этого:
Scratch, а точнее, чем-то похожий на него MagicCode, можно скачать, но только на Windows, а можно работать через браузер
Magicblocks - блочная среда разработки, основанная на проекте Node-RED, для создания умного дома
Micropython
Начнём с того, что создатели этой платформы сделали достаточно неплохую документацию. Для каждого из способов программирования - отдельные уроки(например, для Micropython), а кроме этого даже сделали свой загрузчик
и онлайн IDE где доступны примеры и библиотеки.
Будем говорить честно, оба приложения достаточно сыроватые, не всё понятно, а так же все файлы которые предлагается скачать, доступны только для Windows, но тем не менее загрузить Micropython, а так же подключиться к плате с помощью Online IDE - возможно, хотя, на мой взгляд, использовать ESP32 MPY-Jama гораздо удобнее.
Напишем небольшой проект - поуправляем встроенными светодиодами с помощью инфракрасного пульта. Для работы с инфракрасными модулями существует прекрасная библиотека micropython_ir, добавим её на наше устройство. Это можно сделать, используя менеджер пакетов mpremote
:
mpremote mip install "github:peterhinch/micropython_ir/ir_rx"
Но в таком случае установится вся библиотека, а в нашем случае нужно всего два файла __init__.py
и nec.py
. Почему только эти? Дело в том, что пульт, найденный мной в залежах, поддерживает именно этот протокол сообщений. Если вы, как и я не нашли пульт, но не знаете какой у него протокол - можно использовать FlipperZero.
Итак, мы загрузили библиотеку, подключили модуль ИК-приёмника к одному из доступных портов. В моём случае информация с него будет поступать на 32-й пин.
from machine import Pin
from ir_rx.nec import NEC_16
IR_Pin = Pin(32, Pin.IN)
led_Pins = [Pin(i, Pin.OUT) for i in [16,17,18,27]]
def callback(data, addr, ctrl):
if 0 <= data <len(led_Pins) :
new_value = abs(led_Pins[data].value()-1)
led_Pins[data].value(new_value)
ir = NEC_16(IR_Pin, callback)
В начале импортируем необходимые модули. Затем инициализируем переменные: IR_Pin
- к которому подключен ИК-приёмник и led_Pins
- список пинов, к которым подключены светодиоды.
Затем описываем функцию-обработчик. При нажатии на одну из 4 кнопок пульта (data
- это просто число), мы инвертируем состояние светодиода с соответствующим индексом.
А затем подключаем функцию-обработчик к данным с нашего модуля. В принципе, на этом можно было бы и закончить, данный код вполне рабочий. Но поскольку у нас не так много ресурсов, это всё-таки микроконтроллер, а не компьютер, хорошим тоном считается вызывать сборщик мусора. Так что немного дополним нашу программу:
import gc
import time
# Весь код из блока выше
while True:
time.sleep(1)
gc.collect()
Итого, программировать устройство на Micropython возможно, можно легко пробовать различные проекты, но уроки далеко не полны(например про инфракрасные модули вообще никакой информации), а IDE и загрузчик оставляют желать лучшего. Посмотрим на другие способы.
Arduino
Поскольку эта плата базируется на ESP32, то в Arduino IDE можно использовать какую-нибудь из стандартных конфигураций. Но авторы устройства создали собственную сборку, которую можно добавить в ArduinoIDE. Указываем в настройках новый путь для менеджера плат - https://github.com/magicbitlk/arduino-esp32/releases/download/Magicbit/package_magicbit_index.json
, а затем, непосредственно в самом менеджере, скачиваем всё необходимое.
Не с первой попытки, но тестовый пример(классический Blink
) заработал. Кстати, под системной переменной LED_BUILTIN
скрывается светодиод подключенный к 16 пину.
Просмотрев уроки, можно заметить, что разработчики не создали собственные библиотеки для управления встроенными модулями, как, например сделала фирма M5Stack, а предлагает использовать уже готовые, от проверенных разработчиков, например для работы со встроенным дисплеем предлагается использовать знакомую многим библиотеку Adafruit_SSD1306.h
.
Поскольку среди модулей, которые я заказал был датчик для измерения температуры и влажности, напишем небольшой проект - "метеостанция". Мне хочется, что бы на моём экране отображались не только цифры, а какая-то инфографика, так что я воспользовался онлайн генератором кода для экрана SSD1306 и сделал вот такой шаблон:
И сервис автоматически сгенерировал код, приводить его полностью - нет смысла, а для того, что бы показать, как выглядит экран - я воспользуюсь симулятором Wokwi, в котором соберу схему, аналогичную нашему устройству. Кстати, весь проект(схему и код) можно посмотреть и запустить по ссылке.
Теперь подключим к устройству наш сенсор, и допишем код, который будет считывать значения и выводить их на экран. В процессе написания этого блока, я всё-таки решил переписать автоматически сгенерированный код и для улучшения читабельности - разделить на независимые функции:
Для начала - подключаем необходимые библиотеки и инициализируем переменные для работы с экраном и с датчиком:
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define DHTPIN 32
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Затем основная функция, в которую поступает два параметра - температура и влажность, и которая отрисовывает картинку на экране:
void updateDisplay(float temperature, float humidity){
// Очищаем дисплей
display.clearDisplay();
// Рисуем контуры
display.drawRect(0, 0, 128, 64, SSD1306_WHITE);
display.drawLine(0, 32, 128, 32, SSD1306_WHITE);
// Всё, что касается температуры
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 10);
display.print(F("Temp: "));
display.setTextSize(1);
display.setCursor(75, 15);
display.print(F(String(temperature,1).c_str()));
display.drawCircle(110, 15, 2, SSD1306_WHITE);
display.setCursor(115, 15);
display.print(F("C"));
// Всё, что касается влажности
display.setTextSize(1);
display.setCursor(5, 48);
display.print(F("Humidity: "));
display.print(F(String(humidity,1).c_str()));
display.print(F(" %"));
// Обновляем дисплей
display.display();
}
А затем две стандартные Arduino функции: setup()
- в которой мы инициализируем экран и датчик и loop()
- в которой мы считываем показания датчика и обновляем картинку:
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
dht.begin();
}
void loop() {
float currentTemperature = dht.readTemperature();
float currentHumidity = dht.readHumidity();
updateDisplay(currentTemperature,currentHumidity);
delay(1000);
}
Что можно сказать про программирование с помощью Arduino IDE? Да, сделали свою сборку для менеджера плат, но никакой собственной библиотеки не сделали. Хорошо это или плохо? Как посмотреть. С одной стороны - используются общепринятые библиотеки, что позволит легко портировать проекты как с Magicbit на другие конфигурации, так и в обратном направлении(что мы собственно и сделали, используя симулятор). С другой стороны - платформа позиционирует себя как образовательную и в таком случае, было бы удобнее сделать либо более подробные уроки, либо всё-таки свою библиотеку, базирующуюся на популярных, но что бы она была одна.
Программирование на Micropython и в Arduino IDE доступно для любой платы на основе ESP32. Давайте посмотрим на те способы разработки, которые предлагает Magicbit. Начнём с MagicCode.
MagicCode
MagicCode
- это основанная на Scratch платформа блочного программирования. В ней есть несколько режимов, загрузка программы по проводу и по WiFi, но увы, эта среда доступна только для Windows. Если поискать на сайте - то можно обнаружить онлайн-версию
Перед тем как начать в ней работать, необходимо установить последнюю версию MagicOS
на плату, с помощью загрузчика.
После установки MagicOS
при загрузке устройства появляется меню, в котором просят выбрать режим: MagicCode/MagicBlocks/Examples/Robotics. Выберем MagicCode
и подключимся в IDE.
В целом - Scratch
с дополнительными блоками - доступен базовый функционал части модулей, например есть блок для работы с адресными светодиодами - neopixel
, но подразумевается использование только стандартного блока с одним светодиодом. А библиотека и функции - одни и те же.
Сделаем для проверки работоспособности простейшую программу которая в зависимости от того, какие кнопки нажаты включает один из светодиодов.
Воспользуемся формулой C = A + 2B, где A и B - значения кнопок, таким образом мы сможем распознать каждое из 4 состояний:
В целом - работает, но переодически отваливается подключение и приходится переподключать заново и обновлять страницу. Переходим к последнему способу - MagicBlocks.
MagicBlocks
В отличие от MagicCode
- MagicBlocks
позиционируется как полностью онлайн среда разработки, на основе популярного проекта - Node-RED.
Как и в случае работы в MagicCode
- мы работаем когда на плату установлена MagicOS
, только в этот раз нужно выбрать уже другой режим. Выбираем MagicBlocks
и заходим на сайт.
Скажем честно, выглядит довольно вырвиглазненько:
Зайдём на вкладку Device Menager
и добавим наше устройство:
А затем в настройках укажем данные для подключения по WiFi. В общем "интуитивно понятный интерфейс".
После подключения, переходим на вкладку Home
, запускаем Playground
и переходим на соответствующую вкладку:
Окей, тут уже что-то серьёзное. Попробуем повторить, а затем слегка модифицировать один из примеров - Включение светодиода через интернет.
Для начала повторяю всё, что написано в инструкции и, на удивление, всё работает.
Создали два сигнала, подключили их к одному из пинов, ответственных за светодиод
задеплоили и теперь при нажатии на один из сигналов - светодиод включается, а при нажатии на другой - выключается.
Приятно, что в этой IDE подумали про возможность экспорта и импорта. Причём это не какой-то специализированный файлик, а просто JSON. Примерно вот такого вида:
[
{
"id": "683f9ac2.0e1e34",
"type": "tab",
"label": "Flow 1",
"disabled": false,
"info": ""
},
{
"id": "42e33d4d.b20944",
"type": "inject",
"z": "683f9ac2.0e1e34",
"name": "",
"topic": "on",
"payload": "1",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 170,
"y": 180,
"wires": [
[
"74b61ed8.deaf7"
]
]
},
{
"id": "3ccaa5c2.9bfe2a",
"type": "inject",
"z": "683f9ac2.0e1e34",
"name": "",
"topic": "off",
"payload": "0",
"payloadType": "num",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 170,
"y": 240,
"wires": [
[
"74b61ed8.deaf7"
]
]
},
{
"id": "74b61ed8.deaf7",
"type": "DO",
"z": "683f9ac2.0e1e34",
"name": "LedPin",
"epId": "id4127-1733886857062",
"pin": "16",
"x": 350,
"y": 220,
"wires": []
}
]
В целом всё работает, но кажется, что это заслуга не столько Magicbit, сколько Node-RED.
Заключение
Кажется пришло время подвести итоги. Идея платы в таком форм-факторе достаточно прикольная, удобно, что сразу идёт в комплекте несколько модулей, можно придумать достаточно большое количество обучающих проектов. С точки зрения софта - явные недоработки.
С методической точки зрения, некоторые уроки написаны неплохо, но их явно мало, ни для одного из средств разработки не рассмотрены все модули, я уже и не говорю о библиотеках.
Учитывая, что последние обновления на сайте были больше года назад, проект, который неплохо начинался(собрал почти в 7 раз больше заявленного на Kickstarter) больше не поддерживается, а значит Magicbit - это просто очередная плата на основе ESP32, а жаль, из неё могло бы вырасти что-то большее.
Комментарии (9)
Sagittarius67
11.12.2024 05:52Если вы, как и я не нашли пульт, но не знаете какой у него протокол - можно использовать FlipperZero.
Имея ESP32 и IR приёмник вы предлагаете использовать FlipperZero для определения протокола пульта? Вы шутите?
red_dragon
11.12.2024 05:52Ох уж эти выводы. А что могло бы вырасти из этой платы, если бы проект поддерживался?
HEXFFFFFFFF
Нельзя быть фанатом ESP или фанатом STM, или атмеги. Контроллер выбирается под задачи. Технологии, среда, язык тоже. Где то и микропайтон сойдет, а где то нужен голый асм. Особенно при обучении нужно учить уметь выбирать правильные технологии и контроллер.
StepanovAlex
Но бывает так, что задачи под любимый МК подбираешь. Ведь разбиение задачи на подзадачи это искусство.
LAutour
На практике (особенно на производстве) чем меньше "зоопарк" применяемых микроконтроллеров - тем лучше.
AviPaperno Автор
Мне кажется, что важно отличать фаната от фанатика. Фанатик будет везде пихать свой любимый контроллер, даже если не удобно, а фанат при прочих равных - выберет свой любимый)
odobryabov
В идеале всё так, но с точки зрения затрат и окупаемости иногда лучше выбрать то, с чем ты хорошо знаком и можешь сделать быстро и хорошо. В итоге, цена компонентов будет завышена, но ПО будет написано быстрее и качественнее. И дальнейшая поддержка проще. И наоборот, можно сэкономить на компонентах, но пока разработчик разберётся что-куда, и потом выяснится, что надо было сделать по-другому, то тут уже вся экономия боком выйдет.
Indemsys
Я бы уточнил - контроллер в семействе. Но не семейство и тем более не архитектура.
И вряд ли кто-то научит выбирать правильные архитектуры. Слишком уже развит vendor lock-in