Проект 3: Движение по квадрату

Робот Фобо едет по квадрату

Введение

Первый автономный режим! 🤖

Робот Фобо сам поедет по квадрату: вперёд → поворот 90° → вперёд → поворот → 4 раза и вернётся примерно на старт!

Траектория движения

Вариант 1: Простой код (на таймерах)

Этот код использует функции из Проекта 2. Можно менять время для калибровки.

/*
 * Проект 3: Движение по квадрату
 * Простой вариант на таймерах
 * Использует функции из Проекта 2
 */

// Пины моторов (из Проекта 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;   // PWM правых моторов
const int ENB = 6;   // PWM левых моторов

// Калибровочные скорости из Проекта 2
int speedLeft = 200;   // Скорость левых моторов (Motor B)
int speedRight = 180;  // Скорость правых моторов (Motor A)

// Времена движения (можно менять для калибровки!)
int turnTime90 = 500;   // Время для поворота на 90° (мс)
int moveTime = 2000;    // Время для проезда стороны (мс)

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("Старт через 3 секунды!");
  delay(3000);
}

// Движение вперёд (из Проекта 2)
void moveForward() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, speedRight);  // Правые моторы
  analogWrite(ENB, speedLeft);   // Левые моторы
}

// Поворот налево (из Проекта 2)
void turnLeft() {
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);   // Правые моторы вперёд
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);  // Левые моторы назад
  analogWrite(ENA, speedRight);
  analogWrite(ENB, speedLeft);
}

// Остановка моторов
void stopMotors() {
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, LOW);
  analogWrite(ENA, 0);
  analogWrite(ENB, 0);
}

void loop() {
  Serial.println("\n--- Квадрат ---");

  // 4 стороны квадрата
  for (int side = 1; side <= 4; side++) {
    Serial.print("Сторона ");
    Serial.println(side);

    moveForward();
    delay(moveTime);
    stopMotors();
    delay(300);

    turnLeft();
    delay(turnTime90);
    stopMotors();
    delay(500);
  }

  Serial.println("✓ Готово!\n");
  delay(10000);  // Пауза 10 секунд перед следующим циклом
}

Как калибровать:

  1. Если робот проезжает слишком мало/много — измените moveTime (больше = дальше)

  2. Если поворот не 90° — измените turnTime90 (больше = больше угол)

  3. Если едет по дуге — вернитесь к Проекту 2, настройте speedLeft и speedRight

Параметры для калибровки

Вариант 2: С библиотекой

С AlashMotorControlLite (установка см. Проект 2):

Код:

/*
 * Проект 3: Движение по квадрату
 * С библиотекой AlashMotorControlLite
 * Конфигурация из Проекта 2
 */

#include <AlashMotorControlLite.h>

// Создаём объекты моторов (конфигурация из Проекта 2)
// Left motor (Motor B): IN3=D8, IN4=D12, ENB=D6
// Right motor (Motor A): IN1=D4, IN2=D2, ENA=D5
AlashMotorControlLite motorLeft(DIR_DIR_PWM, 8, 12, 6);
AlashMotorControlLite motorRight(DIR_DIR_PWM, 4, 2, 5);

// Параметры движения
int speed = 80;          // Скорость: -100...100
int turnTime = 500;      // Время поворота на 90° (мс)
int moveTime = 2000;     // Время движения вперёд (мс)

void setup() {
  Serial.begin(9600);
  Serial.println("Робот Фобо: Квадрат (с библиотекой)");
  Serial.println("Старт через 3 секунды!");
  delay(3000);
}

// Движение вперёд
void moveForward() {
  motorLeft.setSpeed(speed);
  motorRight.setSpeed(speed);
}

// Поворот налево (правые вперёд, левые назад)
void turnLeft() {
  motorLeft.setSpeed(-speed);  // Левые назад
  motorRight.setSpeed(speed);  // Правые вперёд
}

// Остановка моторов
void stopMotors() {
  motorLeft.stop();
  motorRight.stop();
}

void loop() {
  Serial.println("\n--- Квадрат ---");

  // 4 стороны квадрата
  for (int i = 0; i < 4; i++) {
    Serial.print("Сторона ");
    Serial.println(i + 1);

    moveForward();
    delay(moveTime);
    stopMotors();
    delay(300);

    turnLeft();
    delay(turnTime);
    stopMotors();
    delay(500);
  }

  Serial.println("✓ Готово!\n");
  delay(10000);  // Пауза 10 секунд перед следующим циклом
}

Загрузка и тест

  1. Загрузите код (без батарей!)

  2. Найдите свободное место 2×2 метра

  3. Поставьте робота, включите питание (старт через 3 сек!)

  4. Робот проедет квадрат и вернётся примерно на старт (±10-20 см — норма для таймеров)

Эксперименты

1. Маленький квадрат

Уменьшите время: moveTime = 1000; (половина времени = половина расстояния)

2. Прямоугольник

// Длинная сторона
moveForward(); delay(moveTime); stopMotors(); delay(300);
turnLeft(); delay(turnTime90); stopMotors(); delay(500);

// Короткая сторона
moveForward(); delay(moveTime / 2); stopMotors(); delay(300);
turnLeft(); delay(turnTime90); stopMotors(); delay(500);

// Повторить 2 раза

3. Треугольник

Измените поворот на 120°: delay(turnTime90 * 4 / 3);

Сделайте 3 стороны вместо 4:

for (int i = 0; i < 3; i++) {
  moveForward(); delay(moveTime); stopMotors(); delay(300);
  turnLeft(); delay(turnTime90 * 4 / 3); stopMotors(); delay(500);
}

4. Восьмёрка

Два круга: левый + правый. Для круга — 8 поворотов по 45° (turnTime90 / 2).

Поиск неисправностей

Робот не вернулся на старт: Подберите moveTime или turnTime90. Ошибка ±15 см — нормально для таймеров.

Робот едет по дуге: Откалибруйте моторы (см. Проект 2).

Разные поверхности: На ковре/линолеуме разное трение — подберите свои значения.

Заключение

🎉 Первый автономный режим готов! Сохраните откалиброванные значения — пригодятся в следующих проектах.

Что дальше: Проект 4 (сервопривод), Проект 5 (ультразвуковой датчик), Проект 6 (следование за рукой).