
Наборы LEGO с электрикой уже давно перестали быть просто игрушкой. Современная серия устройств Powered Up — это небольшая модульная робототехническая платформа: smart-устройства, моторы, датчики, подсветка, управляемые по Bluetooth, с возможностью программирования поведения моделей, что ранее было доступно только в специализированных наборах (LEGO Mindstorms, Education).
Как же получить данные из smart-устройства, ведь это открывает новые возможности по использованию электронных LEGO наборов.
Официальное приложение LEGO PoweredUp предлагает визуальный блоковый редактор программирования и виртуальных пультов управления. Можно логически объединять до четырёх хабов (большие «интеллектуальные кубики» LEGO с портами ввода-вывода), настраивать взаимодействие устройств и собирать достаточно сложные алгоритмы — от роботов, до беспилотного грузовика, автоматизированной установки или управления железной дорогой.
Однако у официального ПО есть два ключевых ограничения.
Во-первых, оно полностью закрыто: приложение не предоставляет доступ к данным в реальном времени, а значит — нельзя передать данные на ПК, построить график, провести анализ или просто сохранить сигналы.
Во-вторых, программа всегда запускается на смартфоне или планшете, и хаб должен быть постоянно подключён к устройству, что существенно ограничивает автономность и применимость.
К счастью, экосистема Powered Up (знакомство с ней https://youtu.be/8F44vVdfK_A) основана на открытых технологиях: устройства работают по BLE (Bluetooth Low Energy), а LEGO официально опубликовала протокол взаимодействия — LWP3 (LEGO® Wireless Protocol v3, https://lego.github.io/lego-ble-wireless-protocol-docs/).
Это открыло путь сторонним разработчикам ПО создавать свои инструменты для программирования и управления хабами LEGO. И одним из удачных решений, на мой взгляд, является PyBricks.
PyBricks (https://pybricks.com/ это альтернативная прошивка для хабов серии Powered Up, созданная командой энтузиастов, решившая «раскрыть» весь потенциал LEGO-электроники. Вместе с прошивкой предоставляется веб-IDE: редактор кода, загрузчик и BLE-коммуникатор — всё работает прямо в браузере.

Программировать можно на MicroPython (бесплатный режим) или в блочном редакторе, доступном по подписке. PyBricks полностью заменяет штатную прошивку и превращает хаб в автономный микроконтроллер со встроенным интерпретатором Python, код запускается прямо на устройстве. При этом всегда можно вернуться на родную прошивку: официальное приложение LEGO PoweredUp перепрошьёт хаб при первом подключении. И кроме того, у этого ПО хорошая документация, можно без труда разобраться, что не скажешь о приложении LEGO – там информации практически нет.
В этой статье мы хотели поделиться опытом передачи данных с LEGO-хаб в ПК, показать, как это работает и какие открываются новые возможности.
Что мы сделали:
1. Прошили LEGO Technic Hub альтернативной прошивкой PyBricks.
2. Создали простую LEGO-установку с обратной связью
3. Написали программу для хаба, которая периодически отправляет данные
4. На ПК с помощью библиотеки Bleak подключили хаб к компьютеру
5. Получили данные с хаба и применили их.
Было решено сделать простую установку с обратной связью. На вал мотора установили небольшую «качель», на неё – датчик наклона от набора LEGO WeDo 2.0. Этот датчик измеряет угол от -45 до 45 градусов (точнее два угла, по тангажу и крену, нам нужен первый).

Далее нужно написать программу на PyBricks, загрузить её в перепрошитый хаб и отсоединится — код будет работь автономно. Программа постоянно считывает угол наклона и управляет мотором так, чтобы выставить качель в горизонтальное положение. Скорость вращения двигателя рассчитывается пропорционально отклонению — классический пропорциональный регулятор.
Вот такая программа получилась в Pybricks.
from pybricks.hubs import TechnicHub
#from pybricks.hubs import CityHub
from pybricks.pupdevices import Motor, TiltSensor
from pybricks.parameters import Port
from pybricks.tools import wait
# создаём хаб и устройства
hub = TechnicHub()
#hub = CityHub()
motor = Motor(Port.A)
tilt = TiltSensor(Port.B)
angle_0 = 0 # целевой угол
#Kp коэффициент пропорционального усиления (КПУ)
Kp = 3
# Увод качели от равновесия перед началом
motor.run(30)
wait(1000)
K = 0 # счетчик попыток найти равновесие
while True:
# угол наклона в градусах: 0 = горизонт, -2 = погрешность экземпляра
angle = tilt.tilt()[0]-2 # [0]=тангаж, [1]=крен
# отклонение
error = angle - angle_0
# скорость, управляющее воздействие
speed = Kp*error
# ограничим скорость
speed = max(min(speed, 75), -75)
motor.run(speed)
K+=1
# print(f"{angle},{speed}")
print(angle) # Вывод для передачи данных
# определение достижения целевого угла
if abs(angle) ==angle_0:
angle = 0
for i in range(10):
angle += tilt.tilt()[0]-2
wait(100)
if angle != angle_0 * (i+1):
break
if angle == angle_0 * (i+1):
print("РОВНО, K=", K)
break
wait(50)
Двигатель запускается командой motor.run(speed) – движение с постоянной скорость в град/с. При маленьких скоростях движение реализовано рывками, но для нашей задачи это не принципиально.

После отладки, когда система заработала стабильно, стало интересно провести эксперимент, точнее серию экспериментов и посмотреть, как изменяются динамика и устойчивость при разных значениях коэффициента пропорциональности. А чтобы наблюдать процесс во времени, хаб должен передать угол наклона. Для этого в коде оставили один-единственный print(), который и будет передавать на ПК значение текущего угла.
Принимать и визуализировать данные будет программа, которую мы напишем и запустим на ПК. Для связи с хабом используем Bleak.
Bleak (https://pypi.org/project/bleak/) — это кроссплатформенная библиотека Python для работы с BLE. Она позволяет: находить BLE-устройства и подключаться к ним, читать и писать их характеристики, подписываться на уведомления — именно через них PyBricks будет передавать строки, отправленные командой print().
Алгоритм работы следующий: запускаем нашу программу на ПК, включаем хаб (индикатор должен мигать), и Bleak находит его по имени. После появления сообщения «— Приём данных…» нужно нажать кнопку хаба ещё раз — это запускает загруженную программу PyBricks, и в этот момент он начинает отправлять телеметрию.
Полученные данные отображаются в консоли, а параллельно мы строим график в реальном времени с помощью matplotlib.
Скрытый текст
В программе на ПК для работы необходимо найти хаб. Сканирование инициализируется вызовом
await BleakScanner.discover(timeout=8)
Среди найденных устройств выбирается с именем «HUBPB».
После подключения программа подписывается на специальную BLE-характеристику (можно взять из описания LWP3), которая в прошивке PyBricks выполняет роль виртуального UART (универсальный асинхронный приёмопередатчик).
Это позволяет оставленной нами команде print() в PyBricks не просто выводит текст «в никуда», а отправлять строку по BLE-каналу уведомлений (notify characteristic) — то есть устройство, подписанное на эту характеристику (в нашем случае — ПК с Bleak), получает каждую строку, которую хаб «напечатал». Подписка выглядит как
client.start_notify(CHAR_UUID, callback),
где callback — это наша функция обработчик данных. Следующей строчкой надо вывести сообщение об ожидании данных (например "— Приём данных…")
Данные, приходящие из PyBricks, выглядят как обычные текстовые строки, иногда с управляющими символами. Поэтому в обработчике сначала делаем data.decode(...).strip(), а затем фильтруем всё, что не является цифрой или знаком числа. В итоге у нас остаётся значение, которое можно преобразовать в float и использовать дальше.
Каждый принятый замер мы сопровождаем меткой времени t (time.time()) и уже в таком виде отправляем в очередь межпроцессного обмена:
queue.put((t, value)).
Это единственная точка соприкосновения двух процессов, она позволяет полностью развести Bluetooth-код и графику, чтобы они не мешали друг другу.
Графическая часть работает отдельно — она выполняется в собственном процессе, запущенном через
multiprocessing.Process(target=plotter).
Внутри него создаётся окно matplotlib, включается интерактивный режим (plt.ion()), и начинается простой цикл: чтение очередной точки, добавление в массивы, обновление линии и вызов plt.pause(0.01) для перерисовки. Получается «живой график», который визуализирует поток данных в момент их получения, без задержек.
В финальном управляющем блоке (if name == "__main__":) необходимо создать очередь, запустить процесс с графиком и отдать управление BLE-части. При завершении или нажатии Ctrl+C в программе необходимо корректно завершить подпроцесс, чтобы не оставлять зависших окон.
Таким образом, print() в PyBricks фактически становится каналом телеметрии: всё, что программа на хабе выводит в консоль, уходит по BLE в нашу программу на ПК.

Передавать можно несколько значений в print(), через запятую. Соответственно на стороне ПК эту строку приёма надо разделить и преобразовать во float.
То есть теперь можно получать поток данных напрямую из LEGO-устройства и обрабатывать его в реальном времени – логировать, проводить вычисления или, как мы, вывести значения на график . Вот, кстати, так выглядит результат.

На полученном графике можно даже заметить «физику процесса». Цветом выделены области различных значений коэффициента пропорциональности, для каждого значения проведены серии из трёх тестов. Длинные пики вниз — это исходное положение качели примерно 30°, откуда начинается выравнивание, начало теста.
Картина получается показательная: коэффициент Kₚ = 2 обеспечивает самое быстрое и стабильное время сходимости. При более высоких значениях постепенно появляется заметная перерегулировка — система начинает «размахиваться» и тратит больше времени на сходимость.
Фактически, в этом примере мы провели маленькую лабораторную работу по автоматическому управлению, и получили данные, которые можно интерпретировать и анализировать.
Интересно, например, что в некоторых сериях, независимо от коэффициента, наблюдается почти мгновенная сходимость. Это наводит на мысль наличия случайной составляющей в процессе. Можно углубиться далее, построить фазовый портрет, исследовать устойчивость, получить бифуркационную диаграмму… Но это уже тема для отдельного исследования.
Сегодня же нам хотелось показать главное: LEGO-электроника с прошивкой PyBricks и библиотекой Bleak в сочетании с фантазией превращается из игрушки в инструмент для экспериментов и получения навыков исследователя. Причём всё это работает не на дорогих комплектах LEGO Education, а на вполне доступных наборах Technic и City с электрикой. Наша установка была собрана на Technic Hub (Control+), но мы попробовали перепрошить более простой CITY Hub (88009) — и он без проблем заработал.
Надеемся, эта статья кому-то подскажет как использовать компоненты знакомого всем конструктора по-новому. Поможет увидеть широкие возможности у простой на первый взгляд системы.
XelaVopelk
А это работает для Kazi?
Amir_Aizatulin Автор
У Kazi нет таких устройств.