Делаем своего первого робота на Raspberry Pi

Комплектующие для робота на Raspberry Pi

С помощью Raspberry Pi и языка Python мы соберём робота, способного обходить препятствия, применяя ИК-модули для распознавания объектов.

Если вы начинающий и пока слабо знакомы с Raspberry Pi, однако хотите найти несложный проект для начала работы, то это именно то, что вам нужно. Мы разберёмся, каким образом сконструировать робота на базе Raspberry Pi и Python, умеющего объезжать препятствия и свободно передвигаться.

Сборка роботов с функцией обхода препятствий — весьма популярное занятие, и реализовать подобный проект не так уж сложно. Завершив данный урок, вы научитесь добавлять своему роботу возможность уклоняться от объектов, а заодно попрактикуетесь в написании кода на Python и работе с периферией Raspberry Pi.

Комплектующие

Чтобы собрать нашего робота на базе Raspberry, потребуется достаточно большой набор деталей:

  • Raspberry Pi B/B+ и основная периферия: S-карта, клавиатура, мышь, и т.д.

  • IR (ИК) модуль

  • Мотор-редуктор постоянного тока

  • L293D плата расширения

  • Шасси и колеса робота

  • Шасси

  • Макет

  • Двусторонний скотч

  • Перемычки

  • Батарея 9В и коннекторы

  • Кнопка

  • Резистор 220 Ом

Как работает робот?

Принцип работы этого робота достаточно прост. Вся система позволяет избегать столкновений с препятствиями за счёт встроенных сенсоров. В роботе применяются два ИК-датчика, способных определять объекты на расстоянии 5–6 см. Датчик выдаёт цифровой НИЗКИЙ (0В) сигнал при обнаружении объекта в указанном диапазоне, а в остальных случаях формирует цифровой ВЫСОКИЙ (5В) сигнал.

Робот на Raspberry Pi

Каков же принцип действия этих ИК-сенсоров? ИК расшифровывается как «инфракрасный» — это длина волны света, которую человеческий глаз не воспринимает. Подобные модули содержат пару ИК-светодиодов — приёмник и передатчик. Когда перед ИК-сенсором оказывается объект, его поверхность отражает часть инфракрасного излучения назад к приёмнику. В результате приёмник формирует НИЗКИЙ сигнал, сообщая о наличии объекта перед датчиком.

Принцип работы ИК-датчика

Данные сенсоры соединены с входными контактами GPIO на Raspberry Pi. Далее «малина» при помощи python-скрипта опрашивает выходные значения контактов GPIO, к которым подключены ИК-датчики. Если на выходе фиксируется низкий уровень, скрипт отправляет двигателям постоянного тока команду сначала двигаться назад, а затем совершать поворот. Кроме того, робот изначально запускается нажатием кнопки, после чего Raspberry Pi через драйвер L293D даёт двигателям команду двигаться вперёд.

Подключение ИК-датчиков

Распиновка Raspberry Pi GPIO

Распиновка Raspberry Pi GPIO

Первым делом необходимо включить Raspberry Pi, предварительно подсоединив к нему монитор, клавиатуру и прочую периферию. Затем следует протестировать модули ИК-датчиков. Для проверки подключите их к Raspberry Pi согласно приведённой ниже схеме.

Схема подключения ИК-датчиков к Raspberry Pi

Запитайте датчики, подав 5В (контакт +) и GND (земля, контакт -) от Raspberry Pi. Выходной контакт B на датчиках подключите к GPIO-выводам Raspberry Pi — 3 и 16. Расположение контактов GPIO можно проверить по распиновке, приведённой выше. Мы применяем конфигурацию GPIO.BOARD, при которой нумерация контактов соответствует их физическому расположению на плате (1,2,3, …). Изучите расположение выводов на датчиках и произведите все подключения в соответствии со схемой.

Далее скопируйте приведённый ниже код и сохраните его в Python-файл — irtest.py:

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.IN)                            #Right sensor connection
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Left sensor connection
while True:
i=GPIO.input(3)                         #Reading output of right IR sensor
j=GPIO.input(16)                        #Reading output of left IR sensor
if i==0:                                #Right IR sensor detects an object
print "Obstacle detected on Left",i
time.sleep(0.1)
elif j==0:                              #Left IR sensor detects an object
print "Obstacle detected on Right",j
time.sleep(0.1)

Сохранив файл, запускаем его:

sudo python irtest.py

При поднесении руки к датчику вы увидите, что на экране отображаются следующие данные:

Вывод данных ИК-датчиков

Соединение моторов с L293D

Протестировав ИК-датчики, нужно подключить и проверить модуль L293D вместе с двигателями. Чтобы запитать модуль L293D, соедините контакты + и - на плате с 9-вольтовой батареей. Помимо этого, подключите «-» платы к выводу GND на Raspberry Pi. Схема подключения приведена ниже:

Схема подключения моторов к L293D

Затем необходимо подать входные сигналы на плату. Четыре GPIO-вывода Raspberry Pi управляют направлением вращения двух моторов. Клеммы двигателей подсоединяются к четырём выходным клеммам платы. Питание двигателей осуществляется от 9В батареи. Логика управления моторами через Raspberry Pi представлена ниже:

L293D Raspberry Pi логика управления

Вход A

Вход B

Состояние мотора

High (высокий)

Low (низкий)

Поворачивается по часовой стрелке

Low

High

Поворачивается против часовой стрелки

High

High

Происходит торможение

Low

Low

Происходит торможение

В данном контексте HIGH означает сигнал 5 В или цифровую единицу, а LOW — сигнал 0 В или цифровой ноль. К примеру, GPIO.output (5,1) — данная команда посылает сигнал HIGH (цифровую 1) на вывод 5 Raspberry Pi. Таким образом, направлением каждого мотора можно управлять, записывая сигналы HIGH / LOW через два GPIO-контакта от Raspberry Pi.

Финальная сборка

Теперь необходимо подключить кнопку к Raspberry Pi согласно приведённой выше схеме. Кнопка служит для включения и выключения робота. Завершив все подключения, закрепите колёса. С помощью двусторонней клейкой ленты соберите компоненты на корпусе робота. Результат должен выглядеть приблизительно так:

Финальная сборка робота на Raspberry Pi

Проверка двигателей

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

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5,GPIO.OUT)   #Left motor input A
GPIO.setup(7,GPIO.OUT)   #Left motor input B
GPIO.setup(11,GPIO.OUT)  #Right motor input A
GPIO.setup(13,GPIO.OUT)  #Right motor input B
GPIO.setwarnings(False)

while True:
print "Rotating both motors in clockwise direction"
GPIO.output(5,1)
GPIO.output(7,0)
GPIO.output(11,1)
GPIO.output(13,0)
time.sleep(1)     #One second delay

print "Rotating both motors in anticlockwise direction"
GPIO.output(5,0)
GPIO.output(7,1)
GPIO.output(11,0)
GPIO.output(13,1)
time.sleep(1)     #One second delay

Проверьте, что на плату драйвера (L293D) подано питание и все соединения выполнены по схеме выше. Затем скопируйте приведённый код и сохраните его на Raspberry Pi в виде Python-файла — motor.py. Запустите его командой:

sudo python motor.py

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

Загрузка кода для робота Raspberry Pi

Вы можете загрузить или скопировать приведённый ниже код:

robot_py.zip

import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.IN) #Right IR sensor module
GPIO.setup(12, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) #Activation button
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Left IR sensor module
GPIO.setup(5,GPIO.OUT) #Left motor control
GPIO.setup(7,GPIO.OUT) #Left motor control
GPIO.setup(11,GPIO.OUT) #Right motor control
GPIO.setup(13,GPIO.OUT) #Right motor control

#Motor stop/brake
GPIO.output(5,0)
GPIO.output(7,0)
GPIO.output(11,0)
GPIO.output(13,0)

flag=0
while True:
     j=GPIO.input(12)
     if j==1: #Robot is activated when button is pressed
             flag=1
             print "Robot Activated",j

     while flag==1:
             i=GPIO.input(3) #Listening for output from right IR sensor
             k=GPIO.input(16) #Listening for output from left IR sensor
             if i==0: #Obstacle detected on right IR sensor
                     print "Obstacle detected on Right",i
                     #Move in reverse direction
                     GPIO.output(5,1) #Left motor turns anticlockwise
                     GPIO.output(7,0)
                     GPIO.output(11,1) #Right motor turns clockwise
                     GPIO.output(13,0)
                     time.sleep(1)

                     #Turn robot left
                     GPIO.output(5,0) #Left motor turns clockwise
                     GPIO.output(7,1)
                     GPIO.output(11,1) #Right motor turns clockwise
                     GPIO.output(13,0)
                     time.sleep(2)
             if k==0: #Obstacle detected on left IR sensor
                     print "Obstacle detected on Left",k
                     GPIO.output(5,1)
                     GPIO.output(7,0)
                     GPIO.output(11,1)
                     GPIO.output(13,0)
                     time.sleep(1)

                     GPIO.output(5,1)
                     GPIO.output(7,0)
                     GPIO.output(11,0)
                     GPIO.output(13,1)
                     time.sleep(2)

             elif i==0 and k==0:
                     print "Obstacles on both sides"
                     GPIO.output(5,1)
                     GPIO.output(7,0)
                     GPIO.output(11,1)
                     GPIO.output(13,0)
                     time.sleep(2)

                     GPIO.output(5,1)
                     GPIO.output(7,0)
                     GPIO.output(11,0)
                     GPIO.output(13,1)
                     time.sleep(4)

             elif i==1 and k==1:     #No obstacles, robot moves forward
                     print "No obstacles",i
                     #Robot moves forward
                     GPIO.output(5,0)
                     GPIO.output(7,1)
                     GPIO.output(11,0)
                     GPIO.output(13,1)
                     time.sleep(0.5)
             j=GPIO.input(12)
             if j==1: #De activate robot on pushin the button
                     flag=0
                     print "Robot De-Activated",j
                     GPIO.output(5,0)
                     GPIO.output(7,0)
                     GPIO.output(11,0)
                     GPIO.output(13,0)
                     time.sleep(1)

Завершив сборку всех компонентов, скачайте или скопируйте вышеприведённую Python-программу на Raspberry Pi. Файл программы называется robot.py. Запустите его командой:

sudo python robot.py

Эта команда запустит вашего робота. После нажатия кнопки робот начнёт движение. Вы увидите, как он уклоняется от объектов, находящихся перед его датчиками, и перемещается в свободном пространстве.

Готовый робот на Raspberry Pi

Данная программа довольно проста по логике. Робот активируется при нажатии пользователем кнопки. После этого он движется вперёд и контролирует, нет ли перед ним каких-либо препятствий. Каждый раз, когда ИК-модули фиксируют объект на расстоянии менее 5 см, они информируют Raspberry Pi о его присутствии (отправляя цифровые НИЗКИЕ сигналы). После этого Pi передаёт двигателю команды, заставляя его откатываться назад и поворачивать вправо или влево. Затем робот вновь продолжает движение вперёд, обходя различные препятствия. Повторное нажатие кнопки деактивирует робота.

Что можно сделать далее? Загрузив код на Raspberry Pi, вы сможете сделать робота полностью беспроводным и автономным, применив аккумулятор от смартфона для питания и USB-адаптер Wi-Fi для связи с ним. Экран ноутбука можно расширить через VNC-сервер и кабель локальной сети. Либо воспользуйтесь SSH для удалённого подключения к Pi через терминал без проводов.