Your cart is currently empty!


♦
Jekaterina Guzek, Õpimapp / Portfolio
В предыдущем проекте мы использовали транзистор для управления двигателем, которым мы могли управлять только скоростью двигателя.
Пару слов о L293D
Для управления двигателем в одном или другом направлении необходимо изменить полярность клемм двигателя. Здесь нам на помощь приходит драйвер двигателя
L293D (или SN754410). Это четырехканальный драйвер двигателя, предназначенный для управления двигателями, реле или другими индуктивными электрическими устройствами. То есть, можно управлять двигателем напрямую. В микросхему встроены защитные диоды, которые защищают от электрического люфта, вызванного индуктивностью.
Компоненты:
Схема:
Код:
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
}
}
Одна кнопка включает, друга выключает моторичик
Компоненты:
Схема:
так же использовался видео, которое посмотрели перед начал сборки машинки
Код:
// ПЕРЕМЕННЫЕ ДЛЯ ИЗМЕРЕНИЯ РАССТОЯНИЯ
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);
Что происходит при припятствии:
В другом случии едит вперед.
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см | Назад → Стоп → Поворот направо → Стоп |
Сначала плату взяли, что больше, но в ходе работы изменили ее на более компактную, чтобы слишком не был задран перед с ультрозвукавыми датчиками.
Тут как раз и заменили, на этапе сборка
Желтый и красный был для начальных тестов провода
Почти готов к тестам и залития кода наш робот
Первые запуск нашего робота после залития кода
Далее на видио видно, как робот справляется с припятствиями