Проект 11: Управление роботом с помощью ИК-пульта
Робот Фобо управляется инфракрасным пультом! Используем кнопки пульта (▲▼◄► и OK) для ручного управления роботом. Это основа дистанционного управления — в следующих проектах добавим переключение между автономными режимами.
Как это работает:
Нажимаете кнопку на пульте (например, ▲)
ИК-приёмник получает сигнал и передаёт код кнопки в Arduino
Arduino распознаёт код и выполняет команду (едет вперёд)
Отпускаете кнопку — робот останавливается
Подготовка: Библиотеки AlashIRControlRX и AlashMotorControlLite должны быть установлены (см. Проекты 10, 2).
Рабочий код
Скопируйте и загрузите этот код в Arduino IDE:
/*
* Проект 11: Управление роботом Фобо с ИК-пульта
* Кнопки: ▲ - вперёд, ▼ - назад, ◄ - налево, ► - направо, OK - стоп
*/
#include <AlashIRControlRX.h>
#include <AlashMotorControlLite.h>
// ============ ПИНЫ ============
const uint8_t IR_PIN = A3; // ИК-приёмник на аналоговом пине A3 (используется как цифровой)
// ============ КОДЫ КНОПОК ПУЛЬТА ============
// ВАЖНО: Если ваши коды отличаются, измените их (см. Проект 10)
const unsigned long BTN_UP = 0xFF18E7; // ▲ Вперёд
const unsigned long BTN_DOWN = 0xFF4AB5; // ▼ Назад
const unsigned long BTN_LEFT = 0xFF10EF; // ◄ Налево
const unsigned long BTN_RIGHT = 0xFF5AA5; // ► Направо
const unsigned long BTN_OK = 0xFF38C7; // OK - Стоп
const unsigned long BTN_REPEAT = 0xFFFFFFFF; // Код повтора (кнопка удерживается)
// ============ НАСТРОЙКИ СКОРОСТИ ============
const int speedForward = 75; // Скорость движения вперёд
const int speedBackward = 70; // Скорость движения назад
const int speedTurn = 65; // Скорость поворота
// ============ ОБЪЕКТЫ ============
AlashIRControlRX irReceiver(IR_PIN);
AlashMotorControlLite motorRight(DIR_DIR_PWM, 4, 2, 5); // IN1, IN2, ENA
AlashMotorControlLite motorLeft(DIR_DIR_PWM, 8, 12, 6); // IN3, IN4, ENB
// ============ ПЕРЕМЕННЫЕ СОСТОЯНИЯ ============
unsigned long lastCommand = 0; // Последняя полученная команда
void setup() {
Serial.begin(9600);
irReceiver.begin();
Serial.println("=== Робот Фобо: Управление с ИК-пульта ===");
Serial.println("Кнопки: ▲▼◄► - движение, OK - стоп");
Serial.println("Готов к работе!");
stopMotors();
}
void loop() {
if (irReceiver.check()) {
unsigned long code = irReceiver.data;
// Игнорируем код повтора, используем последнюю команду
if (code == BTN_REPEAT) {
code = lastCommand;
} else {
lastCommand = code;
}
// Обработка команд
switch (code) {
case BTN_UP:
moveForward();
Serial.println("▲ ВПЕРЁД");
break;
case BTN_DOWN:
moveBackward();
Serial.println("▼ НАЗАД");
break;
case BTN_LEFT:
turnLeft();
Serial.println("◄ НАЛЕВО");
break;
case BTN_RIGHT:
turnRight();
Serial.println("► НАПРАВО");
break;
case BTN_OK:
stopMotors();
Serial.println("● СТОП");
break;
default:
// Неизвестная кнопка - показываем код
Serial.print("? Неизвестная кнопка: 0x");
Serial.println(code, HEX);
break;
}
}
}
// ============ ФУНКЦИИ ДВИЖЕНИЯ ============
void moveForward() {
motorLeft.setSpeed(speedForward);
motorRight.setSpeed(speedForward);
}
void moveBackward() {
motorLeft.setSpeed(-speedBackward);
motorRight.setSpeed(-speedBackward);
}
void turnLeft() {
// Поворот на месте: левый назад, правый вперёд
motorLeft.setSpeed(-speedTurn);
motorRight.setSpeed(speedTurn);
}
void turnRight() {
// Поворот на месте: левый вперёд, правый назад
motorLeft.setSpeed(speedTurn);
motorRight.setSpeed(-speedTurn);
}
void stopMotors() {
motorLeft.stop();
motorRight.stop();
}
Как работает код:
irReceiver.check() — проверяет, получен ли сигнал с пульта
Код повтора (0xFFFFFFFF) — игнорируется, используется последняя команда
switch-case — распознаёт кнопку и вызывает нужную функцию
Повороты на месте — один мотор вперёд, другой назад
Serial Monitor — показывает какая кнопка нажата
Загрузка и запуск
Примечание
Процесс загрузки кода: см. подробную инструкцию в Уроке 1.
Важно: Коды кнопок могут отличаться! Если ваши коды не совпадают, используйте программу сканирования из Проекта 10 и замените их в разделе «КОДЫ КНОПОК ПУЛЬТА».
Тестирование
Отключите USB, вставьте батареи
Включите питание (переключатель на батарейном отсеке)
Наведите пульт на ИК-приёмник (угол до 30°)
Нажимайте кнопки: - ▲ — робот едет вперёд - ▼ — робот едет назад - ◄ — робот поворачивает налево на месте - ► — робот поворачивает направо на месте - OK — робот останавливается
Предупреждение
Безопасность:
Тестируйте на открытом пространстве (2×2 метра)
Держите пульт наготове для остановки (кнопка OK)
Не допускайте падения робота со стола!
Эксперименты
Эксперимент 1: Регулировка скорости
Попробуйте разные значения скорости:
const int speedForward = 50; // Медленное движение
const int speedTurn = 40;
const int speedForward = 100; // Быстрое движение
const int speedTurn = 80;
Вопрос: При какой скорости робот наиболее управляем? При какой самый быстрый?
Эксперимент 2: Плавные повороты
Измените функции поворотов на плавные (движение по дуге):
void turnLeft() {
// Плавный поворот: правый быстрее, левый медленнее
motorLeft.setSpeed(speedTurn / 2);
motorRight.setSpeed(speedTurn);
}
void turnRight() {
// Плавный поворот: левый быстрее, правый медленнее
motorLeft.setSpeed(speedTurn);
motorRight.setSpeed(speedTurn / 2);
}
Задание: Сравните повороты на месте и плавные повороты. Какой вариант удобнее для управления?
Эксперимент 3: Автостоп при потере сигнала
Добавьте автоматическую остановку, если сигнал не приходит более 500 мс:
unsigned long lastSignalTime = 0;
void loop() {
if (irReceiver.check()) {
unsigned long code = irReceiver.data;
lastSignalTime = millis(); // Запоминаем время последнего сигнала
// ... обработка команд ...
}
// Автостоп через 500 мс без сигнала
if (millis() - lastSignalTime > 500) {
stopMotors();
}
}
Вопрос: Как изменилось поведение робота? Останавливается ли он сразу после отпускания кнопки?
Эксперимент 4: Дополнительные кнопки
Добавьте функции для других кнопок пульта (1-9, *, #):
const unsigned long BTN_1 = 0xFFA25D; // Кнопка "1" - медленная скорость
const unsigned long BTN_2 = 0xFF629D; // Кнопка "2" - средняя скорость
const unsigned long BTN_3 = 0xFFE21D; // Кнопка "3" - быстрая скорость
int currentSpeed = 75; // Глобальная переменная скорости
// В switch добавить:
case BTN_1:
currentSpeed = 50;
Serial.println("Скорость: МЕДЛЕННАЯ");
break;
case BTN_2:
currentSpeed = 75;
Serial.println("Скорость: СРЕДНЯЯ");
break;
case BTN_3:
currentSpeed = 100;
Serial.println("Скорость: БЫСТРАЯ");
break;
// И в функциях использовать currentSpeed вместо speedForward
Задание: Реализуйте переключение скоростей кнопками 1-2-3.
Решение проблем
Проблема 1: Робот не реагирует на пульт
Решение: См. раздел «Поиск неисправностей» в Проекте 10.
Проблема 2: Коды кнопок не совпадают
Решение: Используйте программу сканирования из Проекта 10 и замените коды в разделе «КОДЫ КНОПОК ПУЛЬТА».
Проблема 3: Робот продолжает движение после отпускания кнопки
Решение: Используйте Эксперимент 3 (автостоп при потере сигнала).
Проблема 4: Робот едет криво при движении вперёд
Решение: Откалибруйте моторы (см. Проект 2) или добавьте коррекцию:
void moveForward() {
motorLeft.setSpeed(speedForward);
motorRight.setSpeed(speedForward - 5); // Коррекция для правого мотора
}
Заключение
Отлично! 🎉 Теперь робот Фобо управляется дистанционно!
Что вы узнали:
✅ Приём и обработку ИК-сигналов с пульта
✅ Распознавание кодов кнопок и фильтрацию повторов
✅ Ручное управление роботом (вперёд, назад, повороты)
✅ Отладку через Serial Monitor
Что дальше:
Проект 12: Bluetooth HM-10 — беспроводная связь с телефоном
Проект 13: Управление по Bluetooth — управление со смартфона
Проект 14: Мастер-режим — переключение между автономными режимами!
В Проекте 14 мы объединим ИК-пульт с автономными режимами (следование за рукой, объезд препятствий, движение по линии) — одна кнопка запускает режим, другая останавливает!
Успехов в управлении роботом! 🤖🎮