Mootor ja kaugusemõõtmise andur

Тестовая работа двигателя

В предыдущем проекте мы использовали транзистор для управления двигателем, которым мы могли управлять только скоростью двигателя. 

Пару слов о L293D

Для управления двигателем в одном или другом направлении необходимо изменить полярность клемм двигателя. Здесь нам на помощь приходит драйвер двигателя  
L293D  (или SN754410). Это четырехканальный драйвер двигателя, предназначенный для управления двигателями, реле или другими индуктивными электрическими устройствами. То есть, можно управлять двигателем напрямую. В микросхему встроены защитные диоды, которые защищают от электрического люфта, вызванного индуктивностью.

  • ss  – питание микросхемы +5В
  • s  – внешнее питание до +36В
  • ENABLE1  и  ENABLE2  – активировать двигатель 1 и двигатель 2
  • INPUT1  и  INPUT2  – для управления двигателем 1
  • OUTPUT1  и  OUTPUT2  – для подключения двигателя 1
  • INPUT3  и  INPUT4  – для управления двигателем 2
  • OUTPUT3  и  OUTPUT4  – для подключения двигателя 2
  • GND  – земля

Компоненты:

  • L293D
  • Мотор
  • Батарей
  • Резистр 220 ом
  • кнопка

Схема:

Код:

int switchPin = 2; // переключатель 1  
int motor1Pin1 = 3; // пин 2 (L293D)   
int motor1Pin2 = 4; // пин 7 (L293D)   
int enablePin = 9; // пин 1 (L293D)    

void setup() {
  // входы  
  pinMode(switchPin, INPUT);  
  
  // выходы  
  pinMode(motor1Pin1, OUTPUT);  
  pinMode(motor1Pin2, OUTPUT);  
  pinMode(enablePin, OUTPUT);  
  
  // активировать мотор1  
  digitalWrite(enablePin, HIGH);  
}

void loop() {
  // если переключатель в положении HIGH, то двигать мотор в одну сторону:  
  if (digitalRead(switchPin) == HIGH) {
    digitalWrite(motor1Pin1, LOW); // пин 2 (L293D) LOW  
    digitalWrite(motor1Pin2, HIGH); // пин 7 (L293D) HIGH  
  } 
  // если переключатель в положении LOW, то двигать мотор в другую сторону:  
  else {
    digitalWrite(motor1Pin1, HIGH); // пин 2 (L293D) HIGH  
    digitalWrite(motor1Pin2, LOW); // пин 7 (L293D) LOW  
  }
}

Далее мы добавим еще к нашему проекту

еще одну кнопку резистр 220ом и потенциометр 

Схема:

Kод:

int switchPin = 2; // lüliti 1 

int switchPin2 = 7; // lüliti 2 

int potPin = A0; // potentsiomeeter 

int motor1Pin1 = 3; // viik 2 (L293D) 

int motor1Pin2 = 4; // viik 7 (L293D) 

int enablePin = 9; // viik 1(L293D) 

 void setup() { 

 // sisendid 

 pinMode(switchPin, INPUT); 

 pinMode(switchPin2, INPUT); 

 //väljundid 

 pinMode(motor1Pin1, OUTPUT); 

 pinMode(motor1Pin2, OUTPUT); 

 pinMode(enablePin, OUTPUT); 

} 

 void loop() { 

 //mootori kiirus 

 int motorSpeed = analogRead(potPin); 

 //aktiveeri mootor 

 if (digitalRead(switchPin2) == HIGH)

{ 

 analogWrite(enablePin, motorSpeed); 

 } 

else 

{ analogWrite(enablePin, 0); } 

 // kui lüliti on HIGH, siis liiguta mootorit ühes suunas: 

 if (digitalRead(switchPin) == HIGH)

{

 digitalWrite(motor1Pin1, LOW); // viik 2 (L293D) LOW 

 digitalWrite(motor1Pin2, HIGH); // viik 7 (L293D) HIGH 

 } 

 // kui lüliti on LOW, siis liiguta mootorit teises suunas: 

 else 

{ 

 digitalWrite(motor1Pin1, HIGH); // viik 2 (L293D) HIGH 

 digitalWrite(motor1Pin2, LOW); // viik 7 (L293D) LOW 

 } 

}

Одна кнопка включает, друга выключает моторичик

Проект Самоходная машина

Компоненты:

  • 1 шт. комплект шасси для робота с 2 колесами (2WD-1)
  • 1 шт. Arduino Uno
  • 1 шт. ультразвуковой модуль HC-SR04
  • 1 шт. модуль управления двигателями L298N
  • 1 шт. USB-кабель
  • 1шт акумулятор с кнопкой питания
  • провода (мама-папа/папа-папа)

Схема:

так же использовался видео, которое посмотрели перед начал сборки машинки

Код:

// ПЕРЕМЕННЫЕ ДЛЯ ИЗМЕРЕНИЯ РАССТОЯНИЯ
const int trigPinFront = 3;
const int echoPinFront = 2;

// ПЕРЕМЕННЫЕ ДЛЯ МОТОРОВ
const int mot1f = 6;
const int mot1b = 5;
const int mot2f = 11;
const int mot2b = 10;
int mot_speed = 200; // скорость моторов

// ЛОГИЧЕСКИЕ ПЕРЕМЕННЫЕ
const int dist_stop = 15;

// ПЕРЕМЕННЫЕ ДЛЯ ТАЙМЕРА
unsigned long previousMillis = 0;
const long interval = 100;  // интервал в миллисекундах

// ИНИЦИАЛИЗАЦИЯ
void setup() {
  pinMode(trigPinFront, OUTPUT);
  pinMode(echoPinFront, INPUT);
  
  pinMode(mot1f, OUTPUT);
  pinMode(mot1b, OUTPUT);
  pinMode(mot2f, OUTPUT);
  pinMode(mot2b, OUTPUT);
  
  Serial.begin(9600);
}

// ОСНОВНОЙ ЦИКЛ ПРОГРАММЫ
void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    int distanceFront = ping(trigPinFront, echoPinFront);

    if (distanceFront <= dist_stop) {
      motors_back();  // едет назад
      delay(300);
      motors_stop();  // остановка
      delay(100);
      
      motors_right();  // Простой обход: всегда поворот направо
      delay(300);
      motors_stop();  // остановка
      delay(100);
    } else {
      motors_forward();  // едет вперёд
      delay(100);
    }
  }
}

// ФУНКЦИЯ ИЗМЕРЕНИЯ РАССТОЯНИЯ
int ping(int trigPin, int echoPin) {
  int distances[3];
  for (int i = 0; i < 3; i++) {
    digitalWrite(trigPin, LOW);
    delay(2);
    digitalWrite(trigPin, HIGH);
    delay(10);
    digitalWrite(trigPin, LOW);
    long duration = pulseIn(echoPin, HIGH);
    distances[i] = duration / 58;
  }

  // Сортировка массива и поиск медианы
  for (int i = 0; i < 2; i++) {
    for (int j = i + 1; j < 3; j++) {
      if (distances[i] > distances[j]) {
        int temp = distances[i];
        distances[i] = distances[j];
        distances[j] = temp;
      }
    }
  }
  return distances[1];  // медианное значение
}

// ФУНКЦИИ УПРАВЛЕНИЯ МОТОРАМИ
void motors_forward() {
  analogWrite(mot1f, mot_speed);
  analogWrite(mot2f, mot_speed);
  digitalWrite(mot1b, LOW);
  digitalWrite(mot2b, LOW);
}

void motors_back() {
  digitalWrite(mot1f, LOW);
  digitalWrite(mot2f, LOW);
  analogWrite(mot1b, mot_speed);
  analogWrite(mot2b, mot_speed);
}

void motors_stop() {
  digitalWrite(mot1f, LOW);
  digitalWrite(mot2f, LOW);
  digitalWrite(mot1b, LOW);
  digitalWrite(mot2b, LOW);
}

void motors_left() {
  analogWrite(mot1b, mot_speed); // левый мотор назад
  analogWrite(mot2f, mot_speed); // правый мотор вперёд
}

void motors_right() {
  analogWrite(mot1f, mot_speed); // левый мотор вперёд
  analogWrite(mot2b, mot_speed); // правый мотор назад
}

Несколько слов о коде:

Ультразвуковой датчик подключён к пинам 3 (триггер) и 2 (эхо).
Используется для измерения расстояния до препятствия спереди.

const int trigPinFront = 3;
const int echoPinFront = 2;

Назначение пинов для управления двумя моторами (через L298N) — вперёд/назад для каждого.
Скорость задаётся переменной mot_speed.

const int mot1f = 6;  // левый мотор вперёд
const int mot1b = 5;  // левый мотор назад
const int mot2f = 11; // правый мотор вперёд
const int mot2b = 10; // правый мотор назад
int mot_speed = 200;  // скорость вращения моторов (макс. 255)

Если расстояние меньше 15 см, робот считает, что перед ним препятствие, и совершает манёвр.

const int dist_stop = 15;

Устанавливается таймер, чтобы проверять расстояние раз в 100 мс, не нагружая loop.

unsigned long previousMillis = 0;
const long interval = 100;

Настраиваются режимы пинов. Включается последовательный порт.

void setup() {
  pinMode(trigPinFront, OUTPUT);
  pinMode(echoPinFront, INPUT);
  
  pinMode(mot1f, OUTPUT);
  pinMode(mot1b, OUTPUT);
  pinMode(mot2f, OUTPUT);
  pinMode(mot2b, OUTPUT);
  
  Serial.begin(9600);
}

Проверка: прошло ли 100 мс с последнего измерения? Если да — измеряем расстояние.

if (currentMillis - previousMillis >= interval)

Получаем расстояние с ультразвукового датчика с помощью функции ping().

int distanceFront = ping(trigPinFront, echoPinFront);

Что происходит при припятствии:

  • едет назад 300 мс,
  • останавливается,
  • поворачивает направо 300 мс,
  • снова останавливается.

В другом случии едит вперед.

if (distanceFront <= dist_stop) {
  motors_back();  // Назад
  delay(300);
  motors_stop();  // Стоп
  delay(100);
  motors_right();  // Поворот направо
  delay(300);
  motors_stop();  // Стоп
  delay(100);
}
else {
  motors_forward();  // Иначе едет вперёд
  delay(100);
}

Для точности производится 3 замера и вычисляется медиана — среднее значение среди трёх, отсекая шум.

for (int i = 0; i < 3; i++)

Преобразование времени в расстояние (см) (58 — это коэффициент, зависящий от скорости звука (343 м/с)).

duration / 58;

Вперёд: оба мотора вращаются вперёд.

void motors_forward() {
  analogWrite(mot1f, mot_speed);
  analogWrite(mot2f, mot_speed);
  digitalWrite(mot1b, LOW);
  digitalWrite(mot2b, LOW);
}

Назад: оба мотора вращаются в обратную сторону.

void motors_back() {
  digitalWrite(mot1f, LOW);
  digitalWrite(mot2f, LOW);
  analogWrite(mot1b, mot_speed);
  analogWrite(mot2b, mot_speed);
}

Поворот направо: левый мотор вперёд, правый — назад.

void motors_right() {
  analogWrite(mot1f, mot_speed); // левый мотор вперёд
  analogWrite(mot2b, mot_speed); // правый мотор назад
}

Остановка обоих моторов.

void motors_stop() {
  digitalWrite(mot1f, LOW);
  digitalWrite(mot2f, LOW);
  digitalWrite(mot1b, LOW);
  digitalWrite(mot2b, LOW);
}

Поведение робота

СитуацияДействие робота
Препятствий нетЕдет вперёд
Препятствие ближе 15смНазад → Стоп → Поворот направо → Стоп

Фотографии и видео проделаной работы

Сначала плату взяли, что больше, но в ходе работы изменили ее на более компактную, чтобы слишком не был задран перед с ультрозвукавыми датчиками.

Тут как раз и заменили, на этапе сборка

Желтый и красный был для начальных тестов провода

Почти готов к тестам и залития кода наш робот

Первые запуск нашего робота после залития кода

Далее на видио видно, как робот справляется с припятствиями

Где можно применять такой проект

1. Образование и обучение

  • Изучение робототехники: основы сенсоров, управления моторами, логики избегания препятствий.
  • Программирование: работа с Arduino IDE, структура кода, использование таймеров, функций и циклов.
  • Электроника: понимание работы с модулями (L298N, HC-SR04, HC-05), питание и подключение компонентов.

2. Платформа для экспериментов

  • Для тестирования:
    • Алгоритмы автономного движения.
    • Умные стратегии обхода препятствий.
    • Различные датчики (инфракрасные, компасы, GPS и т.д.).

3. Домашнее использование

  • Автоматические игрушки для детей — реагирует на препятствия, можно «погонять» по дому.
  • Обучающая платформа для ребёнка: весело + практическое программирование.

4. Прототипирование и хобби

  • Создание роботов для соревнований — например, лабиринты, гонки.