Объезжающий препятствия робот является “умным” устройством, способным автоматически обнаруживать препятствия впереди себя и избегать столкновения с ними, поворачиваясь в противоположное направление от них. Это свойство позволяет роботу работать в незнакомой обстановке и является одним из ключевых требований при создании автономных роботов. Подобные работы находят широкое применение в вооруженных силах и чрезвычайных ситуациях, а также во многих других случаях, где желательно не подвергать опасности жизнь и здоровье людей.
В этой статье мы рассмотрим создание робота на основе платы Arduino и ультразвукового датчика, способного объезжать препятствия. Ультразвуковой датчик используется для обнаружения препятствий на пути робота и расчета расстояния до них. При расстоянии до препятствия, меньшего заданной границы, робот изменяет направление и продолжает движение.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress) или Nano (купить на AliExpress).
- Ультразвуковой датчик HC-SR04 (купить на AliExpress).
- Модуль драйвера двигателя LM298N (купить на AliExpress).
- Электродвигатели постоянного тока, работающие от напряжения 5V.
- Литий-ионная батарея 7.4V (купить на AliExpress).
- Колеса.
- Шасси робота.
- Соединительные провода.
Принцип работы ультразвукового датчика HC-SR04
Ультразвуковой датчик HC-SR04 используется для измерения расстояний в диапазоне 2-400 см с точностью 3 мм. Датчик состоит из ультразвукового передатчика, ультразвукового приемника и схемы управления.
Ультразвуковой датчик HC-SR04 обеспечивает на своем выходе сигнал, пропорциональный дистанции до препятствия. Датчик генерирует звуковые колебания в ультразвуковом диапазоне (после получения управляющего импульса) и после этого ждет когда они вернутся к нему (эхо), отразившись от какого-нибудь препятствия. Затем, основываясь на скорости звука (340 м/с) и времени, необходимом для того чтобы эхо достигло источника (нашего датчика), датчик обеспечивает на своем выходе сигнал, пропорциональный расстоянию до препятствия.
Как показано на рисунке сначала нам нужно инициировать датчик для измерения расстояний, для этого на его триггерный контакт (trigger pin) необходимо подать логический сигнал высокого уровня длительностью не менее 10 мкс, после этого датчик генерирует серию звуковых колебаний и после получения отраженного сигнала (эхо) датчик обеспечивает на своем выходе сигнал, пропорциональный расстоянию между ним и препятствием.
Ультразвуковой сигнал отражается от поверхности, возвращается обратно и улавливается приемником ультразвукового сигнала датчика. После этого на контакте Echo датчика устанавливается напряжение высокого уровня (high) на время, пропорциональное расстоянию до препятствия.
После этого расстояние до препятствия можно рассчитать по следующей формуле:
Distance= (Time x Speed of Sound in Air (343 m/s))/2
Также на нашем сайте вы можете посмотреть другие проекты, в которых был использован ультразвуковой датчик.
Для изготовления робота в этом проекте были использованы компоненты, которые достаточно легко приобрести. Для изготовления шасси робота можно использовать детскую игрушку или можно купить уже готовые шасси робота на AliExpress.
Схема проекта
Схема робота на Arduino, объезжающего препятствия, представлена на следующем рисунке. Как видите, в схеме мы использовали плату Arduino Nano, но эту же схему без изменений можно использовать и в случае использования платы Arduino Uno. Код программы в этом случае также останется без изменений.
Объяснение программы для Arduino
Полный код программы приведен в конце статьи, здесь же мы рассмотрим его основные фрагменты. В программе нам необходимо взаимодействовать с датчиком HC-SR04 и подавать управляющие сигналы на контакты, с которых осуществляется управление двигателями. В этом проекте не будет использовано никаких подключаемых библиотек.
Первым делом в программе необходимо инициализировать контакты, через которые происходит взаимодействие с ультразвуковым датчиком: trig pin датчика подключен к контакту 9 платы Arduino, а echo pin — к контакту 10 платы Arduino.
1 2 |
int trigPin = 9; // trig pin of HC-SR04 int echoPin = 10; // Echo pin of HC-SR04 |
Далее инициализируем контакты для взаимодействия с модулем драйвера двигателей LM298N – 4 контакта.
1 2 3 4 |
int revleft4 = 4; //REVerse motion of Left motor int fwdleft5 = 5; //ForWarD motion of Left motor int revright6 = 6; //REVerse motion of Right motor int fwdright7 = 7; //ForWarD motion of Right motor |
Затем в функции setup() зададим режимы работы контактов. 4 контакта управления двигателями и Trig pin датчика – на вывод данных (OUTPUT), Echo Pin датчика – на ввод данных (Input).
1 2 3 4 5 6 |
pinMode(revleft4, OUTPUT); // set Motor pins as output pinMode(fwdleft5, OUTPUT); pinMode(revright6, OUTPUT); pinMode(fwdright7, OUTPUT); pinMode(trigPin, OUTPUT); // set trig pin as output pinMode(echoPin, INPUT); //set echo pin as input to capture reflected waves |
Далее в функции loop() мы будем измерять расстояние до препятствий с помощью датчика HC-SR04 и на основании этого управлять вращением двигателей. Расстояние до препятствия будет определяться впереди робота. Для определения расстояния сначала будет передаваться серия ультразвуковых импульсов длительностью 10 мкс, а затем спустя 10 мкс мы будем принимать отраженный сигнал. Более подробно об измерении расстояний с помощью ультразвукового датчика и платы Arduino можно прочитать в данной статье.
1 2 3 4 5 6 7 |
digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); // send waves for 10 us delayMicroseconds(10); duration = pulseIn(echoPin, HIGH); // receive reflected waves distance = duration / 58.2; // convert to distance delay(10); |
Если расстояние до препятствия больше заранее определенного значения, то это значит, что на пути робота нет препятствия и он может продолжить движение прямо.
1 2 3 4 5 6 7 |
if (distance > 19) { digitalWrite(fwdright7, HIGH); // move forward digitalWrite(revright6, LOW); digitalWrite(fwdleft5, HIGH); digitalWrite(revleft4, LOW); } |
Если расстояние до препятствия меньше заранее определенного значения, это будет означать что впереди робота есть препятствие и его надо объехать. В этом случае робот на небольшое время останавливается, затем движется некоторое время назад, затем снова останавливается на небольшое время и после этого поворачивается в другое направление.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
if (distance < 18) { digitalWrite(fwdright7, LOW); //Stop digitalWrite(revright6, LOW); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, LOW); delay(500); digitalWrite(fwdright7, LOW); //movebackword digitalWrite(revright6, HIGH); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, HIGH); delay(500); digitalWrite(fwdright7, LOW); //Stop digitalWrite(revright6, LOW); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, LOW); delay(100); digitalWrite(fwdright7, HIGH); digitalWrite(revright6, LOW); digitalWrite(revleft4, LOW); digitalWrite(fwdleft5, LOW); delay(500); } |
Таким образом, робот получает возможность объезжать препятствия, встречающиеся у него на пути.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/* Obstacle Avoiding Robot Using Ultrasonic Sensor and Arduino NANO * Circuit Digest(www.circuitdigest.com) */ int trigPin = 9; // trig pin датчика HC-SR04 int echoPin = 10; // Echo pin датчика HC-SR04 int revleft4 = 4; //REVerse motion (движение назад) для левого двигателя int fwdleft5 = 5; //ForWarD motion (движение вперед) для левого двигателя int revright6 = 6; //REVerse motion (движение назад) для правого двигателя int fwdright7 = 7; //ForWarD motion движение вперед) для правого двигателя long duration, distance; void setup() { delay(random(500,2000)); // задержка на случайное время Serial.begin(9600); //для целей отладки, потом можно закомментировать pinMode(revleft4, OUTPUT); // set Motor pins as output pinMode(fwdleft5, OUTPUT); pinMode(revright6, OUTPUT); pinMode(fwdright7, OUTPUT); pinMode(trigPin, OUTPUT); // set trig pin as output pinMode(echoPin, INPUT); //echo pin в режим ввода данных } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); // передаем серию импульсов длительностью 10 мкс delayMicroseconds(10); duration = pulseIn(echoPin, HIGH); // принимаем отраженные импульсы distance = duration / 58.2; // рассчитываем расстояние в см delay(10); // If you dont get proper movements of your robot then alter the pin numbers (если что то работает не так, попробуйте сменить используемые контакты) if (distance > 19) { digitalWrite(fwdright7, HIGH); // движение вперед digitalWrite(revright6, LOW); digitalWrite(fwdleft5, HIGH); digitalWrite(revleft4, LOW); } if (distance < 18) { digitalWrite(fwdright7, LOW); //Stop (остановка) digitalWrite(revright6, LOW); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, LOW); delay(500); digitalWrite(fwdright7, LOW); //движение назад digitalWrite(revright6, HIGH); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, HIGH); delay(500); digitalWrite(fwdright7, LOW); //Stop (остановка) digitalWrite(revright6, LOW); digitalWrite(fwdleft5, LOW); digitalWrite(revleft4, LOW); delay(100); digitalWrite(fwdright7, HIGH); digitalWrite(revright6, LOW); digitalWrite(revleft4, LOW); digitalWrite(fwdleft5, LOW); delay(500); } } |
Видео, демонстрирующее работу робота
Нашел на youtube еще один ролик (один из самых популярных в этой тематике), в котором рассматривается создание робота, объезжающего препятствия. Он более совершенен чем рассмотренный в данной статье благодаря вращающемуся с помощью сервомотора ультразвуковому датчику. К нему есть также исходный код программы (доступен по ссылке из описания ролика), но без объяснения. Но, надеюсь, объяснение программы рассмотренного в данной статье робота поможет вам понять код программы этого более «продвинутого» робота.
25 ответов к “Объезжающий препятствия робот на Arduino”
Добрый день. Только погружаюсь в тему ардуино. Очень понравилась ваша модель. До написания сложных программ, мне ещё очень далеко. Есть идея, установить на модель постоянно крутящуюся платформу с ультразвуковым датчиком. Измеряя расстояние до препятствий модель будет выбирать самый длинный маршрут движения т.е. сможет двигаться по лабиринту. Механическая часть исполнения вращения платформы, подача и съём сигнала это вопрос другой. Мне необходимо понять, такой скетч возможен? Спасибо.
Доброе утро. Такой скетч теоретически возможен, но если вы хотите вращать платформу отдельно от робота, то это значительно усложняет проект поскольку вам нужно будет знать в какую сторону у вас смотрит робот. Тут необходим, наверное, магнитометр, чтобы определять направление куда смотрит робот. А вот если платформа будет неподвижно установлена на роботе, тогда это значительно упростит проект
Здравствуйте при загрузке скетча и нажатия на кнопку включения, ничего не происходит, не могли бы помочь с кодом, или объяснить что не так.
Добрый вечер, скорее всего у вас с аппаратной частью проекта что то не так. Попробуйте оставить в функции void loop() только строки:
digitalWrite(fwdright7, HIGH); // движение вперед
digitalWrite(revright6, LOW);
digitalWrite(fwdleft5, HIGH);
digitalWrite(revleft4, LOW);
То есть при подаче питания робот должен просто двигаться вперед. Проверьте будет ли работать ваш проект с этим простым кодом. Если нет, тогда определенно с аппаратной частью проекта (а именно с подключением двигателей) что то не так
Можно ли адаптировать эту сборку для постройки аэроглиссера (катера с пропеллерами)? Больше всего смущает намного большие обороты вала пропеллера по сравнению с колесами. Нужны другие моторчики? Понадобится ли более мощная батарея? Какие еще возможны «подводные камни»
Ну смотря каких скоростей вы хотите достигнуть на этом аэроглиссере. У нас на сайте есть статья про лодку с дистанционным управлением на Arduino — в ней для вращения пропеллеров использованы обычные электродвигатели. Если же вы хотите достигнуть больших скоростей, то тогда и моторчики понадобятся мощнее. Можете присмотреться в этом плане к BLDC моторам, они для создания дронов используются. Для более мощных моторчиков желателен и более емкий источник питания.
Спасибо за ответ. Достижение высоких скоростей не планируется. Планируется собрать в итоге примерно такую лодку, как в вами приведенном примере. Я, кстати, видел эту статью, однако моя цель не радиоуправление, а объезжающий препятствия плавающий робот.
Да не за что. Буду признателен если отпишитесь потом получилось ли у вас или нет, с какими проблемами пришлось столкнуться и как вы их преодолели. Ну хотя бы кратко
Мне нужна помощь с кнопкой, как подписать в воид сетап и воид луп?
Ну посмотрите вот эту статью для примера. В работе с кнопкой нет ничего сложного. Сначала в void setup() нужно задать режим работы контакта, к которому подключена кнопка, на ввод данных — с помощью функции pinMode(1, INPUT) (здесь 1 — номер контакта). А потом в функции void loop() с помощью функции if (digitalRead(0)==LOW) или if (digitalRead(0)==HIGH) (зависит от того каким образом подключена у вас кнопка) проверять нажата кнопка или нет
Мне нужен скетч такой: когда нажал кнопку чтобы Газонокосилка остановилась повернула и поехала.
То есть в представленный в этой статье проект робота,объезжающего препятствия, вам необходимо добавить только кнопку и немного изменить логику его работы? Просто в предыдущем сообщении вы писали и про датчик скрытой проводки, и про подключение реле
Да, если можно.
Ну тогда напишите что нужно изменить в логике движений робота из представленного здесь проекта или кратко опишите свой алгоритм движений робота. Просто из вашего предыдущего поста не совсем ясно после нажатия кнопки куда робот должен поворачивать и куда ехать. И к какому контакту Ардуино у вас кнопка будет подключена?
Кнопка куда будет подключена мне без разницы, А Алгоритм такой: робот Едет прямо когда нажал кнопку он: {
digitalWrite(fwdright7, LOW); //Stop (остановка)
digitalWrite(revright6, LOW);
digitalWrite(fwdleft5, LOW);
digitalWrite(revleft4, LOW);
delay(500);
digitalWrite(fwdright7, LOW); //движение назад
digitalWrite(revright6, HIGH);
digitalWrite(fwdleft5, LOW);
digitalWrite(revleft4, HIGH);
delay(500);
digitalWrite(fwdright7, LOW); //Stop (остановка)
digitalWrite(revright6, LOW);
digitalWrite(fwdleft5, LOW);
digitalWrite(revleft4, LOW);
delay(100);
digitalWrite(fwdright7, HIGH);
digitalWrite(revright6, LOW);
digitalWrite(revleft4, LOW);
digitalWrite(fwdleft5, LOW);
delay(500);
}
Так если вы сами всю программу самостоятельно написали, то какая вам помощь нужна от меня? Написать команду для проверки того нажата кнопка или нет?
Здравствуйте!
Решили собрать с сыном умную тележку и остановились на вашем проекте. Закупили на Али шасси и недостающее железо, за полтора часа всё скидали, прошили и от души повеселились. Дело в том, что от 2-х Li батареек тележка не едет, а летит. Дубовая резина на колесах несет её юзом в стену, а когда она с грохотом отлетает на открытое пространство, то начинает без остановки крутиться, как сумасшедший волчок. Разве что дым из под колес не идет. Не знаю, почему вы не использовали возможность драйвера LM298 модулировать выходное напряжение. Всё усложнение состоит в двух проводках от контроллера (я использовал пины 3 и 11) на крайние штырьки платы драйвера, предварительно сняв с них перемычки. В скетч нужно добавить всего несколько строчек (тут был вопрос о возможности регулирования скорости). Назначить выходы контроллера, управляющие скоростью моторов и собственно значение ШИМ, например так:
int pin_ML = 3;
int pin_MR = 11;
uint8_t power = 105; // установил опытным путем. При меньших значениях в моем случае не хватает мощи крутить колеса.
pinMode(pin_ML, OUTPUT);
pinMode(pin_MR, OUTPUT);
и включить их в работу
analogWrite(pin_ML, power);
analogWrite(pin_MR, power); Вот и всё. Скорость можно менять на каждом этапе цикла – быстро подъехал, плавно отъехал или наоборот, крутить колеса с разной скоростью, дрифтовать и т.д. В заключение отмечу, что с этой китайской кинематикой ничего путного не соберешь. Эти желтые мотор-редукторы мало того, что крутятся каждый со своей скоростью, так она еще и плавает.
Здравствуйте, спасибо за такой подробный совет. Могу добавить его в основной текст статьи. Может у вас видео или фото есть собранной вами умной тележки?
Про ШИМ я в своем ответе про регулировку скорости тоже писал, но без конкретики, как у вас
Кабель на 220 вольт нужен чтобы проложить его под газоном или на газоне чтобы газонокосилка не выезжала за кабель.
Добрый день! Поможете пожалуйста со скотчем. Я хочу сделать робот газонокосилку. Использовать кабель на 220 вольт а на газонокосилке датчик скрытой проводки на каждом датчики есть светодиод или зуммер я нашёл конструктор для сборки скрытово искателя проводки, только там где зуммер или светодиод подключить реле и когда датчик скрытой проводки замечает кабель газонокосилка останавливается на полсекунды едет назад ждёт пол секунды и поворачивает на лево вот по такому алгоритму нужен скетч. Заранее Большое спасибо
Добрый вечер. К сожалению при такой «удаленной» помощи тяжеловато помочь с вашим не самым простым проектом. Тут и схема газонокосилки понадобится, и схема конструктора для скрытого искания проводки и работа с высокими напряжениями. Я помогал здесь кому мог со скетчами при такой удаленной работе, но у них проекты были в разы проще чем ваш
А можно ставить скорость в скетче?
Напрямую нельзя потому что она зависит от используемых двигателей на роботе, но косвенно увеличить/уменьшить скорость движения робота можно изменяя величины задержек в программе.
Скорость можно будет менять если немного усложнить схему проекта и осуществлять регулировку скорости с помощью ШИМ сигнала
Добрый день. При реализации этого проекта возникла трудность. Датчик расстояния не хотел работать. При попытке решить эту проблему выяснилось что на схеме выход «trig» подключён к 10 выводу, а вывод «echo» к 9 выводу, а в программе наоборот. При переключении выводов в соответствии с программой всё заработало нормально.
Добрый день. Спасибо что указали на опечатку (к сожалению, они иногда случаются), надеюсь, ваш комментарий поможет другим пользователям, которые будут пытаться повторить данный проект