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

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

- L293D
- Мотор
- Батарей
- Резистр 220 ом
- кнопка
Схема:

Код:
| 123456789101112131415161718192021222324252627282930 | intswitchPin = 2; // переключатель 1 intmotor1Pin1 = 3; // пин 2 (L293D) intmotor1Pin2 = 4; // пин 7 (L293D) intenablePin = 9; // пин 1 (L293D) voidsetup() { // входы pinMode(switchPin, INPUT); // выходы pinMode(motor1Pin1, OUTPUT); pinMode(motor1Pin2, OUTPUT); pinMode(enablePin, OUTPUT); // активировать мотор1 digitalWrite(enablePin, HIGH); }voidloop() { // если переключатель в положении 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од:
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 | intswitchPin = 2; // lüliti 1 intswitchPin2 = 7; // lüliti 2 intpotPin = A0; // potentsiomeeter intmotor1Pin1 = 3; // viik 2 (L293D) intmotor1Pin2 = 4; // viik 7 (L293D) intenablePin = 9; // viik 1(L293D) voidsetup() { // sisendid pinMode(switchPin, INPUT); pinMode(switchPin2, INPUT); //väljundid pinMode(motor1Pin1, OUTPUT); pinMode(motor1Pin2, OUTPUT); pinMode(enablePin, OUTPUT); } voidloop() { //mootori kiirus intmotorSpeed = 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шт акумулятор с кнопкой питания
- провода (мама-папа/папа-папа)
Схема:

так же использовался видео, которое посмотрели перед начал сборки машинки
Код:
| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 | // ПЕРЕМЕННЫЕ ДЛЯ ИЗМЕРЕНИЯ РАССТОЯНИЯconstinttrigPinFront = 3;constintechoPinFront = 2;// ПЕРЕМЕННЫЕ ДЛЯ МОТОРОВconstintmot1f = 6;constintmot1b = 5;constintmot2f = 11;constintmot2b = 10;intmot_speed = 200; // скорость моторов// ЛОГИЧЕСКИЕ ПЕРЕМЕННЫЕconstintdist_stop = 15;// ПЕРЕМЕННЫЕ ДЛЯ ТАЙМЕРАunsigned longpreviousMillis = 0;constlonginterval = 100; // интервал в миллисекундах// ИНИЦИАЛИЗАЦИЯvoidsetup() { pinMode(trigPinFront, OUTPUT); pinMode(echoPinFront, INPUT); pinMode(mot1f, OUTPUT); pinMode(mot1b, OUTPUT); pinMode(mot2f, OUTPUT); pinMode(mot2b, OUTPUT); Serial.begin(9600);}// ОСНОВНОЙ ЦИКЛ ПРОГРАММЫvoidloop() { unsigned longcurrentMillis = millis(); if(currentMillis - previousMillis >= interval) { previousMillis = currentMillis; intdistanceFront = 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); } }}// ФУНКЦИЯ ИЗМЕРЕНИЯ РАССТОЯНИЯintping(inttrigPin, intechoPin) { intdistances[3]; for(inti = 0; i < 3; i++) { digitalWrite(trigPin, LOW); delay(2); digitalWrite(trigPin, HIGH); delay(10); digitalWrite(trigPin, LOW); longduration = pulseIn(echoPin, HIGH); distances[i] = duration / 58; } // Сортировка массива и поиск медианы for(inti = 0; i < 2; i++) { for(intj = i + 1; j < 3; j++) { if(distances[i] > distances[j]) { inttemp = distances[i]; distances[i] = distances[j]; distances[j] = temp; } } } returndistances[1]; // медианное значение}// ФУНКЦИИ УПРАВЛЕНИЯ МОТОРАМИvoidmotors_forward() { analogWrite(mot1f, mot_speed); analogWrite(mot2f, mot_speed); digitalWrite(mot1b, LOW); digitalWrite(mot2b, LOW);}voidmotors_back() { digitalWrite(mot1f, LOW); digitalWrite(mot2f, LOW); analogWrite(mot1b, mot_speed); analogWrite(mot2b, mot_speed);}voidmotors_stop() { digitalWrite(mot1f, LOW); digitalWrite(mot2f, LOW); digitalWrite(mot1b, LOW); digitalWrite(mot2b, LOW);}voidmotors_left() { analogWrite(mot1b, mot_speed); // левый мотор назад analogWrite(mot2f, mot_speed); // правый мотор вперёд}voidmotors_right() { analogWrite(mot1f, mot_speed); // левый мотор вперёд analogWrite(mot2b, mot_speed); // правый мотор назад} |
Несколько слов о коде:
Ультразвуковой датчик подключён к пинам 3 (триггер) и 2 (эхо).
Используется для измерения расстояния до препятствия спереди.
| 12 | constinttrigPinFront = 3;constintechoPinFront = 2; |
Назначение пинов для управления двумя моторами (через L298N) — вперёд/назад для каждого.
Скорость задаётся переменной mot_speed.
| 12345 | constintmot1f = 6; // левый мотор вперёдconstintmot1b = 5; // левый мотор назадconstintmot2f = 11; // правый мотор вперёдconstintmot2b = 10; // правый мотор назадintmot_speed = 200; // скорость вращения моторов (макс. 255) |
Если расстояние меньше 15 см, робот считает, что перед ним препятствие, и совершает манёвр.
| 1 | constintdist_stop = 15; |
Устанавливается таймер, чтобы проверять расстояние раз в 100 мс, не нагружая loop.
| 12 | unsigned longpreviousMillis = 0;constlonginterval = 100; |
Настраиваются режимы пинов. Включается последовательный порт.
| 1234567891011 | voidsetup() { pinMode(trigPinFront, OUTPUT); pinMode(echoPinFront, INPUT); pinMode(mot1f, OUTPUT); pinMode(mot1b, OUTPUT); pinMode(mot2f, OUTPUT); pinMode(mot2b, OUTPUT); Serial.begin(9600);} |
Проверка: прошло ли 100 мс с последнего измерения? Если да — измеряем расстояние.
| 1 | if(currentMillis - previousMillis >= interval) |
Получаем расстояние с ультразвукового датчика с помощью функции ping().
| 1 | intdistanceFront = ping(trigPinFront, echoPinFront); |
Что происходит при припятствии:
- едет назад 300 мс,
- останавливается,
- поворачивает направо 300 мс,
- снова останавливается.
В другом случии едит вперед.
| 1234567891011121314 | 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 замера и вычисляется медиана — среднее значение среди трёх, отсекая шум.
| 1 | for(inti = 0; i < 3; i++) |
Преобразование времени в расстояние (см) (58 — это коэффициент, зависящий от скорости звука (343 м/с)).
| 1 | duration / 58; |
Вперёд: оба мотора вращаются вперёд.
| 123456 | voidmotors_forward() { analogWrite(mot1f, mot_speed); analogWrite(mot2f, mot_speed); digitalWrite(mot1b, LOW); digitalWrite(mot2b, LOW);} |
Назад: оба мотора вращаются в обратную сторону.
| 123456 | voidmotors_back() { digitalWrite(mot1f, LOW); digitalWrite(mot2f, LOW); analogWrite(mot1b, mot_speed); analogWrite(mot2b, mot_speed);} |
Поворот направо: левый мотор вперёд, правый — назад.
| 1234 | voidmotors_right() { analogWrite(mot1f, mot_speed); // левый мотор вперёд analogWrite(mot2b, mot_speed); // правый мотор назад} |
Остановка обоих моторов.
| 123456 | voidmotors_stop() { digitalWrite(mot1f, LOW); digitalWrite(mot2f, LOW); digitalWrite(mot1b, LOW); digitalWrite(mot2b, LOW);} |
Поведение робота
| Ситуация | Действие робота |
|---|---|
| Препятствий нет | Едет вперёд |
| Препятствие ближе 15см | Назад → Стоп → Поворот направо → Стоп |
Фотографии и видео проделаной работы
Сначала плату взяли, что больше, но в ходе работы изменили ее на более компактную, чтобы слишком не был задран перед с ультрозвукавыми датчиками.


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


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



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



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