Для урока вам понадобится:
- плата Raspberry Pi c SD-картой с уже установленной ОС Raspbian (как ее установить); ;
- кабель питания;
- светодиод;
- резистор на 220 Ом
- соединительные провода «мама-папа» и «папа-папа».
Что такое GPIO
В отличии от обычного компьютера Raspberry Pi может управлять внешними устройствами. Устройства могут быть абсолютно любыми, от обычной лампочки, до беспилотного летательного аппарата. На уроках робототехники можно собрать робота на базе «малинки» или реализовать систему умного дома.
Чтобы общаться с любыми внешними устройствами и управлять ими, Raspberry Pi имеет на борту интерфейс, называемый GPIO. Это аббревиатура от General Purpose Input Output. Это низкоуровневый интерфейс ввода-вывода прямого управления. На плате Raspberry он находится в углу, в виде гребёнки из 26 контактов, рядом с видеовыходом. Т.е. через этот интерфейс Raspberry может отдавать команды любому внешнему устройству, например мобильному роботу. А также может принимать данные с датчиков мобильного робота.
В этом уроке вы научитесь управлять светодиодом: включать и выключать его по команде.
Как работают GPIO контакты
На следующем рисунке изображено расположение пинов на «малинке». Из рисунка видно, что контакты имеют двойную номерацию: GPIO — нумерация и физическая нумерация.
- GPIO-нумерация. Это GPIO-контакты, каким их видит компьютер. Обычному человеку в этой нумерации логику увидеть сложно — цифры прыгают с места на место, из-за чего запомнить их довольно непросто.
- Физическая нумерация. Самый простой способ — это просто считать контакты один за другим начиная с самого первого (который ближе всего к SD-карте).
Детям и начинающим лучше использовать физическую нумерацию — она проще. По сути, нужно просто считать контакты один за другим. Но потребность в картинке-подсказке все равно не отпадает, потому что вам по-прежнему нужно знать, какие контакты являются GPIO-контактами, а какие отведены для питания и заземления.
Если внутри программы не перескакивать с одной нумерации на другую, а постоянно придерживаться лишь какой-то одной, все должно быть нормально. Но учтите также, что нумерация может зависеть от того, на каком языке вы программируете — к примеру, в Scratch используется физическая нумерация, а в Python вы можете выбрать между той и другой.
Вывод (OUTPUT)
Предупреждение! Внимательно следуете инструкциям!!! Если безо всякого разбора подключать к GPIO контактам провода и источники питания, то можно повредить Raspberry Pi. Кроме того, неприятности могут возникнуть, если подключать к Pi устройства, требующие слишком много энергии.
Если абстрагироваться от Pi, то одной из самых простейших цепей, которую вы можете собрать — это батарея, подключенная к источнику света и переключателю (резистор нужен здесь для защиты светодиода):
То есть, когда вы используете GPIO-контакт в качестве выходного (OUTPUT), то Pi на картинке выше заменяет собой и переключатель, и батарею. Любой контакт можно либо включить, либо выключить, то есть, если говорить компьютерными терминами — задать ему либо состояние HIGH, либо состояние LOW. Если контакт находится в состоянии HIGH, то будет выдавать 3,3 вольта (3v3), если LOW – 0 вольт.
А теперь та же самая цепь, только с использованием Raspberry Pi. Светодиод подключен к GPIO-контакту (который может выдавать 3,3 вольт) и заземляющему контакту (который выдает 0 вольт и выступает для батареи в качестве отрицательного полюса)
Управление светодиодом
Соберите схему и покажите ее преподавателю.
Зайдите в LXTerminal и наберите команду:
sudo python
введите следующие строки:
import RPi.GPIO as GPIO #импорт библиотеки
GPIO.setmode(GPIO.BOARD) #"включение" GPIO или GPIO.BCM
GPIO.setup(35, GPIO.OUT) #объявление 35-го пина как выход
Различие между GPIO.setmode(GPIO.BOARD) и GPIO.setmode(GPIO.BCM) заключается в системе нумерации выводов. В первом случае используется нумерация разъема P1 на борту Raspberry Pi, а во втором случае нумерация выводов системы-на-кристалле Broadcom, являющейся ядром Raspberry Pi. Следует знать, что в случае с BCM нумерация выводов между первой и второй ревизиями немного отличается, а при использовании BOARD ревизия не имеет никакого значения, все остается тем же самым.
Затем для включения светодиода введите команду:
GPIO.output(35, 1)
А для выключения:
GPIO.output(35, 0)
Если вы все сделали правильно, то светодиод должен включаться и выключаться.
Мигание светодиодом:
Для автономной работы светодиода напишите и запустите программу. Для этого откройте предустановленную программу IDLE 3.
import RPi.GPIO as GPIO #импорт библиотеки для работы с GPIO
import time #импорт библиотеки для ожидания
GPIO.setmode(GPIO.BOARD) #"запуск" GPIO
GPIO.setup(35, GPIO.OUT) #объявление порта 35 как выход
while True: #бесконечный цикл
____GPIO.output(35, 1) #включение светодиода
____time.sleep(1) #ожидание 1 секунды
____GPIO.output(35, 0) #выключение светодиода
____time.sleep(1) #ожидание 1 секунд
GPIO.cleanup()
Запустите программу на исполнение. Если вы все сделали правильно, то светодиод будет мигать с интервалом 1 секунда.
Ввод (INPUT) — управление светодиодом с кнопки
К GPIO контактам можно подключать различные сенсоры, девайсы, кнопки и считывать с них показания. В этом случае контакты надо описать на прием данных (вход) такой командой:
GPIO.setup(37, GPIO.IN)
Соберите следующую схему:
Составьте программу:
import RPi.GPIO as GPIO #импорт библиотеки GPIO
GPIO.setmode(GPIO.BOARD) #"включение GPIO"
GPIO.setup(37, GPIO.OUT) #объявление порта 37 как выход
GPIO.setup(35, GPIO.IN) #объявление порта 35 как вход
while True: #бесконечный цикл
____if GPIO.input(3) == False: #если кнопка зажата
________GPIO.output(37, 1) #включаем светодиод
____else: #иначе
________GPIO.output(37, 0) #выключаем
GPIO.cleanup()
Если вы все сделали верно, то при нажатии кнопки светодиод должен включаться, иначе выключаться.
Дополнительное задание
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(16, GPIO.IN)
GPIO.setup(18, GPIO.IN)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
# state - определяет должен ли светодиод быть включенным или выключенным
state = 0
# increment - направление изменения состояний
inc = 1
while True:
# кнопка нажата
if ( GPIO.input(16) == True ):
if (inc == 1):
state = state + 1;
else:
state = state - 1;
# достигнуто максимальное состояние state, возвращаемся назад (декремент)
if (state == 3):
inc = 0
#достигнуто минимальное состояние state, возвращаемся назад (инкремент)
elif (state == 0):
inc = 1
if (state == 1):
GPIO.output(11, GPIO.HIGH)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
elif (state == 2):
GPIO.output(11, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(15, GPIO.LOW)
elif (state == 3):
GPIO.output(11, GPIO.HIGH)
GPIO.output(13, GPIO.HIGH)
GPIO.output(15, GPIO.HIGH)
else:
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
print("pressed B1 ", state)
# нажата кнопка сброса
if ( GPIO.input(18) == True ):
state = 0
inc = 1
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
print("pressed B2 ", state)
sleep(0.2);
Задания для самостоятельной работы:
Задание 1. Подключите к «малинке» два светодиода и одну кнопку. Напишите программу, чтобы при первом нажатии включался красный светодиод, при втором — включался зеленый светодиод, в при третьем нажатии — они оба гасли.
Задание 2. Подключите к «малинке» светодиод и одну кнопку. Напишите программу, чтобы при первом нажатии на кнопку светодиод включался, а при следующем нажатии — выключался.