Ходячий робот своими руками на ардуино

Обновлено: 08.07.2024

В этой статье мы займемся постройкой своего робота с нуля. То, что у нас получится, смотрите на фото ниже. Робот будет ездить как самостоятельно, так и под управлением смартфона. А еще мы рассмотрим постройку своего мобильного робота с нуля.


3D принтер

Если я хочу построить робота я должен определиться с выбором платформы, на которую я буду устанавливать двигатели, платы, аккумуляторы. Я, конечно, могу приобрести готовый вариант, но интереснее сделать платформу самому. Такая платформа точно будет соответствовать вашим требованиям. Платформу можно сделать из орг. Стекла, фанеры, а я сделаю ее из пластика.

Вы можете сказать, что платформу самому делать неудобно и потребуется множество инструментов, начиная от кернера и заканчивая шлифовальным станком. А я говорю, что нам понадобится воображение и 3D принтер.


3D принтер? Всем, наверное, знаком обычный офисный принтер, который может распечатать на А4 нужный нам текст. Так вот, 3D принтер – это принтер, который может распечатать нужную деталь. Есть разные 3d принтеры. У меня принтер с технологией FDM (послойное наплавление). Какие еще есть технологии 3d печати, можно узнать в интернете.

Многие 3D принтеры работают на Arduino. При желании, можно собрать свой 3D принтер. Главная идея 3D принтера в том, что можно печатать абсолютно любую вещь, мы же напечатаем корпус для робота.

Для начала определимся с описанием платформы. Я хочу, чтобы платформа была двухколесной и в нее должны помещаться Arduino, питание, моторы и несколько датчиков.

Теперь нужно нарисовать макет платформы на бумаге и разместить на ней нужные компоненты. Например, вот так.


Когда макет будет готов, нужно будет сделать 3D модель платформы. Для этого существует множество программ. Я, обычно, пользуюсь программой Компас. Я не буду учить работать с Компасом, но если вам интересно, можете посмотреть в интернете или попросить в комментариях сделать урок по Компасу.

Вот такая платформа получилась у меня.


После этого нужно преобразовать 3D модель в G-код, понятный 3d принтеру. Для этого существуют специальные программы - слайсеры. Я использую программу Repetier-Host со слайсером Sli3er. Вот как выглядит деталь, готовая к распечатке.


А вот распечатанная модель.


Только недавно у нас была идея, а готовая деталь уже перед нами. С помощью 3D принтера можно создавать уникальные вещи в единичных экземплярах. 3D принтер – классная штука. Советую всем!

Моторы

Теперь нужно подумать о том, как наш мобильный робот будет двигаться. Первое, что приходит на ум – колеса. Так и поступим.

Если кто помнит, мы уже пробовали подключать мотор к Arduino. Кто не помнит, не знает или не читал – смотрим тут. В подключении мотора с помощью MOSFET есть существенные недостатки – невозможно оперативно менять скорость и направление вращения. Пришло время научить Arduino управлять моторчиками по-настоящему!

Для этого можно использовать микросхему L293D. L293D позволяет управлять сразу двумя моторами, с током 600 мА на канал и пиковым до 1000 мА, а если объединить каналы – то до 1200 мА и 2000 мА пикового тока. Про объединение расскажу ниже.

Для начала, как всегда, следует посмотреть на Datasheet, чтобы разобраться, куда и что подключать. Если вы не знаете о микросхемах, то стоит прочитать эту статью.

Приступим. Соберем простенькую схему с одним мотором и порулим им. Внимание на схему сборки.


Если не знаете английский или просто не разобрались в Datasheet, то вот описание подключения. Нумерацию микросхем, надеюсь, все знают или узнали из статьи про микросхемы.

  • Пин 1 – Отвечает за скорость вращения мотора. Аналогичный - на пине 9. Принимает значения от 0 до 255, что без проблем можно организовать с помощью PWM.Я подсоединил EN к пятому пину Arduino, который поддерживает PWM.
  • Пины 2 и 7 – Отвечают за направление движения мотора. Аналогичные - на пинах 10 и 15. Подача логической единицы на один из этих пинов заставит мотор крутиться в одну сторону (зависит от подключения мотора), подача логической единицы на другой – заставит мотор крутиться в обратную сторону.
  • Пины 3 и 6 – К ним нужно подключать мотор. Полярность не важна, от подключения будет зависеть только направление вращения. Аналогичные - на пинах 11 и 14.
  • Пины 4 и 5 – Это земля. Думаю, не нуждается в пояснении. Аналогичные – 12 и 13.
  • Пин 8 – Питание для моторов. На него нужно подать питание в диапазоне от 4.5 до 36 Вольт
  • Пин 16 – на него подается логическая единица с Arduino. 5 Вольт, если что.

Отлично! Мотор подключили. Теперь можно и покодить.

Как работает? Работает просто. При нажатии на левую кнопку колесо крутится в одну сторону, а при нажатии на правую – в другую. Поворотом ручки потенциометра можно регулировать скорость вращения моторчика. Действие нашей испытательной установки для моторчиков показано на видео.

З.Ы. Да, знаю, что качество видео не супер, но постараюсь найти нормальную камеру и организовать место для съемки как можно скорее.

Теперь про соединение каналов L293. Если хочется подключить более мощный моторчик, то можно объединить каналы.

Первый способ – параллельно соединить аналогичные выводы микросхемы, что даст прибавку к максимальной силе тока в два раза. Минус – к одной микросхеме можно подключить только один моторчик.

Второй способ – сверху на L293 напаять другую L293. Берем и напаиваем пин 1 к пину 1, пин 2 к пину 2 и так далее. Этот способ так же дает прибавку к силе тока в два раза, но, в отличие от первого – оставляет возможность управлять сразу двумя моторчиками. У вас может возникнуть идея – а не напаять ли мне еще парочку L293? К сожалению, последующая напайка микросхем не приведет к увеличению силы тока еще на 600 мА. Прибавка будет незначительна.

“Э-эх, придется убирать мой 12-Вольтовый мотор… “ Не спешите расстраиваться. Для более мощных моторов подойдет старший брат L293 - L298, но сейчас мы не будем его рассматривать. Это мы сделаем чуть позже.

Motor Shield

Согласитесь, что с таким пучком проводов выглядит это все не очень. Чтобы избавиться от него можно спаять схему с L293 на печатной или макетной плате для пайки, но что делать, если паять не хочется или не умеется? Для этого существуют готовые решения в виде шилдов для Arduino, например. Я расскажу про один из них – Motor Shield V1 от DK Electronics.

Вот, собственно, фото шилд.


К минусам платы. Для работы с шилдом используются почти все цифровые пины, кроме 0, 1, 2, 13. Как мы знаем, пины 0 и 1 используются Arduino для прошивки, поэтому их лучше не использовать.

Есть тут и хорошая сторона. Если не подключать сервы, например, освобождаются пины 9 и 10, а если не использовать какой-либо из моторов, то освободятся пины 3, 5, 6, 11, в зависимости от неиспользуемого мотора. И еще. Нам остаются доступны шесть аналоговых выходов, которые при желании можно использовать как цифровые.

Начнем подключение моторов. Ради эксперимента сделаем робота, который ездит вперед, назад, а также вращается вокруг собственной оси. В качестве платформы я взял собственную разработку, описанную выше. Вы можете взять, что душе угодно, главное – подходящее по характеристикам.

Нам понадобятся


    – Можно использовать любую другую форм фактора Arduino UNO. Leonardo или Iskra, например.
  • Motor Shield – Подойдут и другие версии этого шилда.
  • Моторчики на 6В – Можно взять любые, подходящие по характеристикам к Motor Shield.
  • Колеса диаметром 42мм – Колеса подходящие к моторчикам и платформе
  • Крепления для моторчиков – Моторчики нужно прикрепить к платформе. Возьмите подходящие к вашей.
  • Питание – Я взял блок аккумуляторов и получил на выходе около 5 Вольт, что недостаточно для питания моторов и Arduino, поэтому я подключил DC/DC преобразователь и поднял напряжение до 9В. Если нет преобразователя, то можно воспользоваться обычной кроной, подключив ее к питанию Arduino.

Пришло время собрать нашего робота.

Шаг 1

Соединяем Arduino и Motor Shield.


Шаг 2

Собираем моторы и прикручиваем их на платформу.


Шаг 3

Собираем питание через повышающий преобразователь.


Для тех, у кого Крона. Не забудьте перемычку!


Шаг 4

Прикручиваем моторы к Motor шилду с Arduino.


Шаг 5


Шаг 6 (Опционально)

Прикрепим крышку – для эстетики.


У нас есть готовый робот. Теперь пришло время его запрограммировать. Смотрим на код.

Отлично! Время проверять. Вот видео с моей проверки. А у вас как?

“Ты что-то говорил про робототехнические платы?” – могут сказать те, кто читал вводный урок 2 части курcа. Да, такие платы есть. Рассмотрим робототехническую платформу Strela.


Мечта робототехника. (Почти). Преимущества платы я описывал тут. Сразу к делу.

На ней- то и установлен старший брат L293 – L298. А еще пины выведены тройками, что как раз подходит для подключения многих датчиков.

Эту плату можно подключить вместо Arduino UNO и Motor Shield. Кроме того, ребята из Амперки написали библиотеку для работы со Стрелой, что делает управление моторами достаточно тривиальной задачей.

Для тех, кто не знал, рассказываю. К каждой нормальной библиотеке существуют примеры по ее использованию и библиотека для Стрелы не исключение. Для того чтобы их найти, заходим во вкладку Файл -> Примеры -> Strela. Там выбираем пример StrelaMotors, где выполняется скетч, похожий на скетч с использованием Motor Shield. Кстати, к Motor Shield тоже есть примеры. Если интересно – смотрите.

Что еще можно сделать со Стрелой – смотрите ниже.А мы переходим к беспроводной связи по Bluetooth.

Bluetooth

Робот, который сам ездит по комнате это, конечно, хорошо, но хотелось бы порулить роботом самостоятельно. Для этого нужно организовать связь между Arduino и управляющим устройством.

В качестве управляющего устройства я выбрал смартфон. Связь мы будем организовывать по протоколу Bluetooth, поэтому пришло время знакомиться.


Это модуль HC-06. Я не буду особо вдаваться в подробности, но кому интересно, переходим сюда. Наша цель – порулить роботом со смартфона. Начнем, пожалуй.

Для начала нужно подключить HC-06 к Arduino. Подключение будем осуществлять при помощи Software Serial. Эта библиотека позволяет эмулировать Serial Port на нужных нам пинах. Ради эксперимента попробуем сделать это на пинах A0(RX) и A1(TX). Зачем? Помним, что я рассказывал про Motor Shield.

  • Vcc – к 5V
  • GND – к GND
  • RX – к TX
  • TX – к RX


Я подключу HC-06 к роботу, которого мы собирали выше. Для этого воспользуемся тремя полосами на Motor Shield.


Робот готов. Осталось его запрограммировать.

Прежде чем читать код, вы должны кое-что узнать. Моторы не идеальны, как и все в этом мире. Даже два мотора из одной партии, идущие друг за другом, будут немного отличаться, что скажется на разнице в количестве оборотов при одном и том же напряжении. Если моторы просто подключить к motor Shield и подать на них одинаковую скорость, а это и есть одинаковое напряжение, то робот поедет не прямо, а немного, или много, в сторону. Это можно увидеть в видео выше.

Для того чтобы этого избежать, мы будем применять корректировочные коэффициенты. У меня левое колесо крутится намного быстрее, чем правое, поэтому я поставил коэффициент 0.62 для компенсации. Значение коэффициента подбирается экспериментальным путем.

Робота прошили. Теперь займемся смартфоном.

RC controller

Для связи Arduino и смартфона через Bluetooth есть множество различных приложений. В поиске ключевыми словами будут: Arduino, Bluetooth, RC.

Я выбрал приложение под названием Bluetooth RC Controller. Оно идеально подойдет для нашей цели. При нажатии на кнопку приложение отправляет значение типа char на HC-06, который, в свою очередь, передает пришедшее значение Arduino. Значение, отправляемое при нажатии кнопки, устанавливается самостоятельно.


Чтобы установить соединение с роботом, нужно нажать на шестерню и выбрать пункт “Settings” В “Settings” нужно убедиться, что кнопки соответствуют этим отсылаемым символам, либо изменяем код Arduino.


После настройки символов можно устанавливать соединение с HC-06. Жмем на шестерню и заходим в “Connect to car” Открывается окно с сопряженными устройствами. В нем выбираем HC-06. Если его нет, то ищем с помощью “Scan for devices”. Если устройство найдено, но не хочет сопрягаться, то заходим в Bluetooth на смартфоне и сопрягаем, как обычно. Пароль стандартный – 1234. После этого заходим в “Scan for devices” и соединяемся.


Когда соединение установится, загорится зеленый огонек сверху, а HC-06 перестанет моргать. Можно начинать рулить. Полоска сверху отвечает за скорость движения.

Strela

Вернемся к Стреле. Еще одним преимуществом Стрелы является возможность установить Bluetooth XBee формата, а хорошо это тем, что другие пины остаются свободными. А так как для Стрелы есть готовая библиотека, которая помогает сократить код для управления моторами, то использовать Стрелу для управления роботом по Bluetooth очень даже стоит.

Для этого нужно подключить XBee к Стреле, прошить ее скетчем из примеров под названием “ArduinoBluetoothRCCarOnStrela” и подключиться к XBee через RC controller.

Советы

Робот у меня готов и даже ездит по команде со смартфона. Но не все может пройти гладко. Я расскажу о некоторых проблемах и их решениях, а также дам несколько советов начинающим робототехникам.

Колеса крутятся не в те стороны, в какие хотелось бы – эта проблема легко устраняется путем перестановки проводов в клемниках или программно.

Bluetooth модуль не работает – нужно проверить наличие горящего красного светодиода на модуле. Если он не горит, то проверить правильность подключения Bluetooth модуля. Если светодиод горит, но соединение ну устанавливается, нужно убедиться в том, что RX модуля соединен с TX платы и наоборот, а так же попробовать способ с сопряжением модуля с Arduino через стандартный Bluetooth интерфейс.

Робот не едет прямо – я описывал эту проблему чуть выше, когда рассказывал про Bluetooth и Motor Shield.

При езде робот неожиданно останавливается и теряется соединение с HC-06 – проблема в источнике питания. Мы знаем, что Arduino нужно не менее 7В для стабильной работы, а еще мы знаем, что моторчики очень хорошо кушают. Если поднести щупы мультиметра к клеммникам подачи напряжения и измерить напряжение при выключенных моторах, а потом их включить, то можно увидеть, что напряжение на мультиметре упадет. Причем упасть напряжение может по-разному.

Если подключен источник питания, который не может обеспечить достаточный ток для моторов, то напряжение может упасть сильно, с 9 до 5 Вольт, например, а 5В уже не будет хватать для Arduino и она перезапустится. Решение – подключить более мощное питание. Как рассчитать, я расскажу ниже.

Если подключить источник питания мощнее, то просадка напряжения может быть только в течение нескольких миллисекунд, но и их может оказаться достаточно для перезапуска контроллера. Решение – параллельно проводам питания установить конденсатор не менее чем на 1000мкФ, емкость можно определить экспериментально. Я ставил конденсатор на 3300 мкФ и на 16В. Не забываем смотреть на максимальное напряжение конденсатора.

Когда источник питания достаточно мощный, просадки напряжения не более 0.2В.

Несколько советов для начинающих робототехников

Начиная планировку робота, первым делом желательно позаботиться о расчёте мощности силовой части и подборе соответствующего источника питания. Будет обидно, если 4 батарейки ААА не потянут твои 4 6-вольтовых мотора, а места для более источника питания не останется.

Для расчета мощности ищем характеристики моторов, плат, датчиков. Из курса физики знаем, что мощность можно рассчитать по формуле P = IU, где I – сила тока, U – напряжение. С помощью этой формулы и характеристик легко рассчитать потребляемую мощность готового устройства, а зная потребляемую мощность и рабочее напряжение питания, можно узнать оптимальную силу тока, необходимую для работы устройства, зная силу тока, можно определиться с необходимой емкостью аккумулятора и время работы устройства от выбранного аккумулятора.

Если есть цель сделать “пароль” из трех символов, то не стоит программировать все три сразу. Лучше сделать пароль из одного символа, проверить его, потом из двух, а после проверки – из трех. Мне помогает.

Робот создается методом проб и ошибок. Не получится один раз запрограммировать, чтобы действие выполнялось идеально. Те же подстроечные коэффициенты на колесах, поэтому не стоит опускать руки если что-то не получается, а если совсем-совсем не получается, то можно обратиться к добрым людям на форумы или написать мне, обязательно поможем!

Заключение

Робототехника – классная штука! В скором времени, я думаю, роботы займут, а то и уже заняли место в жизни людей. Мы сделали простейшего робота-машинку с управлением со смартфона, позже займемся более серьезными проектами, ну а пока – до скорого!

Очередной простой шагающий робот на базе контроллера Arduino и сервомашинок. Данный робот примечателен тем, что в нем в качестве ног используются лопатки для еды.

Простой шагающий робот на Arduino

Шагающий робот на Arduino

Робот состоит из этих деталей:

Вернуться в рубрику:

Разработки на платформе arduino - это супер современные устройства. Платформа - это аппаратно-программный комплекс на котром можно делать различные робототехнические устройства своими

Мало что может сравниться по крутизне с разработкой высоконагруженных веб-проектов типа Facebook или ковырянии ядра Linux. В качестве примечательного исключения можно привести разработку самопальных роботов у себя дома. И знаете, что? Оказывается, полученных нами на данный момент знаний в электронике и программировании микроконтроллеров уже более чем достаточно для создания первого робота!

Управление электродвигателями из Arduino

Ну, почти достаточно. Нам понадобится управлять электродвигателями, а это мы еще не проходили. К счастью, тут все довольно просто.

Типичная схема подключения электродвигателя превосходно объяснена на wiki-сайте Амперки, поэтому я просто приведу здесь их иллюстрацию:

Типичная схема подключения электродвигателя

Там же можно прочитать интересную статью про полевые МОП-транзисторы (a.k.a. MOSFET). В отличие от биполярных транзисторов, полевые транзисторы управляются напряжением, а не током. Полевые транзисторы используются, когда нужно управлять сравнительно большим током (сотни миллиампер). Типичный полевой транзистор, используемый во многих проектах, что я видел — IRF3205.

Описанная схема позволяет вращать электродвигателем только в одну сторону. Однако колеса в роботе должны крутиться не только вперед, но и назад. Для решения этой проблемы используется конструкция под названием H-мост. При желании его можно спаять и самостоятельно, но в наше время обычно используют готовые микросхемы. Одной из самых популярных является микросхема L298P. В частности, именно она используется в Motor Shield от Амперки. Если вы полистаете даташит [PDF], то обнаружите, что это довольно скучная микросхема, построенная на транзисторах и логических вентилях — никакой магии.

Из драйверов двигателей, аналогичных L298P, стоит упомянуть L293D и L293B. Максимальный ток на канал первого составляет 0.6 А против 2 А у L298P. Зато L293D имеет встроенную диодную защиту от паразитных токов и стоит заметно дешевле. L293B также намного дешевле L298P. Максимальный ток на канал этого чипа — 1 А, встроенной диодной защиты нет.

Если вы решите изготовить свой Motor Shield при помощи ЛУТ или ФР, вот соответствующая схема для одного электродвигателя:

Схема подключения L298P

В заключение к теоретической части стоит упомянуть, что в роботах обычно используют электродвигатели с редукторами. Благодаря редуктору скорость вращения колеса уменьшается, а момент силы увеличивается. Другими словами, робот двигается медленнее, чем мог бы, зато становится способен преодолевать более сложные препятствия — взбираться на крутые горки, и так далее. Рассмотренный далее робот, к примеру, способен подъехать к стене, начать карабкаться на нее, и в результате перевернуться.

Собираем радиоуправляемого робота

Также я использовал упомянутый выше Motor Shield от Амперки. Вы можете использовать его, или любую аналогичную плату на базе чипа L298P. Наконец, нам понадобится пара NRF24L01, два адаптера со стабилизатором напряжения к ним, или, предпочтительнее, один адаптер и один Joystick Shield. Напомню, что эти устройства ранее рассматривались в заметке Arduino и беспроводная связь при помощи NRF24L01. Если вы знакомы с другими способами управления Arduino по беспроводной связи, можете использовать их, однако код придется соответствующим образом переписать.

Сборка робота осуществляется элементарно. Motor Shield ставится на Arduino. К винтовым клеммникам шилда подключаются электродвигатели, провода фиксируются при помощи отвертки. Если у вашей ходовой части 4 двигателя, подключите к каждому клеммнику по два электродвигателя, расположенных с одной стороны. В один момент времени эти двигатели все равно крутятся в одну и ту же сторону.

Клеммник питания я подключил к шести последовательно соединенным батарейкам AA. Соответствующий отсек для батареек шел вместе с гусеничной платформой. Помимо прочего, отсек еще и обеспечивает платформе низкий центр тяжести. Подойдет и другой источник питания на 9 В, например, крона. Чтобы постоянно не доставать батарейки для выключения робота, а затем не вставлять их обратно, имеет смысл припаять какой-нибудь выключатель.

На вашем Motor Shield или его аналоге обязательно должна быть перемычка, определяющая, питаются ли Arduino и шилд от одного или двух независимых источников питания. Во время программирования Arduino перемычка должна стоять на использовании двух независимых источников. После отключения Arduino от USB верните перемычку так, чтобы использовался один общий источник. Впрочем, как альтернативный вариант, можно использовать в роботе и два независимых источника питания.

Робот и пульт управления им в собранном виде:

Радиоуправляемый робот на Arduino

Дополнение: Впоследствии робот и джойстик к нему были существенно переработаны. Кроме того, был добавлен FPV. Фото улучшенной версии можно посмотреть здесь (JPG, 224 Кб).

Код прошивки робота:

typedef struct <
uint8_t directionM1 ;
uint8_t directionM2 ;
uint8_t speedM1 ;
uint8_t speedM2 ;
> EnginesState ;

const int directionM1 = 4 ;
const int speedM1 = 5 ;
const int speedM2 = 6 ;
const int directionM2 = 7 ;

const int FORWARD = HIGH ;
const int BACKWARD = LOW ;

RF24 radio ( 9 , 10 ) ;
EnginesState enginesState ;
unsigned long lastEnginesStateUpdateMs = 0 ;

void setDefaultEnginesState ( )
<
enginesState. directionM1 = FORWARD ;
enginesState. directionM2 = FORWARD ;
enginesState. speedM1 = 0 ;
enginesState. speedM2 = 0 ;
>

void setup ( )
<
setDefaultEnginesState ( ) ;

pinMode ( directionM1, OUTPUT ) ;
pinMode ( directionM2, OUTPUT ) ;
pinMode ( speedM1, OUTPUT ) ;
pinMode ( speedM2, OUTPUT ) ;

radio. begin ( ) ;
radio. setChannel ( 108 ) ;
radio. setPALevel ( RF24_PA_LOW ) ;
radio. setDataRate ( RF24_250KBPS ) ;
// radio.openWritingPipe(addresses[0]); // not used yet
radio. openReadingPipe ( 1 , addresses [ 1 ] ) ;
radio. startListening ( ) ;
>

void loop ( )
<
delay ( 10 ) ;

if ( radio. available ( ) )
<
radio. read ( & enginesState, sizeof ( enginesState ) ) ;
lastEnginesStateUpdateMs = millis ( ) ;
>
else if ( millis ( ) - lastEnginesStateUpdateMs > 500 )
<
setDefaultEnginesState ( ) ;
lastEnginesStateUpdateMs = millis ( ) ;
>

digitalWrite ( directionM1, enginesState. directionM1 ) ;
analogWrite ( speedM1, enginesState. speedM1 ) ;

digitalWrite ( directionM2, enginesState. directionM2 ) ;
analogWrite ( speedM2, enginesState. speedM2 ) ;
>

Как видите, робот просто получает направление и скорость вращения двигателей от пульта. Если пульт не посылал никаких данных в течение 500 мс, робот останавливается. NRF24L01 иногда теряет пакеты, особенно при наличии помех от самих двигателей робота. Благодаря тому, что робот какое-то время помнит последнюю полученную команду, он будет двигаться плавно, даже если 98% пакетов теряются.

typedef struct <
uint8_t directionM1 ;
uint8_t directionM2 ;
uint8_t speedM1 ;
uint8_t speedM2 ;
> EnginesState ;

/* depends on your point of view */
/*
const int FORWARD = HIGH;
const int BACKWARD = LOW;
*/
const int FORWARD = LOW ;
const int BACKWARD = HIGH ;

const int joystickX = A0 ;
const int joystickY = A1 ;
const int joystickBtn = 2 ;

const int THRESHOLD_LOW = 510 ;
const int THRESHOLD_HIGH = 530 ;

RF24 radio ( 9 , 10 ) ;

void setup ( )
<
pinMode ( joystickX, INPUT ) ;
pinMode ( joystickY, INPUT ) ;
pinMode ( joystickBtn, INPUT ) ;

radio. begin ( ) ;
radio. setChannel ( 108 ) ;
radio. setPALevel ( RF24_PA_LOW ) ;
radio. setDataRate ( RF24_250KBPS ) ;
radio. openWritingPipe ( addresses [ 1 ] ) ;
// radio.openReadingPipe(1, addresses[0]); // not used yet
>

void loop ( )
<
EnginesState enginesState ;
delay ( 10 ) ;

int x = analogRead ( joystickX ) ;
int y = analogRead ( joystickY ) ;

if ( y THRESHOLD_LOW )
<
enginesState. directionM1 = FORWARD ;
enginesState. directionM2 = FORWARD ;
enginesState. speedM1 = map ( y, THRESHOLD_LOW, 0 , 0 , 255 ) ;
enginesState. speedM2 = enginesState. speedM1 ;
>
else if ( y > THRESHOLD_HIGH )
<
enginesState. directionM1 = BACKWARD ;
enginesState. directionM2 = BACKWARD ;
enginesState. speedM1 = map ( y, THRESHOLD_HIGH, 1023 , 0 , 255 ) ;
enginesState. speedM2 = enginesState. speedM1 ;
>
else
<
enginesState. directionM1 = FORWARD ;
enginesState. directionM2 = FORWARD ;
enginesState. speedM1 = 0 ;
enginesState. speedM2 = enginesState. speedM1 ;
>

if ( x THRESHOLD_LOW )
<
enginesState. speedM2 = map ( x, THRESHOLD_LOW, 0 ,
enginesState. speedM2 , 0 ) ;
>
else if ( x > THRESHOLD_HIGH )
<
enginesState. speedM1 = map ( x, THRESHOLD_HIGH, 1023 ,
enginesState. speedM1 , 0 ) ;
>

if ( digitalRead ( joystickBtn ) == LOW ) /* rotation mode */
<
if ( x THRESHOLD_LOW )
<
enginesState. directionM1 = FORWARD ;
enginesState. directionM2 = BACKWARD ;
enginesState. speedM1 = map ( x, THRESHOLD_LOW, 0 , 0 , 255 ) ;
enginesState. speedM2 = enginesState. speedM1 ;
>
else if ( x > THRESHOLD_HIGH )
<
enginesState. directionM1 = BACKWARD ;
enginesState. directionM2 = FORWARD ;
enginesState. speedM1 = map ( x, THRESHOLD_HIGH, 1023 , 0 , 255 ) ;
enginesState. speedM2 = enginesState. speedM1 ;
>
>

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

Заключение

Как видите, роботов делать легко и приятно. Полную версию исходников к этой заметке вы найдете в этом репозитории на GitHub.

А пробовали ли вы делать роботов? Если да, то какие компоненты использовали? Если нет, собираетесь ли попробовать?

arduino робот

В этой статье я опишу процесс создания шилда управления роботом, подключение ультразвукового дальномера и реализацию алгоритма объезда препятствий. На выходе у нас должен получиться полностью автономный робот.

А прошлой статье я описывал процесс реализации управления роботом по Bluetooth через смартфон на Android. Это был первый режим работы робота. После этой статьи у нас появится второй режим. В будущем я планирую добавить еще несколько.

Создание шилда управления роботом

Для переключения между различными режимами работы я решил сделать отдельный шилд. В прошлый раз я уже использовал Proto Shield. Сегодня я его немного модернизирую под свои потребности.

Для этого нам понадобятся следующие детали:

  • Светодиоды - 7 штук
  • Кнопки - 3 штуки
  • Резисторы на 220 Ом - 6 штук
  • Резисторы на 10 кОм - 2 штуки
  • Перемычки - 5 штук
  • Разъём PBS (мама) на 16 контактов - 1 штука
  • Миниатюрная макетная плата - 1 штука

arduino робот

Все компоненты запаиваем на Proto Shield по указанной схеме (вид со стороны деталей):

Размещение элементов на плате:

arduino робот

В левом нижнем углу я вывел кнопку RESET. Она замыкает выводы RESET и GND. В левом верхнем - разъем подключения сервоприводов. Вверху светодиод с 13 дискретного вывода. Справа 2 кнопки переключения режимов (след / пред).

Каждая кнопка подтянута к земле резистором на 10 кОм.

arduino робот

Далее размещены 6 светодиодов, которые подключены к панельке контактов через резисторы на 220 Ом.

arduino робот

Светодиоды будут служить индикаторами режимов работы робота.

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

arduino робот

Подключение шилда управления роботом

Подключим провода к разъему на 16 контактов. Описывать буду назначение контактов сверху вниз. LED 1..6 - выводы светодиодов, BTN 1..2 - кнопки.

  • 1 - LED 1 - к 22 дискретному выводу Arduino
  • 2
  • 3
  • 4 - LED 2 - к 23 дискретному выводу Arduino Mega 2560
  • 5
  • 6 - BTN 1 - к 28 дискретному выводу Arduino Mega 2560
  • 7 - LED 3 - к 24 дискретному выводу Arduino Mega 2560
  • 8 - GND - к GND Arduino Mega 2560
  • 9 - +5 V - к +5 V Arduino Mega 2560
  • 10 - LED 4 - к 25 дискретному выводу Arduino Mega 2560
  • 11 - BTN 2 - к 29 дискретному выводу Arduino Mega 2560
  • 12
  • 13 - LED 5 - к 26 дискретному выводу Arduino Mega 2560
  • 14
  • 15
  • 16 - LED 6 - к 27 дискретному выводу Arduino Mega 2560
  • VCC на JY-MCU подключаем к +5В Arduino
  • GND на JY-MCU подключаем к GND Arduino
  • TXT на JY-MCU подключаем к дискретному PIN 50 на Arduino
  • RXD на JY-MCU подключаем к дискретному PIN 51 на Arduino

arduino робот

Подключение ультразвукового дальномера HC-SR04

Процесс подключения ультразвукового дальномера HC-SR04 к Arduino и работу с ним я описывал ранее. В тонкости в этот раз вдаваться не буду, а лучше подробно распишу как я его закрепил на сервоприводе.

Для создания крепления под ультразвуковой дальномер HC-SR04 я использовал кусок платы от Proto Shield и панельку контактов.

arduino робот

Откусил от панельки контактов две части по 4 контакта и запаял их на плату параллельно.

arduino робот

arduino робот

Перед подключением дальномера я сперва “раскорячил” его контакты, чтобы они плотно держались в разъеме.

arduino робот

Проковырял в плате дырку под болт.

arduino робот

Закрепил модуль на сервоприводе.

arduino робот

В результате у меня получился такой девайс.

arduino робот

Осталось только подключить провода к контактной панельке на плате дальномера и завести их на контакты Arduino Mega 2560. Этим и займемся.

  • VCC HC-SR04 подключим к +5V на Arduino Mega 2560
  • Trig HC-SR04 к цифровому пину 31 на Arduino Mega 2560
  • Echo HC-SR04 к цифровому пину 30 на Arduino Mega 2560
  • GND HC-SR04 к GND на Arduino Mega 2560

Алгоритм объезда препятствий

С алгоритмом я особо не заморачивался. Все достаточно просто и интуитивно понятно.

Из исходного положения проверяем расстояние впереди. Если оно больше 30 сантиметров, то продолжаем двигаться вперед, иначе:

  • останавливаем двигатели
  • поворачиваем сервопривод на углы от 0 до 180 градусов с шагом в 15 градусов и измеряем расстояния на этих углах
  • заносим полученные значения в массив
  • поворачиваем сервопривод на угол 90 градусов (прямо)
  • ищем в массиве позицию с максимальным значением данных
  • если это значение меньше 30 сантиметров, то едем назад
  • если это значение больше 30 сантиметров, то проверяем какому углу поворота сервопривода оно соответствует и в зависимости от этого поворачиваем влево или вправо

Можно еще сделать проверку на большее расстояние впереди. Тогда можно будет не останавливать двигатели, а использовать плавный поворот.

Скетч реализации алгоритма объезда препятствий

В строках, на которые будет ругаться компилятор, поменяйте тире на минусы.

Демонстрация робота на Arduino

В следующий раз я попробую реализовать алгоритм прохождения лабиринта по правилу правой руки или движение по белой линии.

Похожие записи

Комментариев: 83

Блин, у меня машина живёт своей жизнью, я правда переделал код под РУ машину.

может серву запитай отдельно, а то у меня тоже была проблема с нехваткой тока от встроенного в Arduino стабилизатора

Не, у меня преобразователь из 7.4 в 6. Всё нормально работало.

Хотя да! Наверно дело в питании, потому что у тебя на видео серва быстро крутиться, а у меня slow.

Полезная статья, спасибо. Разбирался тут в вашем коде. Особенно мне полезно было унать про программную часть использования этого дальнометра (у меня такой же). Всё, что хотел узнать, понял. А конструкцию
int vHC_SR04() const int vTrig = 31;
const int vEcho = 30;
unsigned int vdistance_sm=0;
unsigned int vtime_us=0;
digitalWrite(vTrig, HIGH);
delayMicroseconds(10);
digitalWrite(vTrig, LOW);
vtime_us=pulseIn(vEcho, HIGH);
vdistance_sm=vtime_us/58;
return vdistance_sm;
>
нужно писать каждый раз, когда требуется узнать показания? Понятно, циклы никто не отменял, но это - единственный способ замерить показания?

это функция определения расстояния - написать ее надо только 1 раз
чтобы ее использовать просто пишите vHC_SR04()
это ее вызовет в нужном месте и вернет вам результаты измерений

Мне очень нравиться! Но можно переделать на ардуино уно, на етой порти то не все задействованы, а на уно портов должно хватить.

Поменяйте в скетче номера портов на свои.
У меня просто нет UNO - сам не могу проверить.

Окей попробую но токо прийтется шилд купить а то старый згорел почемуто

Полезная статья.Спасибо Вам.
Попробовал Ваш скетч откомпелировать но он выдал вот такие ошибки:
In file included from sketch_nov28b.ino:3:
C:\arduino-1.0.2\libraries\SoftwareSerial/SoftwareSerial.h:52: error: conflicting return type specified for 'virtual void SoftwareSerial::write(uint8_t)'
C:\arduino-1.0.2\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'
Ни как не могу побороть. Не подскажете причину ?
Использую Arduino IDE 1.0.2.

у меня версия 1.0.5
перепроверил скетч - в строках кода, на которые ругается компилятор замените тире на минусы.

Все проверил ошибка осталась, но добавилась еще одна sketch_nov28a.cpp: In function 'void vbluetoothmode()':
sketch_nov28a:193: error: 'class SoftwareSerial' has no member named 'available'

Было бы интересно реализовать конструкцию с 2 дальномерами, где первый сканирует сектор спереди, а другой постоянно отмеряет расстояние до препятствия по линии движения.

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

Хорошая идея. Благодарю за подсказку.

А можешь пожалуйста скинуть код с режимом объезжать все препятствия только без bluetooth, сервопривода, светодиодов.

К сожалению нет. Без сервопривода никак. У меня поиск проезда завязан на измерении расстояний по сторонам.

Было бы прикольно, если бы игрушка составляла что-то на подобии карты, где можно передвигаться (примерно как у роботов-пылесосов).

Здравствуйте! Подскажите будете реализовывать следующие функции
Возможность движения по загруженному GPS треку
Запись маршрута движения в файл

Пока не готов вам ответить. Думал об этом, но пока отвлекся на другой проект.

//Создаем объекты для двигателей
AF_DCMotor motor1(1); //канал М1 на Motor Shield — задний левый
AF_DCMotor motor2(2); //канал М2 на Motor Shield — задний правый
AF_DCMotor motor3(3); //канал М3 на Motor Shield — передний левый
AF_DCMotor motor4(4); //канал М4 на Motor Shield — передний правый
// Создаем объект для сервопривода
Servo vservo;
// Создаем переменные для запоминания скорости левых и правых двигателей
int vspdL, vspdR;
/* Создаем переменную, на значение которой будет уменьшаться скорость при плавных поворотах.
Текущая скорость должна быть больше этого значения. В противном случае двигатели со стороны направления поворота просто не будут вращаться */
const int vspd = 200;
// Массив для хранения углов поворота сервопривода (шаг 15 градусов)
const int vservo_array[13]= 0,15,30,45,60,75,90,105,120,135,150,165,180>;
// Массив для хранения данных о расстоянии под различными углами поворота сервопривода
int vHC_SR04_array[13];
// Пины, используемые ультразвуковым дальномером
const int vTrig = 31;
const int vEcho = 30;
// Переменные, для хранения данных с дальномера
unsigned int vtime_us=0;
unsigned int vdistance_sm=0;
// Минимальное расстояние в сантиметрах, при котором нужно искать новый маршрут движения
const int vmindistance = 30;
// Переменная для циклов перебора значения массивов vservo_array и vHC_SR04_array
int vservo_int;
// Переменные для цикла поиска максимального значения в массивах
int vmaxarrayindex_int;
int vmaxarrayvalue_int;

void setup() // Устанавливаем скорость передачи данных по кабелю
Serial.begin(9600);
// Выбираем пин к которому подключен сервопривод
vservo.attach(9); // или 10, если воткнули в крайний разъём
// Поворачиваем сервопривод в положение 90 градусов при каждом включении
vservo.write(90);
// Устанавливаем максимальную скорость вращения двигателей
vspeed(255,255);
// Устанавливаем значение для пинов, к которым подключен ультразвуковой дальномер
pinMode(vTrig, OUTPUT);
pinMode(vEcho, INPUT);
>
void loop() <>
/* Режим работы с использованием ультразвукового дальномера */
void vultrasoundmode() vservo.write(90);
delay(200);
Serial.print("Now ");
Serial.println(vHC_SR04());
// Если расстояние меньше наименьшего, то
if (vHC_SR04() vspd) vspeed(vspdL,vspdR-vspd);
>
else
vspeed(vspdL,0);
>
vforwardRL();
>

// Изменение скорости
void vspeed(int spdL,int spdR) if (spdL == spdR) vspdL=spdL;
vspdR=spdR;
>
motor1.setSpeed(spdL);
motor2.setSpeed(spdR);
motor3.setSpeed(spdL);
motor4.setSpeed(spdR);
>

Читайте также: