Делаем своего первого робота на 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В) сигнал.
Каков же принцип действия этих ИК-сенсоров? ИК расшифровывается как «инфракрасный» — это длина волны света, которую человеческий глаз не воспринимает. Подобные модули содержат пару ИК-светодиодов — приёмник и передатчик. Когда перед ИК-сенсором оказывается объект, его поверхность отражает часть инфракрасного излучения назад к приёмнику. В результате приёмник формирует НИЗКИЙ сигнал, сообщая о наличии объекта перед датчиком.
Данные сенсоры соединены с входными контактами GPIO на Raspberry Pi. Далее «малина» при помощи python-скрипта опрашивает выходные значения контактов GPIO, к которым подключены ИК-датчики. Если на выходе фиксируется низкий уровень, скрипт отправляет двигателям постоянного тока команду сначала двигаться назад, а затем совершать поворот. Кроме того, робот изначально запускается нажатием кнопки, после чего Raspberry Pi через драйвер L293D даёт двигателям команду двигаться вперёд.
Подключение ИК-датчиков
Распиновка Raspberry Pi GPIO
Первым делом необходимо включить 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. Схема подключения приведена ниже:
Затем необходимо подать входные сигналы на плату. Четыре GPIO-вывода Raspberry Pi управляют направлением вращения двух моторов. Клеммы двигателей подсоединяются к четырём выходным клеммам платы. Питание двигателей осуществляется от 9В батареи. Логика управления моторами через 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 согласно приведённой выше схеме. Кнопка служит для включения и выключения робота. Завершив все подключения, закрепите колёса. С помощью двусторонней клейкой ленты соберите компоненты на корпусе робота. Результат должен выглядеть приблизительно так:
Проверка двигателей
Подключив двигатели, следует их протестировать. Воспользуйтесь приведённым ниже кодом для проверки работы моторов и 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
Вы можете загрузить или скопировать приведённый ниже код:
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
Эта команда запустит вашего робота. После нажатия кнопки робот начнёт движение. Вы увидите, как он уклоняется от объектов, находящихся перед его датчиками, и перемещается в свободном пространстве.
Данная программа довольно проста по логике. Робот активируется при нажатии пользователем кнопки. После этого он движется вперёд и контролирует, нет ли перед ним каких-либо препятствий. Каждый раз, когда ИК-модули фиксируют объект на расстоянии менее 5 см, они информируют Raspberry Pi о его присутствии (отправляя цифровые НИЗКИЕ сигналы). После этого Pi передаёт двигателю команды, заставляя его откатываться назад и поворачивать вправо или влево. Затем робот вновь продолжает движение вперёд, обходя различные препятствия. Повторное нажатие кнопки деактивирует робота.
Что можно сделать далее? Загрузив код на Raspberry Pi, вы сможете сделать робота полностью беспроводным и автономным, применив аккумулятор от смартфона для питания и USB-адаптер Wi-Fi для связи с ним. Экран ноутбука можно расширить через VNC-сервер и кабель локальной сети. Либо воспользуйтесь SSH для удалённого подключения к Pi через терминал без проводов.