Урок 29/31: Car-7 Управление умным автомобилем SunFounder с помощью пульта дистанционного управления | Robojax
В этом уроке мы превратим ваш умный автомобиль SunFounder в машину с дистанционным управлением с помощью инфракрасного (ИК) пульта. Вместо проводного соединения или приложения для смартфона вы научитесь сопоставлять кнопки стандартного ИК-пульта с управлением движением автомобиля—вперёд, назад, повороты и даже диагональные манёвры—а также регулировать его скорость на лету. Этот проект станет отличным следующим шагом после изучения основ управления двигателями и ИК-связи, поскольку он объединяет оба аспекта в единую интерактивную систему.
Практическая ценность здесь заключается в понимании того, как создать надёжный и удобный интерфейс управления для робототехнической платформы. Принципы, которые вы изучите, напрямую применимы к широкому кругу проектов, таких как:
- Создание робота с дистанционным управлением для задач домашней автоматизации, например, небольшого курьера.
- Создание программируемого транспортного средства для образовательных робототехнических соревнований.
- Разработка собственного пульта для слайдера камеры или механизма панорамирования и наклона.
- Прототипирование пользовательского интерфейса для более крупной и сложной автоматизированной системы.
Оборудование и компоненты
Этот проект основан на наборе SunFounder 3-in-1 Arduino. Для выполнения вам понадобятся компоненты, перечисленные ниже. Подключение несложное и продолжает предыдущие уроки курса.
- Набор SunFounder 3-in-1 Arduino: Включает шасси умного автомобиля, плату драйвера двигателей и плату Arduino.
- Инфракрасный пульт: Стандартный пульт, входящий в комплект.
- ИК-приёмник: Датчик, который будет декодировать сигналы с пульта.
- Светодиод и резистор на 330 Ом: Используются как визуальный индикатор для подтверждения нажатия клавиши. (на видео в 04:08)
- Соединительные провода: Для создания необходимых соединений на макетной плате.
Схема подключения
Прежде чем перейти к коду, убедимся, что оборудование подключено правильно. Подключение ИК-приёмника и драйвера двигателей соответствует предыдущим урокам этой серии. Чтобы сделать проект более интерактивным, мы также подключим внешний светодиод к контакту 13 в качестве индикатора визуальной обратной связи.
Вот пошаговое руководство по подключению:
- ИК-приёмник: У ИК-приёмника три контакта. Положительный контакт подключается к шине 5V на макетной плате. Контакт заземления подключается к шине GND. Сигнальный контакт, который является последним, подключается к цифровому контакту 11 на вашей плате Arduino. (на видео в 05:29)
- Внешний светодиод: Подключите одну ножку резистора на 330 Ом к цифровому контакту 13 на Arduino. Другую ножку резистора подключите к более длинной (анодной) ножке светодиода. Более короткая (катодная) ножка светодиода должна быть подключена к шине GND на макетной плате. (на видео в 04:08)
- Драйвер двигателей: Четыре контакта драйвера двигателей (A_1B, A_1A, B_1B, B_1A) подключаются к контактам 5, 6, 9 и 10 на Arduino соответственно. Эта схема была рассмотрена в предыдущих уроках. (на видео в 06:44)
Для наглядного примера этих подключений обратитесь к схеме ниже.
Объяснение кода
Код для этого проекта разработан так, чтобы быть интуитивно понятным. Он использует библиотеку IRremote для обработки сложной задачи декодирования ИК-сигналов. Давайте разберём настраиваемые пользователем части, которые вы, возможно, захотите изменить для своих собственных проектов.
В верхней части скетча вы найдёте определения контактов. Это первое, что следует проверить, если вы подключили компоненты к другим контактам, чем в этом примере.
const int IR_RECEIVE_PIN = 12; // Определите номер контакта для ИК-датчика
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;
IR_RECEIVE_PIN: Эта константа определяет цифровой контакт, подключённый к сигнальному контакту вашего ИК-приёмника. Если вы подключили его к другому контакту, измените номер здесь.A_1B,A_1A,B_1B,B_1A: Эти константы соответствуют четырём управляющим контактам на вашем драйвере двигателей. Они управляют скоростью и направлением левого и правого двигателей.
Далее вы найдёте важную переменную, которая управляет поведением автомобиля.
int speed = 150;
speed: Эта переменная задаёт начальную скорость автомобиля. Значение может варьироваться от 0 до 255. В этом проекте вы можете изменить её с помощью клавиш "+" и "-" на пульте. Код также включает логику для предотвращения превышения скорости 255 или падения ниже 0. (на видео в 09:22)
Основная логика дистанционного управления обрабатывается в функции loop(). При нажатии клавиши функция decodeKeyValue() преобразует сырой ИК-код в простую строку, например, "2" для движения вперёд или "+" для увеличения скорости. Это делает последующие операторы if очень лёгкими для чтения и изменения. (на видео в 07:58)
Пользовательские функции, такие как moveForward(), turnRight() и moveLeft(), отвечают за управление двигателями. Каждая функция принимает текущую speed (скорость) в качестве аргумента. Например, moveForward(speed) приведет в движение оба двигателя вперед с заданной скоростью. Ключевое различие между «поворотом» и «движением» заключается в том, что при повороте оба колеса вращаются в противоположных направлениях, заставляя автомобиль разворачиваться на месте, тогда как при движении вращается только одно колесо, заставляя автомобиль описывать дугу вокруг неподвижного колеса. (в видео на 10:14)
Живая демонстрация проекта
После загрузки кода и включения автомобиля пульт дистанционного управления становится вашим основным интерфейсом. Демонстрация в видео highlights несколько ключевых особенностей поведения:
- Управление скоростью: Нажатие клавиши «+» увеличивает скорость на 50, а клавиши «-» уменьшает её. Скорость ограничена максимумом 255 и минимумом 0 для защиты двигателей. (в видео на 11:56)
- Кратковременное движение: При нажатии клавиши направления, например «2» (вперед) или «8» (назад), автомобиль движется в течение одной секунды, а затем автоматически останавливается. Это функция безопасности, встроенная в код. (в видео на 13:09)
- Повороты и маневрирование: Клавиши, расположенные крестом на пульте, работают как джойстик. Нажатие «4» или «6» поворачивает автомобиль влево или вправо на месте. Нажатие диагональных клавиш, таких как «1» или «3», выполняет «движение влево» или «движение вправо» — это более резкий поворот, при котором одно колесо остается неподвижным. (в видео на 16:42)
Вы можете заметить, что автомобиль не всегда движется идеально прямо. Это часто связано с незначительными различиями в двигателях или натяжением сборки автомобиля, что является обычной и нормальной характеристикой таких наборов. (в видео на 15:14)
Главы
- [00:00] Введение в ИК-пульт дистанционного управления для умного автомобиля
- [01:15] Предварительные требования и необходимые предыдущие уроки
- [01:56] Обзор документации проекта
- [02:29] Понимание функций клавиш пульта дистанционного управления
- [03:29] Пошаговое руководство по подключению ИК-приемника и светодиода
- [05:51] Открытие и загрузка кода проекта
- [07:41] Объяснение кода: цикл, декодирование клавиш и действия
- [09:22] Ограничение скорости и функции безопасности в коде
- [10:08] Объяснение функций движения двигателей
- [11:49] Живая демонстрация: тестирование управления скоростью и мигания светодиода
- [13:27] Живая демонстрация: движение вперед, назад и повороты
- [14:31] Полная демонстрация автомобиля с питанием и движением
/*
Lesson 29/31: Car-7 Controlling SunFounder Smart Car using Remote Controller
Get this code and watch video Download and resource page https://robojax.com/RJT612
*/
#include <IRremote.h>
const int IR_RECEIVE_PIN = 12; // Define the pin number for the IR Sensor
const int A_1B = 5;
const int A_1A = 6;
const int B_1B = 9;
const int B_1A = 10;
int speed = 150;
void setup() {
Serial.begin(9600);
//motor
pinMode(A_1B, OUTPUT);
pinMode(A_1A, OUTPUT);
pinMode(B_1B, OUTPUT);
pinMode(B_1A, OUTPUT);
//IR remote
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Start the IR receiver // Start the receiver
Serial.println("REMOTE CONTROL START");
}
void loop() {
if (IrReceiver.decode()) {
// Serial.println(results.value,HEX);
String key = decodeKeyValue(IrReceiver.decodedIRData.command);
if (key != "ERROR") {
Serial.println(key);
if (key == "+") {
speed += 50;
} else if (key == "-") {
speed -= 50;
} else if (key == "2") {
moveForward(speed);
delay(1000);
} else if (key == "1") {
moveLeft(speed);
} else if (key == "3") {
moveRight(speed);
} else if (key == "4") {
turnLeft(speed);
} else if (key == "6") {
turnRight(speed);
} else if (key == "7") {
backLeft(speed);
} else if (key == "9") {
backRight(speed);
} else if (key == "8") {
moveBackward(speed);
delay(1000);
}
if (speed >= 255) {
speed = 255;
}
if (speed <= 0) {
speed = 0;
}
delay(500);
stopMove();
}
IrReceiver.resume(); // Enable receiving of the next value
}
}
void moveForward(int speed) {
analogWrite(A_1B, 0);
analogWrite(A_1A, speed);
analogWrite(B_1B, speed);
analogWrite(B_1A, 0);
}
void moveBackward(int speed) {
analogWrite(A_1B, speed);
analogWrite(A_1A, 0);
analogWrite(B_1B, 0);
analogWrite(B_1A, speed);
}
void turnRight(int speed) {
analogWrite(A_1B, speed);
analogWrite(A_1A, 0);
analogWrite(B_1B, speed);
analogWrite(B_1A, 0);
}
void turnLeft(int speed) {
analogWrite(A_1B, 0);
analogWrite(A_1A, speed);
analogWrite(B_1B, 0);
analogWrite(B_1A, speed);
}
void moveLeft(int speed) {
analogWrite(A_1B, 0);
analogWrite(A_1A, speed);
analogWrite(B_1B, 0);
analogWrite(B_1A, 0);
}
void moveRight(int speed) {
analogWrite(A_1B, 0);
analogWrite(A_1A, 0);
analogWrite(B_1B, speed);
analogWrite(B_1A, 0);
}
void backLeft(int speed) {
analogWrite(A_1B, speed);
analogWrite(A_1A, 0);
analogWrite(B_1B, 0);
analogWrite(B_1A, 0);
}
void backRight(int speed) {
analogWrite(A_1B, 0);
analogWrite(A_1A, 0);
analogWrite(B_1B, 0);
analogWrite(B_1A, speed);
}
void stopMove() {
analogWrite(A_1B, 0);
analogWrite(A_1A, 0);
analogWrite(B_1B, 0);
analogWrite(B_1A, 0);
}
String decodeKeyValue(long result)
{
switch(result){
case 0x16:
return "0";
case 0xC:
return "1";
case 0x18:
return "2";
case 0x5E:
return "3";
case 0x8:
return "4";
case 0x1C:
return "5";
case 0x5A:
return "6";
case 0x42:
return "7";
case 0x52:
return "8";
case 0x4A:
return "9";
case 0x9:
return "+";
case 0x15:
return "-";
case 0x7:
return "EQ";
case 0xD:
return "U/SD";
case 0x19:
return "CYCLE";
case 0x44:
return "PLAY/PAUSE";
case 0x43:
return "FORWARD";
case 0x40:
return "BACKWARD";
case 0x45:
return "POWER";
case 0x47:
return "MUTE";
case 0x46:
return "MODE";
case 0x0:
return "ERROR";
default :
return "ERROR";
}
}
Common Course Links
Common Course Files
Вещи, которые могут вам понадобиться
-
АмазонкаSunFounder Arduino Learning Kit on AliExpresss.click.aliexpress.com
-
Амазонка
-
Амазонка
-
Амазонка
-
Амазонка
Ресурсы и ссылки
-
Внешний
Файлы📁
Библиотеки Arduino (zip)
-
Исходный код обучающего набора 3-в-1 Smart Car от SunFounder
3in1-kit-main-v2.zip12.80 MB