Маленький ровер на Arduino: собираем автономного робота своими руками
Компоненты и материалы
| Arduino Nano R3 | 1 |
| Макетная плата (breadboard) | 1 |
| Перемычки (набор) | 1 |
| Ультразвуковой датчик HC-SR04 | 1 |
| Колеса для микросервопривода FS90R (Adafruit) | 2 |
| Микросервопривод непрерывного вращения FS90R (Adafruit) | 2 |
| Светодиоды (любой цвет) | 2 |
| Короб для 4×AA батареек | 1 |
| Опорное колесо (Ball Caster) 3/8" | 1 |
| Пластиковый контейнер (коробок от маргарина/крабовых палочек) | 1 |
| Наклейки для декора | 1 |
Инструменты
- Клеевой пистолет
- Канцелярский нож (carpet knife)
Программное обеспечение
- Arduino IDE
О проекте
Предыстория
Племянник (9 лет) и племянница (7 лет) в восторге от видеоролика с роботом-избегателем препятствий, который я делал давно. Урок для того проекта не выйдет — пропал жесткий диск вместе с исходниками (с тех пор я religioзно делаю бэкапы и использую GitHub).
Решил сделать максимально простой и веселый робот, в сборке которого дети смогут участвовать практически самостоятельно. Шасси — пластиковая коробка от крабовых палочек (идеальный размер, спасибо папе за закуски!). Подойдет и коробка от маргарина.
Важно: Я описываю, как собирали мы — дети делали почти всё сами. Но это не рекомендация. Вы — взрослый, решаете, чему можно доверять ребенка. Даже с мягким пластиком и аккуратными ножами дети носили защитные очки. Для отверстий под светодиоды использовали шуруповерт с малым моментом. Аптечка так и не пригодилась, но ответственность — на вас.
Схема подключения
Схема чуть сложнее минимума: сервоприводы подключены через общие шины питания на макетке. Для детей (и взрослых: сестра 35 лет, мама 65 — все были в восторге!) распечатал схему 1:1 на А4, подготовил перемышки нужных цветов и длин.
После сборки загружаем скетч. В коде есть комментарии для настройки. При правильной сборке сервы начнут вращаться, светодиоды мигать. Если поднести руку к датчику — один серво остановится, другой развернется назад.
Сборка механики
- Отметьте и вырежьте отверстия под ультразвуковой датчик («глаза») на передней стенке.
- На боковых стенках у дна вырежьте окна под сервоприводы: корпус сервы должен войти, крепежные ушки — нет.
- Сверлите 2 отверстия под светодиоды (тонкая дрель/шуруповерт).
- Снизу сзади закрепите опорное колесо (винтами или горячим клеем).
Теперь устанавливаем электронику в коробку, фиксируем горячим клеем. Надеваем колеса на сервы после застывания клея. Декорируйте! (Фото в студию!)
Вставляем батареи — ровер ездит хаотично, пока не садится батарея, не надоест шум или собака не утащит его!
Код (скетч для 4-пинового ультразвукового датчика)
#include <Servo.h>
// Если датчик 3-пиновый: раскомментируйте строку 6, закомментируйте 7
// int distanceR = A0; // Trigger pin
int distance = 6; // Trigger pin
int pingDelay = 10; // Длительность импульса ультразвука
int distanceR = A0; // Echo pin
int led1 = 8, led2 = 9; // Светодиоды
Servo leftPower;
Servo rightPower;
unsigned long flashTime;
unsigned long nextSensorTime;
float obstacleDist = 0.0f;
void setup() {
// Serial.begin(115200);
leftPower.attach(3);
rightPower.attach(5);
leftPower.write(90);
rightPower.write(90);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
delay(1000);
}
void loop() {
LEDs();
// Ограничиваем опрос датчика 5 раз в сек (экономия батареи)
if (millis() - nextSensorTime > 200) {
nextSensorTime = millis();
// Два замеров — датчик иногда сбивается
float reading1 = TakeReading();
delay(100);
float reading2 = TakeReading();
// Serial.println(reading1); Serial.println(reading2);
obstacleDist = (reading1 >= reading2) ? reading1 : reading2;
if (obstacleDist < 10.0f) {
// Serial.println("turn");
turn();
} else {
// Serial.println("forward");
forward();
}
}
}
void LEDs() {
if (millis() - flashTime > 1000) flashTime = millis();
if (millis() - flashTime < 500) {
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
} else {
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
}
}
void forward() {
// Если едет назад — поменяйте 135 и 45 местами
leftPower.write(135);
rightPower.write(45);
}
void turn() {
// Для поворота в другую сторону: раскомментируйте 92-93, закомментируйте 95-96
// leftPower.write(90);
// rightPower.write(135);
leftPower.write(45);
rightPower.write(90);
delay(350);
}
float TakeReading() {
unsigned long echo = 0;
float result = 0.0f;
pinMode(distance, OUTPUT);
digitalWrite(distance, LOW);
delayMicroseconds(2);
digitalWrite(distance, HIGH);
delayMicroseconds(pingDelay);
digitalWrite(distance, LOW);
pinMode(distanceR, INPUT);
digitalWrite(distanceR, HIGH);
echo = pulseIn(distanceR, HIGH, 38000);
result = echo / 58.138;
return result;
}
Производственный процесс
- Построение ровера на Windows IoT Core с Raspberry Pi 2 — Руководство от новичка к профи
- Игра «UFO Attack» на Arduino UNO и матрице MAX7219 — Собираем аркаду с джойстиком Atari
- Цифровые кости на Arduino: генератор случайных чисел с LCD-дисплеем и кнопкой
- Эффект огня на воде: проект с Arduino UNO, NeoPixel и ультразвуковым увлажнителем
- 3D RGB Arduclock — Bluetooth-часы на адресных LED с RTC
- Мониторинг состояния реки: Arduino-система контроля качества воды
- Строим Iron Man на Arduino: компоненты, сенсоры и пошаговый гайд
- Интерактивная игра с джойстиком и LED-обратной связью на Arduino
- Find Me: Умный поисковик вещей на Arduino и Bluetooth
- Сборка функционального 3D-печатного манипулятора на Arduino: пошаговое руководство