Проект 2: Управление моторами L298N
Введение
Робот Фобо собран! Пора научить его двигаться! 🚗
В Проекте 1 вы собрали робота и подключили все компоненты. Теперь напишем код для управления моторами через драйвер L298N.
Примечание
Предварительные требования: Робот Фобо полностью собран (Проект 1), батареи заряжены
Как работает L298N
Драйвер моторов L298N получает команды от Arduino и управляет моторами, используя питание от батарей.
Управление: - IN1, IN2 — направление Motor A (правые моторы) - IN3, IN4 — направление Motor B (левые моторы) - ENA, ENB — скорость (ШИМ 0-255)
Управление направлением (IN1-IN4)
L298N имеет 2 канала (Motor A и Motor B), каждый управляется двумя входами:
IN1/IN3 |
IN2/IN4 |
Результат |
|---|---|---|
HIGH |
LOW |
Вращение вперёд |
LOW |
HIGH |
Вращение назад |
LOW |
LOW |
Стоп (свободное вращение) |
HIGH |
HIGH |
Стоп (тормоз) |
Пример:
// Motor A вперёд
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
// Motor B назад
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Управление скоростью (ENA, ENB)
ШИМ (PWM) управляет скоростью мотора через analogWrite():
ENA (D5) — скорость левых моторов
ENB (D6) — скорость правых моторов
Значения: 0 (стоп), 127 (50%), 255 (100%)
analogWrite(ENA, 180); // Средняя скорость
analogWrite(ENA, 255); // Полная скорость
Первое движение
Создадим программу для движения вперёд.
Полный код:
/*
* Проект 2: Управление моторами L298N
* Первый тест движения робота Фобо
*/
// Определение пинов для моторов
const int IN1 = 4; // Направление Motor A (правая сторона)
const int IN2 = 2;
const int IN3 = 8; // Направление Motor B (левая сторона)
const int IN4 = 12;
const int ENA = 5; // ШИМ скорость Motor A (правые)
const int ENB = 6; // ШИМ скорость Motor B (левые)
void setup() {
// Настройка всех пинов как OUTPUT
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
Serial.begin(9600);
Serial.println("========================================");
Serial.println(" Робот Фобо: Тест моторов");
Serial.println("========================================");
}
void moveForward(int speed) {
// Motor A (правая сторона) вперёд
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed);
// Motor B (левая сторона) вперёд
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed);
Serial.println("→ Движение вперёд");
}
void stopMotors() {
// Остановка обоих моторов
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 0);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENB, 0);
Serial.println("■ Стоп");
}
void loop() {
moveForward(150); // Едем вперёд на средней скорости
delay(2000); // 2 секунды
stopMotors(); // Останавливаемся
delay(1000); // Пауза 1 секунда
// Цикл повторяется
}
Загрузка и тестирование
Опасно
Выньте батареи перед загрузкой кода через USB! (см. Урок 1)
Результат: Робот едет вперёд 2 сек → стоп 1 сек → повторяется.
Расширенный код: Все направления движения
Полный набор функций для управления роботом:
/*
* Проект 2: Полный контроль моторов
* Все направления движения для робота Фобо
*/
// Определение пинов для моторов
const int IN1 = 4; // Направление Motor A (правая сторона)
const int IN2 = 2;
const int IN3 = 8; // Направление Motor B (левая сторона)
const int IN4 = 12;
const int ENA = 5; // ШИМ скорость Motor A (правые)
const int ENB = 6; // ШИМ скорость Motor B (левые)
// Глобальные переменные для скорости
int defaultSpeed = 180; // Скорость по умолчанию (0-255)
void setup() {
// Настройка пинов
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
Serial.begin(9600);
Serial.println("========================================");
Serial.println(" Робот Фобо: Полный контроль моторов");
Serial.println("========================================");
Serial.println();
}
// Движение вперёд
void moveForward(int speed) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, speed);
analogWrite(ENB, speed);
Serial.print("→ Вперёд | Скорость: ");
Serial.println(speed);
}
// Движение назад
void moveBackward(int speed) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENA, speed);
analogWrite(ENB, speed);
Serial.print("← Назад | Скорость: ");
Serial.println(speed);
}
// Поворот налево (левые моторы назад, правые вперёд)
void turnLeft(int speed) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW); // Правые моторы вперёд (Motor A)
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH); // Левые моторы назад (Motor B)
analogWrite(ENA, speed);
analogWrite(ENB, speed);
Serial.print("↺ Поворот налево | Скорость: ");
Serial.println(speed);
}
// Поворот направо (левые моторы вперёд, правые назад)
void turnRight(int speed) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH); // Правые моторы назад (Motor A)
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW); // Левые моторы вперёд (Motor B)
analogWrite(ENA, speed);
analogWrite(ENB, speed);
Serial.print("↻ Поворот направо | Скорость: ");
Serial.println(speed);
}
// Остановка
void stopMotors() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENA, 0);
analogWrite(ENB, 0);
Serial.println("■ Стоп");
}
// Тестовая программа
void loop() {
Serial.println("\n--- Начало цикла тестирования ---");
// Вперёд
moveForward(defaultSpeed);
delay(2000);
stopMotors();
delay(1000);
// Назад
moveBackward(defaultSpeed);
delay(2000);
stopMotors();
delay(1000);
// Поворот налево
turnLeft(defaultSpeed);
delay(1000);
stopMotors();
delay(1000);
// Поворот направо
turnRight(defaultSpeed);
delay(1000);
stopMotors();
delay(3000); // Пауза 3 секунды перед новым циклом
}
Калибровка моторов
Проблема: Даже при одинаковом ШИМ моторы вращаются с разной скоростью из-за различий в обмотках, износа и трения. Робот едет по дуге вместо прямой.
Решение: Подобрать разные значения ШИМ для левых и правых моторов.
Метод калибровки:
Запустите робота вперёд на 3 секунды (на открытом пространстве)
Если уходит влево → увеличьте скорость левых моторов
Если уходит вправо → увеличьте скорость правых моторов
Повторяйте, пока не поедет прямо
Калибровочный код:
/*
* Калибровка моторов робота Фобо
*/
const int IN1 = 4;
const int IN2 = 2;
const int IN3 = 8;
const int IN4 = 12;
const int ENA = 5;
const int ENB = 6;
// Калибровочные значения ШИМ (подбираются вручную)
int speedLeft = 180; // Скорость левых моторов (Motor B)
int speedRight = 180; // Скорость правых моторов (Motor A)
void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
Serial.begin(9600);
Serial.println("Калибровка моторов");
Serial.print("Левые: ");
Serial.print(speedLeft);
Serial.print(" | Правые: ");
Serial.println(speedRight);
}
void moveForwardCalibrated() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENA, speedRight); // Индивидуальная скорость для правых (Motor A)
analogWrite(ENB, speedLeft); // Индивидуальная скорость для левых (Motor B)
}
void stopMotors() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
analogWrite(ENA, 0);
analogWrite(ENB, 0);
}
void loop() {
// Едем вперёд 3 секунды для теста
moveForwardCalibrated();
delay(3000);
// Останавливаемся
stopMotors();
delay(10000); // 10 секунд на анализ результата
}
Пример калибровки:
Первый запуск: speedLeft = 180, speedRight = 180 → робот уходит влево
Второй запуск: speedLeft = 190, speedRight = 180 → всё ещё уходит влево
Третий запуск: speedLeft = 200, speedRight = 180 → робот едет прямо! ✓
Запишите калибровочные значения! Вы будете использовать их во всех последующих проектах.
Эксперименты
Эксперимент 1: Разные скорости
Цель: Понять, как скорость влияет на движение робота.
Задание: Протестируйте робота на разных скоростях (100, 150, 200, 255) и запишите наблюдения:
При какой минимальной скорости робот начинает двигаться?
Как меняется траектория движения при разных скоростях?
При какой скорости робот едет ровнее всего?
void loop() {
Serial.println("Скорость: 100");
moveForward(100);
delay(2000);
stopMotors();
delay(2000);
Serial.println("Скорость: 200");
moveForward(200);
delay(2000);
stopMotors();
delay(2000);
}
Эксперимент 2: Калибровка поворота на 90°
Цель: Научиться точно поворачивать робота на 90 градусов.
Метод: Вызовите turnLeft() и подберите время экспериментально.
void turn90Left() {
turnLeft(180);
delay(500); // Начните с 500 мс, подберите для вашего робота!
stopMotors();
}
Задание:
Поставьте робота на пол, отметьте начальное направление
Запустите функцию turn90Left()
Измерьте реальный угол поворота
Скорректируйте время в delay() пока не получите ровно 90°
Подсказка: Время зависит от скорости, трения пола и веса робота. Обычно 400-700 мс.
Поиск неисправностей
Моторы не вращаются: - Батареи заряжены? Переключатель включён? - Попробуйте скорость 255: analogWrite(ENA, 255)
Робот едет назад вместо вперёд: Поменяйте HIGH/LOW в moveForward():
digitalWrite(IN1, LOW); // Было HIGH
digitalWrite(IN2, HIGH); // Было LOW
Робот едет криво: Откалибруйте моторы (см. раздел «Калибровка моторов»)
Библиотека AlashMotorControlLite (опционально)
Официальная библиотека упрощает код: setSpeed(-100…100), stop()/brake().
Установка: Library Manager → AlashMotorControlLite → Install (подробно в Уроке 1)
#include <AlashMotorControlLite.h>
// Режим DIR_DIR_PWM: IN1, IN2, PWM(ENA/ENB)
AlashMotorControlLite motorRight(DIR_DIR_PWM, 4, 2, 5);
AlashMotorControlLite motorLeft(DIR_DIR_PWM, 8, 12, 6);
void setup() {
Serial.begin(9600);
Serial.println("Робот Фобо готов!");
}
void loop() {
// Вперёд (скорость: -100...100)
motorLeft.setSpeed(80);
motorRight.setSpeed(80);
delay(2000);
motorLeft.stop(); // Мягкая остановка (выбег 1-3 сек)
motorRight.stop();
delay(1000);
// Назад (отрицательные значения)
motorLeft.setSpeed(-80);
motorRight.setSpeed(-80);
delay(2000);
motorLeft.brake(); // Резкая остановка (0.1-0.5 сек)
motorRight.brake();
delay(1000);
// Поворот налево
motorLeft.setSpeed(-70);
motorRight.setSpeed(70);
delay(1000);
motorLeft.stop();
motorRight.stop();
delay(3000);
}
Заключение
Поздравляем! 🎉 Вы освоили управление моторами робота Фобо!
Вы научились: Работать с драйвером L298N, управлять направлением (IN1-IN4) и скоростью (ШИМ), создавать функции движения, калибровать моторы.
Что дальше: Проект 3 (движение по квадрату), Проект 6 (следование за рукой), Проект 7 (объезд препятствий), Проект 9 (следование по линии), Проект 14 (мастер-режим).
Важно: Сохраните ваши калибровочные значения (speedLeft, speedRight) — они понадобятся во всех следующих проектах!