Проект 11: Робот который ездит по линии
Этот проект позволяет создать робота, который следует за линией и выполняет различные виды поворотов, используя четыре датчика линии и библиотеку AlashMotorControlX2 для управления моторами. Робот распознает черную линию на белой поверхности и корректирует свое направление движения на основе показаний датчиков.

Этот проект основан на роботе, собранном из набора 4WD Smart Car Kit v1.0, который будет следовать за линией и выполнять различные виды поворотов с помощью четырех датчиков линии. Используя управление двумя моторами через библиотеку AlashMotorControlX2, робот будет обнаруживать и следовать за черной линией на белом фоне. В этом проекте робот будет выполнять нормальные и резкие повороты в зависимости от показаний датчиков линии.
Принцип работы
Датчики линии определяют, находится ли робот на линии или вне ее. В зависимости от показаний датчиков, Arduino принимает решение о направлении движения робота: вперед, налево, направо, резкий поворот налево или резкий поворот направо. Моторы управляются через библиотеку AlashMotorControlX2.
Настройка чувствительности датчиков линии
Чтобы робот мог точно следовать за линией, необходимо правильно настроить чувствительность каждого датчика линии. Для этого необходимо выполнить следующие шаги:
Настройка чувствительности датчиков:
Каждый датчик линии имеет потенциометр, с помощью которого можно регулировать его чувствительность. Поворачивайте потенциометр, пока датчик не начнет стабильно реагировать на линию.
Для точной настройки датчиков можно использовать специальный проект «Датчик линии», в котором подробно описан процесс настройки чувствительности датчиков. Обратитесь к этому проекту для получения более детальной информации.
Тестирование и корректировка:
После настройки чувствительности датчиков, протестируйте робота на линии. Убедитесь, что робот корректно распознает линию и выполняет необходимые повороты.
Если робот не следует линии должным образом, попробуйте скорректировать чувствительность датчиков и скорость моторов.
Продолжайте регулировать настройки, пока робот не начнет двигаться идеально по линии.
Пример кода
// Подключаем библиотеку
#include <AlashMotorControlX2.h>
// Определение пинов для моторов (стиль AlashMotorControlX2)
// Мотор A - Левый мотор
const unsigned int PIN_IN1_A = 9; // Пин IN1 левого мотора (Логика HIGH = вперед для мотора A)
const unsigned int PIN_IN2_A = 8; // Пин IN2 левого мотора (Логика LOW = вперед для мотора A)
const unsigned int PIN_EN_A = 10; // Пин Enable (PWM) левого мотора - должен быть PWM-пином!
// Мотор B - Правый мотор
const unsigned int PIN_IN1_B = 7; // Пин IN1 правого мотора (Логика HIGH = вперед для мотора B)
const unsigned int PIN_IN2_B = 6; // Пин IN2 правого мотора (Логика LOW = вперед для мотора B)
const unsigned int PIN_EN_B = 5; // Пин Enable (PWM) правого мотора - должен быть PWM-пином!
// Инициализация двух моторов для L298N с PWM (Enable пинами)
// Используем конструктор с 6 параметрами
AlashMotorControlX2 motors(PIN_IN1_A, PIN_IN2_A, PIN_EN_A,
PIN_IN1_B, PIN_IN2_B, PIN_EN_B,
DRIVER_L298N, // Явно указываем тип драйвера (по умолчанию L298N)
DRIVER_L298N);
// Определение пинов для датчиков линии
const unsigned int SENSOR_EXTREME_LEFT = 2; // Крайний левый датчик
const unsigned int SENSOR_CENTER_LEFT = 3; // Центральный левый датчик
const unsigned int SENSOR_CENTER_RIGHT = 4; // Центральный правый датчик
const unsigned int SENSOR_EXTREME_RIGHT = 12; // Крайний правый датчик
// Определение состояний робота
#define STATE_FORWARD 0
#define STATE_RIGHT 1
#define STATE_LEFT 2
#define STATE_SUPER_RIGHT 3
#define STATE_SUPER_LEFT 4
#define STATE_STOP 5
int state = STATE_FORWARD; // Начальное состояние
// Параметры скорости
int SpeedAll = 80; // Базовая скорость (0-255)
int SuperTurnSpeedAll = 150; // Скорость для резких поворотов (0-255)
int TurnSpeedAll = 100; // Скорость для обычных поворотов (0-255)
// Переменные для хранения состояния датчиков
boolean centerLeftActive = false;
boolean centerRightActive = false;
boolean extremeLeftActive = false;
boolean extremeRightActive = false;
void setup() {
Serial.begin(9600);
while (!Serial) { ; }
Serial.println("Line Follower - AlashMotorControlX2 (L298N with PWM)");
pinMode(SENSOR_EXTREME_LEFT, INPUT);
pinMode(SENSOR_CENTER_LEFT, INPUT);
pinMode(SENSOR_CENTER_RIGHT, INPUT);
pinMode(SENSOR_EXTREME_RIGHT, INPUT);
motors.setSpeed(SpeedAll);
Serial.println("Setup complete.");
}
void loop() {
// --- Чтение состояния датчиков линии ---
extremeLeftActive = (digitalRead(SENSOR_EXTREME_LEFT) == HIGH);
centerLeftActive = (digitalRead(SENSOR_CENTER_LEFT) == HIGH);
centerRightActive = (digitalRead(SENSOR_CENTER_RIGHT) == HIGH);
extremeRightActive = (digitalRead(SENSOR_EXTREME_RIGHT) == HIGH);
// --- Определение целевого состояния ---
int targetState;
if (centerLeftActive == centerRightActive && extremeLeftActive == extremeRightActive) {
targetState = STATE_FORWARD;
} else if (centerLeftActive) {
targetState = STATE_LEFT;
} else if (centerRightActive) {
targetState = STATE_RIGHT;
} else if (extremeLeftActive) {
targetState = STATE_SUPER_LEFT;
} else if (extremeRightActive) {
targetState = STATE_SUPER_RIGHT;
} else {
targetState = STATE_FORWARD;
}
Serial.println(targetState);
if (state == targetState) {
return;
}
state = targetState;
switch (state) {
case STATE_FORWARD:
goForward();
Serial.println("F");
break;
case STATE_RIGHT:
turnRight();
Serial.println("R");
break;
case STATE_LEFT:
turnLeft();
Serial.println("L");
break;
case STATE_SUPER_RIGHT:
turnSuperRight();
Serial.println("SR");
break;
case STATE_SUPER_LEFT:
turnSuperLeft();
Serial.println("SL");
break;
case STATE_STOP:
stopMotors();
Serial.println("S");
break;
}
delay(50);
}
// --- Функции управления движением ---
void goForward() {
motors.setSpeed(SpeedAll);
motors.forward();
}
void turnLeft() {
int turnSpeed = constrain(SpeedAll + TurnSpeedAll, 0, 255);
motors.setSpeedA(turnSpeed);
motors.setSpeedB(turnSpeed);
motors.backwardA();
motors.forwardB();
}
void turnRight() {
int turnSpeed = constrain(SpeedAll + TurnSpeedAll, 0, 255);
motors.setSpeedA(turnSpeed);
motors.setSpeedB(turnSpeed);
motors.forwardA();
motors.backwardB();
}
void turnSuperLeft() {
int superTurnSpeed = constrain(SpeedAll + SuperTurnSpeedAll, 0, 255);
motors.setSpeedA(superTurnSpeed);
motors.setSpeedB(superTurnSpeed);
motors.backwardA();
motors.forwardB();
}
void turnSuperRight() {
int superTurnSpeed = constrain(SpeedAll + SuperTurnSpeedAll, 0, 255);
motors.setSpeedA(superTurnSpeed);
motors.setSpeedB(superTurnSpeed);
motors.forwardA();
motors.backwardB();
}
void stopMotors() {
motors.stop();
// Для резкой остановки (торможения) используйте:
// motors.HardStop();
}
// --- Пример для TA6586 ---
#include <AlashMotorControlX2.h>
#include <AlashMotorDriverType.h> // Подключаем для использования DRIVER_TA6586
// Определение пинов для моторов TA6586
const unsigned int PIN_IN1_A = 9; // Пин IN1 для левого мотора (PWM)
const unsigned int PIN_IN2_A = 10; // Пин IN2 для левого мотора (PWM)
const unsigned int PIN_IN1_B = 5; // Пин IN1 для правого мотора (PWM)
const unsigned int PIN_IN2_B = 6; // Пин IN2 для правого мотора (PWM)
// Инициализация двух моторов для драйвера TA6586
AlashMotorControlX2 motors(PIN_IN1_A, PIN_IN2_A,
PIN_IN1_B, PIN_IN2_B,
DRIVER_TA6586,
DRIVER_TA6586);
// Определение пинов для датчиков линии
const unsigned int SENSOR_EXTREME_LEFT = 2;
const unsigned int SENSOR_CENTER_LEFT = 3;
const unsigned int SENSOR_CENTER_RIGHT = 4;
const unsigned int SENSOR_EXTREME_RIGHT = 12;
// Определение состояний робота
#define STATE_FORWARD 0
#define STATE_RIGHT 1
#define STATE_LEFT 2
#define STATE_SUPER_RIGHT 3
#define STATE_SUPER_LEFT 4
#define STATE_STOP 5
int state = STATE_FORWARD;
int SpeedAll = 80;
int SuperTurnSpeedAll = 150;
int TurnSpeedAll = 100;
boolean right = false;
boolean left = false;
boolean Sright = false;
boolean Sleft = false;
void setup() {
Serial.begin(9600);
while (!Serial) { ; }
Serial.println("Line Follower Robot - AlashMotorControlX2 (TA6586 Driver)");
pinMode(SENSOR_EXTREME_LEFT, INPUT);
pinMode(SENSOR_CENTER_LEFT, INPUT);
pinMode(SENSOR_CENTER_RIGHT, INPUT);
pinMode(SENSOR_EXTREME_RIGHT, INPUT);
Serial.println("Setup complete. Starting loop...");
}
void loop() {
Sleft = (digitalRead(SENSOR_EXTREME_LEFT) == HIGH);
left = (digitalRead(SENSOR_CENTER_LEFT) == HIGH);
right = (digitalRead(SENSOR_CENTER_RIGHT) == HIGH);
Sright = (digitalRead(SENSOR_EXTREME_RIGHT) == HIGH);
int targetState;
if (left == right && Sleft == Sright) targetState = STATE_FORWARD;
else if (left) targetState = STATE_LEFT;
else if (right) targetState = STATE_RIGHT;
else if (Sleft) targetState = STATE_SUPER_LEFT;
else if (Sright) targetState = STATE_SUPER_RIGHT;
else targetState = STATE_FORWARD;
if (state == targetState) {
return;
}
state = targetState;
switch (state) {
case STATE_FORWARD:
forward();
break;
case STATE_RIGHT:
rightTurn();
break;
case STATE_LEFT:
leftTurn();
break;
case STATE_SUPER_RIGHT:
superRightTurn();
break;
case STATE_SUPER_LEFT:
superLeftTurn();
break;
case STATE_STOP:
stopMotors();
break;
}
delay(10);
}
// --- Функции управления движением (Адаптированы для TA6586) ---
void forward() {
int constrainedSpeed = constrain(SpeedAll, 0, 255);
motors.setSpeed(constrainedSpeed);
motors.forward();
}
void leftTurn() {
int turnSpeed = constrain(SpeedAll + TurnSpeedAll, 0, 255);
motors.setSpeedA(turnSpeed);
motors.setSpeedB(turnSpeed);
motors.backwardA();
motors.forwardB();
}
void rightTurn() {
int turnSpeed = constrain(SpeedAll + TurnSpeedAll, 0, 255);
motors.setSpeedA(turnSpeed);
motors.setSpeedB(turnSpeed);
motors.forwardA();
motors.backwardB();
}
void superLeftTurn() {
int superTurnSpeed = constrain(SpeedAll + SuperTurnSpeedAll, 0, 255);
motors.setSpeedA(superTurnSpeed);
motors.setSpeedB(superTurnSpeed);
motors.backwardA();
motors.forwardB();
}
void superRightTurn() {
int superTurnSpeed = constrain(SpeedAll + SuperTurnSpeedAll, 0, 255);
motors.setSpeedA(superTurnSpeed);
motors.setSpeedB(superTurnSpeed);
motors.forwardA();
motors.backwardB();
}
void stopMotors() {
motors.stop();
// Для резкой остановки (торможения) с TA6586 (оба IN пина HIGH):
// motors.HardStop();
}
Заключение
Этот проект позволяет создать робота, который следует за линией и выполняет различные виды поворотов, используя четыре датчика линии и библиотеку AlashMotorControlX2 для управления моторами. Важно правильно настроить чувствительность датчиков линии и отрегулировать скорость робота, чтобы он мог корректно следовать за линией. Для более детальной информации по настройке датчиков линии обратитесь к проекту «Датчик линии». Экспериментируйте с настройками и компонентами, чтобы убедиться, что робот работает корректно и следует за линией.