Возможно, вы заметили по моим статьям, я большой фанат контроллера 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)


  1. HEXFFFFFFFF
    11.12.2024 05:52

    Нельзя быть фанатом ESP или фанатом STM, или атмеги. Контроллер выбирается под задачи. Технологии, среда, язык тоже. Где то и микропайтон сойдет, а где то нужен голый асм. Особенно при обучении нужно учить уметь выбирать правильные технологии и контроллер.


    1. StepanovAlex
      11.12.2024 05:52

      Но бывает так, что задачи под любимый МК подбираешь. Ведь разбиение задачи на подзадачи это искусство.


    1. LAutour
      11.12.2024 05:52

      На практике (особенно на производстве) чем меньше "зоопарк" применяемых микроконтроллеров - тем лучше.


    1. AviPaperno Автор
      11.12.2024 05:52

      Мне кажется, что важно отличать фаната от фанатика. Фанатик будет везде пихать свой любимый контроллер, даже если не удобно, а фанат при прочих равных - выберет свой любимый)


    1. odobryabov
      11.12.2024 05:52

      В идеале всё так, но с точки зрения затрат и окупаемости иногда лучше выбрать то, с чем ты хорошо знаком и можешь сделать быстро и хорошо. В итоге, цена компонентов будет завышена, но ПО будет написано быстрее и качественнее. И дальнейшая поддержка проще. И наоборот, можно сэкономить на компонентах, но пока разработчик разберётся что-куда, и потом выяснится, что надо было сделать по-другому, то тут уже вся экономия боком выйдет.


    1. Indemsys
      11.12.2024 05:52

      Я бы уточнил - контроллер в семействе. Но не семейство и тем более не архитектура.
      И вряд ли кто-то научит выбирать правильные архитектуры. Слишком уже развит vendor lock-in


  1. StepanovAlex
    11.12.2024 05:52

    ESP32 - классный!


  1. Sagittarius67
    11.12.2024 05:52

    Если вы, как и я не нашли пульт, но не знаете какой у него протокол - можно использовать FlipperZero.

    Имея ESP32 и IR приёмник вы предлагаете использовать FlipperZero для определения протокола пульта? Вы шутите?


  1. red_dragon
    11.12.2024 05:52

    Ох уж эти выводы. А что могло бы вырасти из этой платы, если бы проект поддерживался?