Беспроводной робот-робер, управляемый Node.js через Bluetooth — IoT проект в реальном времени
Компоненты и материалы
| Arduino UNO | ×1 |
| Драйвер двигателей L298 (SparkFun Dual H-Bridge) | ×1 |
| Bluetooth-модуль HC-05 | ×1 |
| Перемычки | ×1 |
| Крона 9V | ×2 |
| DC-моторы 12V (с редуктором) | ×2 |
О проекте
Идея проекта
Node.js отлично подходит для реального времени. Опыт с сокетами вдохновил сделать IoT-проект с Node.js-сервером для самообучения.
Робер общается с сервером по Bluetooth, а фронтенд (веб-страница) отправляет команды серверу через WebSockets.
Цель
Изучить и реализовать беспроводную связь Node-сервера с железом (робером) и удаленное управление через мобильную веб-страницу на сокетах.
Предварительные знания
Базовые знания Node.js, сокетов и работы драйвера L298.
Требования
- Arduino Uno
- L298 Motor Driver
- HC-05 Bluetooth Module
- Перемычки
- 2 кроны 9V
- 2 редукторных мотора (6-9V)
- 2 совместимых колеса
- Шасси
- Компьютер с Node.js для сервера
Шаг 1: Сборка робера
Проще купить набор «2-wheel chassis kit» — есть всё для сборки. Arduino и L298 крепятся сверху, питание — отдельные кроны. Arduino питает HC-05.
Схема подключения
- L298 питается от 9V. Выходы моторов → Мотор A и B. Полярность не важна, но оба мотора должны крутиться в одну сторону. Не снимайте джампер 5V стабилизатора!
- Внимание: питание L298 >12V сожжет стабилизатор 5V.
- Arduino: +9V → Vin, - → общий GND.
- HC-05: VCC → 5V Arduino, GND → GND. TXD HC-05 → RX Arduino, RXD HC-05 → TX Arduino.
- EN1, EN2 L298 → любые PWM-пины Arduino. IN1-IN4 → любые цифровые пины.
Передача данных
- Пользователь заходит на веб-страницу (IP:порт, напр. 192.xxx.xxx.129:8080)
- Клик по кнопке → событие через сокеты на сервер
- Сервер (с HC-05 по Bluetooth) шлет команду модулю
- HC-05 → Arduino по UART
- Arduino управляет L298
Шаг 2: Настройка сервера
Установите Node.js (стабильная версия, у меня 11.15). Пакеты:
- node-gyp (требует Node 11.15, новее могут быть проблемы)
- express
- node-bluetooth
- socket.io
- ejs
Сервер слушает события от веб-страницы. При клике страница эмитит функцию → сервер выполняет → шлет данные в Bluetooth.
Веб-страница на Express + EJS, сокеты — socket.io. Bluetooth — по документации node-bluetooth.
Шаг 3: Код Arduino
Bluetooth шлет строковые команды с терминатором «T»: напр. «forwardT». Arduino накапливает строку до «T», затем парсит и управляет L298.
Команды: forward, backward, fleft, fright, bleft, bright, break, maxspeed, medspeed, lowspeed, стоп.
Шаг 4: Результат и планы
Планы: голосовое управление, избегание препятствий, база данных со статистикой (пройденный путь, макс/средняя скорость), датчики температуры/света/влажности с логированием в БД.
Следующая версия: «Voice Controlled Rover using Mobile»
Код Arduino
const int en1 = 9, en2 = 3;
const int inp1 = 2, inp2 = 4, inp3 = 7, inp4 = 8;
char charRead;
String inputString = "";
void setup() {
Serial.begin(9600);
pinMode(en1, OUTPUT); pinMode(en2, OUTPUT);
pinMode(inp1, OUTPUT); pinMode(inp2, OUTPUT);
pinMode(inp3, OUTPUT); pinMode(inp4, OUTPUT);
}
void loop() {
if (Serial.available()) {
charRead = Serial.read();
if (charRead != 'T') {
inputString += charRead;
} else {
if (inputString == "forward") {
digitalWrite(inp1, HIGH); digitalWrite(inp2, LOW);
digitalWrite(inp3, HIGH); digitalWrite(inp4, LOW);
} else if (inputString == "backward") {
digitalWrite(inp1, LOW); digitalWrite(inp2, HIGH);
digitalWrite(inp3, LOW); digitalWrite(inp4, HIGH);
} else if (inputString == "fleft") {
digitalWrite(inp1, HIGH); digitalWrite(inp2, LOW);
digitalWrite(inp3, LOW); digitalWrite(inp4, LOW);
} else if (inputString == "fright") {
digitalWrite(inp1, LOW); digitalWrite(inp2, LOW);
digitalWrite(inp3, HIGH); digitalWrite(inp4, LOW);
} else if (inputString == "bleft") {
digitalWrite(inp1, LOW); digitalWrite(inp2, LOW);
digitalWrite(inp3, LOW); digitalWrite(inp4, HIGH);
} else if (inputString == "bright") {
digitalWrite(inp1, LOW); digitalWrite(inp2, HIGH);
digitalWrite(inp3, LOW); digitalWrite(inp4, LOW);
} else if (inputString == "break") {
analogWrite(en1, 50); analogWrite(en2, 50);
delay(550);
digitalWrite(inp1, LOW); digitalWrite(inp2, LOW);
digitalWrite(inp3, LOW); digitalWrite(inp4, LOW);
analogWrite(en1, 150); analogWrite(en2, 150);
} else if (inputString == "maxspeed") {
analogWrite(en1, 250); analogWrite(en2, 250);
} else if (inputString == "medspeed") {
analogWrite(en1, 180); analogWrite(en2, 180);
} else if (inputString == "lowspeed") {
analogWrite(en1, 90); analogWrite(en2, 90);
} else {
digitalWrite(inp1, LOW); digitalWrite(inp2, LOW);
digitalWrite(inp3, LOW); digitalWrite(inp4, LOW);
}
inputString = "";
}
}
}
Схемы
Производственный процесс
- Создание беспроводного робототехнического автомобиля с ИК-сенсорами
- Эффективные веб-серверы для ресурсно-ограниченных микроконтроллеров
- Развёртывание TLS-веб-сервера на ESP8266 за $3 за 30 минут
- Реально-временный мониторинг температуры и влажности через веб на Raspberry Pi 4
- Температурно-управляемый вентилятор: DIY релейная система охлаждения мебели для медиа
- От $4 солнечного фонаря к умному беспроводному сенсорному узлу: MSP430 + nRF24L01+ для мониторинга сада
- Превратите Raspberry Pi 4 в веб-сервер и создайте свой сайт
- Превратите свой RC-автомобиль в Bluetooth-управляемый транспорт
- Превращаем старую радиоуправляемую машину в джойстик-контролируемый болид на Arduino
- Wi‑Fi RC-машина с беспроводной зарядкой Qi на Arduino MKR1000