Magicbit — очередная плата на основе ESP32 или…

Возможно вы заметили по моим статьям, я большой фанат контроллера ESP32, а одним из его достоинств, является огромное количество плат на его основе. А благодаря своей популярности, он всё больше и больше попадает в образовательное пространство STEM.

В прошлом году я не удержался и заказал плату Magicbit, разработчики которой позиционировали её как образовательную. Давайте посмотрим, что она из себя представляет.

Внешний вид

mknqjs1qomqznxshygxugxvcnfi.png

Сама по себе плата выполнена в очень оригинальном форм-факторе — это правильный шестиугольник, который с учётом жёлто-горчичного цвета очень напоминает соты. На самой плате расположены:

  • Сам контроллер ESP32

  • Четыре светодиода: синий, зелёный, жёлтый и красный

  • Коннекторы и расширения для внешних модулей

  • Драйвер моторов

  • OLED дисплей

  • Две кнопки

  • Потециометр

  • Зуммер

  • Коннектор для подключения батарейного или аккумуляторного блока

  • Порт MicroUSB для программирования (непонятно, почему не перейти на Type-C)

А кроме этого, в той конфигурации, что я заказал, в комплекте идут дополнительные модули и датчики. С частью из них мы познакомимся.

prqfrljwa9-m5366mwm8e7xzjbw.png

На первый, да и на второй взгляд даже базовой комплектации хватит что бы сделать множество обучающих проектов. Кстати разработчики в описании упоминают »50+ проектов», которые можно сделать. А кроме этого, есть возможность докупить специальную колёсную платформу MagicBot, что бы сделать собственного робота.

Кодинг

Теперь давайте посмотрим, с помощью чего это устройство можно программировать. Раз всё базируется на ESP32 — то все дефолтные способы, такие как Arduino, Micropython и т.д. — очевидны. Что же предлагают нам разработчики кроме этого:

  • Scratch, а точнее, что-то похожий на него MagicCode, можно скачать, но только на Windows, а можно работать через браузер

  • Magicblocks — блочная среда разработки, основанная на проекте Node-RED, для создания умного дома

Micropython

Начнём с того, что создатели этой платформы сделали достаточно неплохую документацию. Для каждого из способов программирования — отдельные уроки (например для Micropython), а кроме этого даже сделали свой загрузчик

bezhqwhqdtpq7dvihcsgjohhi2w.png

и онлайн IDE где доступны примеры и библиотеки.

rj8ic-eytop1gsigvejez7peysq.png

Будем говорить честно, оба приложения достаточно сыроватые, не всё понятно, а так же все файлы которые предлагается скачать доступны только для 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 

В начале импортируем необходимые модули. Затем инициализируем переменные: 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, а затем, непосредственно в самом менеджере, скачиваем всё необходимое.

prwszoxcwn0igt5rvv4e4_dbeoy.png

Не с первой попытки, но тестовый пример (классический Blink) заработал. Кстати, под системной переменной LED_BUILTIN скрывается светодиод подключенный к 16 пину.

Просмотрев уроки, можно заметить, что разработчики не создали собственные библиотеки для управления встроенными модулями, как, например сделала фирма M5Stack, а предлагает использовать уже готовые, от проверенных разработчиков, например для работы со встроенным дисплеем предлагается использовать знакомую многим библиотеку Adafruit_SSD1306.h.

Поскольку среди модулей, которые я заказал был датчик для измерения температуры и влажности, напишем небольшой проект — «метеостанция». Мне хочется, что бы на моём экране отображались не только цифры, а какая-то инфографика, так что я воспользовался онлайн генератором кода для экрана SSD1306 и сделал вот такой шаблон:

qutp50lkuavgj4k71umhf7wjkpg.png

И сервис автоматически сгенерировал код, приводить его полностью — нет смысла, а для того, что бы показать, как выглядит экран — я воспользуюсь симулятором Wokwi, в котором соберу схему, аналогичную нашему устройству. Кстати, весь проект (схему и код) можно посмотреть и запустить по ссылке.

u2utpg4junbptcsngp4e6ll5fuy.png

Теперь подключим к устройству наш сенсор, и допишем код, который будет считывать значения и выводить их на экран. В процессе написания этого блока, я всё-таки решил переписать автоматически сгенерированный код и для улучшения читабельности — разделить на независимые функции:

Для начала — подключаем необходимые библиотеки и инициализируем переменные для работы с экраном и с датчиком:

#include 
#include 
#include 

#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 состояний:

jalq6b1bwjqqgiissw9kxqmd5du.png

В целом — работает, но переодически отваливается подключение и приходится переподключать заново и обновлять страницу. Переходим к последнему способу — MagicBlocks.

MagicBlocks

В отличие от MagicCode — MagicBlocks позиционируется как полностью онлайн среда разработки, на основе популярного проекта — Node-RED.

Как и в случае работы в MagicCode — мы работаем когда на плату установлена MagicOS, только в этот раз нужно выбрать уже другой режим. Выбираем MagicBlocks и заходим на сайт.

Скажем честно, выглядит довольно вырвиглазненько:

-fn6tfrhbx_1j-c4hgz4_vou_ls.png

Зайдём на вкладку Device Menager и добавим наше устройство:

brlptdpfpufzoix5ntgnbfd_dpo.png

А затем в настройках укажем данные для подключения по WiFi. В общем «интуитивно понятный интерфейс».

После подключения, переходим на вкладку Home, запускаем Playground и переходим на соответствующую вкладку:

cblcxmacpa6reaeziqgfaxnzzku.png

Окей, тут уже что-то серьёзное. Попробуем повторить, а затем слегка модифицировать один из примеров — Включение светодиода через интернет.

Для начала повторяю всё, что написано в инструкции и, на удивление, всё работает.

Создали два сигнала, подключили их к одному из пинов, ответственных за светодиод

1tnvicqz6dvdudebdzme7crzs4e.png

задеплоили и теперь при нажатии на один из сигналов — светодиод включается, а при нажатии на другой — выключается.

Приятно, что в этой 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, а жаль, из неё могло бы вырасти что-то большее.

© Habrahabr.ru