Управление Lego Power Functions через Arduino и Bluetooth — полное руководство
Компоненты и материалы
| Arduino UNO | × | 1 |
| Драйвер двигателей L293D (DIP, с длинными ножками) | × | 1 |
| Breadboard | × | 1 |
| Коннектор 9V → Barrel Jack (для питания Arduino) | × | 1 |
| Lego Power Functions Extension wire (Item 8886) — 3 шт. | × | 3 |
| Bluetooth-модуль HC-05 | × | 1 |
О проекте
Есть крутая Lego-модель с моторами Power Functions? Научимся управлять ею с Arduino минимумом деталей. Подробно разберём схемы и код — доступно для новичков. Модель собираете сами (если нет сына, который даст свою 9398 4X4 Crawler).
Также создадим пульт на Android через MIT App Inventor. Скоро у вас будет свой Mars rover во дворе!
Понимание проводки Power Functions
Купите провода расширения (8886) и разрежте их. Сделайте «break-out» кабели: Lego-штекер с одной стороны, пины — с другой.
Проводка (4 жилы):
- GND — земля (минус батарейки, анод)
- C1, C2 — управление направлением (переключение полярности на моторе/серве)
- 9V — плюс от батарейного бокса (только на тёмно-сером штекере)
Для сервы нужны все 4 провода (светло-серый штекер). Для питания от батарейного бокса — только 9V и GND (тёмно-серый штекер, male). Для мотора — C1 и C2 (светло-серый штекер).
Управление мотором через L293D
Нужен PWM для скорости (DC) и позиции (серво). Arduino: analogWrite(pin, 0-255) на пинах с ~.
Arduino выдаёт 5В/30мА, моторы Lego — 9В/>100мА. Нужен H-мост. L293D содержит 2 H-моста: один для моторов (параллельно), второй для сервы. (Для независимого управления двумя моторами — второй L293D).
L293D гальванически разделяет 9В (Lego) и 5В (Arduino). Никогда не соединяйте 9В и 5В! Общий GND — обязателен.
Распиновка Arduino → L293D:
- Мотор: D2 (1A), D5 (2A), D9 (EN1,2 — PWM скорость)
- Серво: D6 (3A), D8 (4A), D3 (EN3,4 — PWM позиция)
Логика L293D (H = 5В, L = 0В):
| EN1,2 | 1A | 2A | Результат |
|---|---|---|---|
| H | H | L | Мотор вперёд (motorDirection=1) |
| H | L | H | Мотор назад (motorDirection=0) |
| EN3,4 | 3A | 4A | Результат |
|---|---|---|---|
| H | H | L | Серво влево (steeringDirection=0) |
| H | L | H | Серво вправо (steeringDirection=1) |
Подпрограмма управления:
void SetMotorControl() {
if (motorDirection == 1) { digitalWrite(controlPin1A, HIGH); digitalWrite(controlPin2A, LOW); }
else { digitalWrite(controlPin1A, LOW); digitalWrite(controlPin2A, HIGH); }
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) { digitalWrite(controlPin3A, HIGH); digitalWrite(controlPin4A, LOW); }
else { digitalWrite(controlPin3A, LOW); digitalWrite(controlPin4A, HIGH); }
analogWrite(servoENablePin, steering);
}
Android-пульт с джойстиком (MIT App Inventor 2)
MIT App Inventor — веб-среда для создания Android-приложений (Google + MIT).
- На телефоне: установите MIT AI2 Companion из Google Play.
- На ПК: откройте ссылку на проект в Firefox/Chrome, войдите через Gmail.
- В Companion на телефоне можно тестировать изменения в реальном времени.
Интерфейс: оранжевая панель с синим джойстиком. Программа (Blocks view):
- Блок
when Touch.Draggedотслеживает палец. - Переменные
currentX,currentY→ расчётsteeringиspeed(-100..0..+100). - Ограничение краёв панели.
- Формирование команды:
RC,steering,speed\n\0— отправка по Bluetooth.
Чтение Bluetooth-команд в Arduino
Подключение HC-05:
- VCC → 5V Arduino (модуль толерантен до 6В)
- GND → GND
- TXD → Arduino RX (D0) — 3.3В, Arduino воспринимает как HIGH
- RXD → Arduino TX (D1) — нужен делитель напряжения! 3 резистора 1 кОм для получения 3.3В из 5В (2/3 от 5В ≈ 3.3В)
Важно: D0/D1共用 USB. При загрузке скетча отключите RXD/TXD от D0/D1!
Сопряжение: Bluetooth ON → приложение → «Bluetooth connect» → ищите HC-05 → код 1234 → «connected» зелёным.
Парсинг команды в Arduino:
#define INPUT_SIZE 30
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0; // null-termination
char* command = strtok(input, ","); // "RC"
char* RCsteering = strtok(NULL, ","); // -100..100
char* RCspeed = strtok(NULL, ","); // -100..100
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
// Масштабирование к 0..255
if (iRCsteering > 0) steeringDirection = 1; else steeringDirection = 0;
steering = int(2.55 * abs(iRCsteering));
if (iRCspeed > 0) motorDirection = 1; else motorDirection = 0;
motorSpeed = int(2.55 * abs(iRCspeed));
SetMotorControl();
}
Что дальше?
- Превратите модель в робота: ультразвуковые датчики, логика избегания препятствий — самодельный Mars rover.
- Добавьте команды и функции.
- Сначала решите: как Arduino определит потерю Bluetooth и остановит модель.
- Breadboard и провода ненадёжны для ездящей модели. Переходите на Adafruit Motor Shield с клеммниками или Sensor Shield.
Делитесь проектами!
Код
Legocar_v3_bluetooth (Arduino)
/* Lego Power Functions car over Bluetooth
Arduino Uno: моторы + серво
Android app: MIT App Inventor 2
Circuit:
- Serial (D0,D1) → HC-05 (отключать при загрузке!)
- L293D motor: D2, D5, D9
- L293D servo: D6, D8, D3
*/
#include <SPI.h>
#include <String.h> // strtok
#define INPUT_SIZE 30
const int controlPin1A = 2, controlPin2A = 5, ENablePin = 9;
const int controlPin3A = 6, controlPin4A = 8, servoENablePin = 3;
int motorSpeed = 0, motorDirection = 1;
int steering = 0, steeringDirection = 0;
void setup() {
Serial.begin(9600);
Serial.setTimeout(1000);
pinMode(controlPin1A, OUTPUT); pinMode(controlPin2A, OUTPUT); pinMode(ENablePin, OUTPUT);
pinMode(controlPin3A, OUTPUT); pinMode(controlPin4A, OUTPUT); pinMode(servoENablePin, OUTPUT);
digitalWrite(ENablePin, LOW); digitalWrite(servoENablePin, LOW);
}
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0;
char* command = strtok(input, ",");
char* RCsteering = strtok(NULL, ",");
char* RCspeed = strtok(NULL, ",");
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
if (iRCsteering > 0) steeringDirection = 1; else steeringDirection = 0;
steering = int(2.55 * abs(iRCsteering));
if (iRCspeed > 0) motorDirection = 1; else motorDirection = 0;
motorSpeed = int(2.55 * abs(iRCspeed));
SetMotorControl();
}
void SetMotorControl() {
if (motorDirection == 1) { digitalWrite(controlPin1A, HIGH); digitalWrite(controlPin2A, LOW); }
else { digitalWrite(controlPin1A, LOW); digitalWrite(controlPin2A, HIGH); }
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) { digitalWrite(controlPin3A, HIGH); digitalWrite(controlPin4A, LOW); }
else { digitalWrite(controlPin3A, LOW); digitalWrite(controlPin4A, HIGH); }
analogWrite(servoENablePin, steering);
}
GitHub с исходниками (Arduino, Fritzing, App Inventor): https://github.com/Notthemarsian/Lego-car-Arduino
Схемы
Fritzing-схема и файлы проекта на GitHub (ссылка выше).
Производственный процесс
- Мастерство SaaS: стратегии сохранения контроля при использовании облака
- Дифференцирование экспоненциальных функций с основанием e
- Первообразные экспоненциально-степенных функций
- Повышение надежности компонентов передачи мощности: Проверенные стратегии для горнодобывающего, производст…
- Электрические щиты управления: основы проектирования для безопасности и ROI
- Ветровая энергетика: превращение движения воздуха в чистую электроэнергию
- UK производители теряют £2,5 млн на исправлении ошибок проектирования в проектах автоматизации
- Надежная аренда энергоустановок и HVAC для бесперебойного климат-контроля
- Восемь проверенных шагов для диагностики и устранения неисправностей системы процессного управления
- Освоение управления натяжением в обработке полотна: основные компоненты