2.5. Проект.md
Поздравляем! Мы научились управлять двигателями, использовать колёса Mecanum, считывать данные с энкодеров и датчиков линии. Теперь пришло время объединить все эти знания в одном большом и интересном проекте. Мы создадим программу, которая превратит нашего робота в «питомца» — он будет самостоятельно следовать за объектом (например, вашей рукой), поддерживая постоянную дистанцию.
- Если объект далеко - робот подъезжает.
- Если объект слишком близко - робот отъезжает.
- Если объект на нужном расстоянии - робот стоит на месте.
Эта задача не только интересна, но и очень полезна. Она научит нас главному — объединять данные с датчиков с системой управления движением, что является основой любой автономной робототехники.
Программирование с помощью классов
До сих пор мы писали код в простом, процедурном стиле. Но когда проект становится сложным, такой код превращается в «спагетти», в котором легко запутаться. Профессиональные программисты используют объектно-ориентированное программирование (ООП), где вся логика работы с компонентом (например, мотором или датчиком) упаковывается в отдельный, самодостаточный блок — класс.
Класс — это шаблон по которому создаются объекты. Например, у нас может быть класс
Motor, который описывает, как в принципе управлять мотором. АleftFrontMotorиrightFrontMotor— это уже объекты, созданные по этому шаблону, каждый со своими пинами, но с одинаковым поведением.
Этот подход делает код чистым, читаемым и легко масштабируемым. В этом проекте мы будем использовать готовые классы для мотора и ультразвукового дальномера.
Подключение
Схема подключения остаётся той же, что и в предыдущих работах. Нам понадобятся:
- Четыре мотора, подключённые через два драйвера
L9110Sк пинам, которые мы определим в коде. - Ультразвуковой дальномер
HC-SR04. Подключим его к пинам 7 (Trig) и 6 (Echo). - Питание. Не забывайте про внешнее питание для моторов и общей земле с
Рудироном.
Программа
В этой программе мы впервые используем классы. Обратите внимание, насколько чистым и понятным становится основной код, когда вся сложная логика спрятана внутри объектов.
// --- Класс для управления ультразвуковым дальномером ---
class Ultrasonic {
int trig;
int echo;
public:
Ultrasonic(int trig, int echo) {
this->trig = trig;
this->echo = echo;
}
void begin() {
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
}
int read() {
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
// Преобразуем время в сантиметры и ограничиваем до 300 см
long duration = pulseIn(echo, HIGH);
int cm = duration / 58;
return constrain(cm, 0, 300);
}
};
// --- Класс для управления одним мотором через драйвер L9110S ---
class Motor {
int dirPin;
int speedPin;
public:
Motor(int dir, int speed) {
dirPin = dir;
speedPin = speed;
}
void begin() {
pinMode(dirPin, OUTPUT);
pinMode(speedPin, OUTPUT);
}
// dir=0 - вперёд, dir=1 - назад
void run(int dir, int speed) {
digitalWrite(dirPin, dir);
analogWrite(speedPin, speed);
}
};
// --- Создаём объекты для наших устройств ---
// Левые моторы
Motor leftFront(13, 12);
Motor leftBack(11, 8);
// Правые моторы
Motor rightFront(A0, 20);
Motor rightBack(A1, A2);
// Дальномер
Ultrasonic ultrasonic(7, 6);
// --- Глобальные переменные ---
int baseSpeed = 200; // Базовая скорость движения робота (0-255)
void setup() {
// Инициализируем все наши объекты
leftFront.begin();
leftBack.begin();
rightFront.begin();
rightBack.begin();
ultrasonic.begin();
Serial.begin(9600); // Для отладки
}
void loop() {
// Считываем расстояние до объекта
int distance = ultrasonic.read();
Serial.print("Расстояние: ");
Serial.println(distance);
// --- Основная логика ---
if (distance > 30 && distance > 0) {
// Если объект далеко, едем вперёд
forward(baseSpeed);
} else if (distance < 20 && distance > 0) {
// Если объект слишком близко, отъезжаем назад
backward(baseSpeed);
} else {
// Если объект в "зоне комфорта" (20-30 см) или датчик не видит ничего (distance = 0),
// стоим на месте.
stopMotors();
}
delay(50); // Небольшая пауза между циклами
}
// --- Функции для управления движением робота ---
void forward(int speed) {
leftFront.run(0, speed);
leftBack.run(0, speed);
rightFront.run(0, speed);
rightBack.run(0, speed);
}
void backward(int speed) {
leftFront.run(1, speed);
leftBack.run(1, speed);
rightFront.run(1, speed);
rightBack.run(1, speed);
}
void stopMotors() {
leftFront.run(0, 0);
leftBack.run(0, 0);
rightFront.run(0, 0);
rightBack.run(0, 0);
}
Проверка работы
- Загрузите код на
Рудирон. - Поставьте робота на пол.
- Поместите перед ним руку или другой крупный предмет.
- Двигайте рукой - когда вы её отдаляете, робот должен ехать за ней, когда приближаете - отъезжать.
Выводы
В этом итоговом проекте вы объединили все знания, полученные в этой главе. Вы научились:
- Программировать с использованием классов, что является шагом к профессиональной разработке.
- Интегрировать датчики с системой движения, создавая автономное поведение.
- Отлаживать и настраивать логику робота для достижения нужного результата.
Вы создали не просто набор движущихся частей, а настоящего робота, способного самостоятельно реагировать на окружающий мир. Теперь у вас есть надежная «база» для создания собственных, ещё более сложных и удивительных проектов!