Python скрипты для работы с GPIO Raspberry Pi. v1

В этом видео:
– пара слов о Python;
– разбор Python скрипта “Светофор”

Сегодня о тех скриптах которые использовались в прошлом видео с Raspberry Pi.
Написаны они на языке python.
Я не буду вдаваться в подробные рассказы о данном языке – скажу что это как и bash (о котом я рассказывал в своих видео) интерпретируемый язык, он легко читается, его легко осваивать, он хорошо подходит для обучения.
Это одна из причин почему он уже встроен в raspberry pi и вам ничего устанавливать не нужно.
Просто открываете текстовый редактор или запускаете IDLE. Пишите скрипт и тестируете полученный результат.
Бонусом является наличие предустановленных модулей для работы с интересующими нас GPIO пинам.
С помощью предустановленного модуля RPi.GPIO можно управлять GPIO пинами.
Модуль это по сути уже написанный скрипт который выполняет определенные действия. У данного модуля внутри может быть множество написанных функций – эти функции по сути части скрипта-модуля, их можно вызывать отдельно не запуская как бы весь модуль-скрипт, а только его нужную часть.
Например, в каком-нибудь математическом модуле может быть заложено множество формул, вам нужна только формула подсчёта площади круга. Вы пишите имя модуля, потом через точку имя нужно формулы, передаёте нужные данные (значение радиуса) и получаете результат – площадь круга.
В данном случае всё тоже самое вы импортируете модуль RPi.GPIO – далее можно работать с его частями, например, обратиться к какому-либо GPIO пину.

В первом скрипте помимо модуля RPi.GPIO, который для краткости можно переименовать просто в GPIO, я подгружаю модуль времени. Так как нужно зажигать светодиоды только на определённое время.
import RPi.GPIO as GPIO
Далее нужно определить как работать с пинами GPIO – так получилось что работать можно по нескольким схемам нумерации этих пинов, есть схема с нумерацией по порядку следования пинов на плате – GPIO.BOARD, есть схема с использованием “Broadcom SOC channel” GPIO.BCM. Подробнее можете почитать по ссылке. На мой взгляд лучше использовать схему GPIO.BOARD – в случае смены нумерации каналов у Broadcom, нумерация на плате не изменится.

Далее для простоты определяется массив light элементами которого являются номера пинов в GPIO, а элементы массива определяютяс значениями переменных – в данном случае цветами (red, green, yellow и blue). Это используется для упрощения написания и чтения скрипта, и служат для определения элемента массива.
Если я хочу указать скрипту использовать пин 12, вместо указания просто значения 12 (которое нужно запоминать при написании кода – для чего число 12, для чего 16 и тп. Проще запомнить сразу имя цвета или переменной – Потом значение переменной можно будет сменить один раз при смене пина, а не менять нумерацию пина во всём скрипте).
Я указываю имя массива и цвет. Например, light[yellow] – значение элемента будет равно 12 – переменная yellow равно 2 и указывает на второй элемент массива.
GPIO.setup(light[green], GPIO.OUT, initial=True)
Для того чтобы включить светодиод – подать сигнал на нужный мне пин я указываю модулю GPIO настроить setup, пин light[green] = 7, перейти в режим подачи сигнала GPIO.OUT и подать сигнал initial=True или можно указать 1.

Для того чтобы выключить светодиод делается всё тоже самое, но указывается статус False или можно указать 0:
GPIO.setup(light[green], GPIO.OUT, initial=False)
Далее наступает секция с конструкцией try except.
В блоке try мы выполняем инструкцию, которая может породить исключение, а в блоке except мы перехватываем их.

KeyboardInterrupt – порождается при прерывании программы пользователем (обычно сочетанием клавиш Ctrl+C).

Ссылка.

Это необходимо чтобы задействовать инструкцию
GPIO.cleanup()
и очистить пины – чтобы они могли быть использованы в других скриптах и тп. Иначе они сохранят своё состояние.

Внути блока try-except используются обычные конструкции с циклами while и for.
Цикл “while True” позволяет выполняться скрипту бесконечно, пока не будет произведено прерывание.

Сами скрипты:
pi@raspberrypi:~ $ cat traffic_lightl.py
import RPi.GPIO as GPIO
import time

#GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BOARD)
red = 1; yellow = 2; green = 3; blue = 0

#light=[4,18,23,24]
light=[7,12,16,18]

GPIO.setup(light[red], GPIO.OUT, initial=False)
GPIO.setup(light[yellow], GPIO.OUT, initial=False)
GPIO.setup(light[green], GPIO.OUT, initial=True)
GPIO.setup(light[blue], GPIO.OUT, initial=False)

print ("Ctrl+C exits the program")

try:
while True:
time.sleep(2)
GPIO.output(light[green],False)
GPIO.output(light[yellow],True)
time.sleep(0.6)

GPIO.output(light[yellow],False)
GPIO.output(light[red],True)
time.sleep(0.6)

for i in range(10):
GPIO.output(light[blue],True); time.sleep(0.05)
GPIO.output(light[blue],False); time.sleep(0.05)
time.sleep(0.6)

GPIO.output(light[yellow],True);time.sleep(0.6)
GPIO.output(light[red],False)
GPIO.output(light[yellow],False)
GPIO.output(light[green],True)

except KeyboardInterrupt:
GPIO.cleanup()

————————–
pi@raspberrypi:~ $ cat traffic_lightl-with-button.py

import RPi.GPIO as GPIO
import time

#GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BOARD)

red = 1; yellow = 2; green = 3; blue = 0; button = 4
#light=[4,18,23,24,25]
light=[7,12,16,18]

GPIO.setup(light[red], GPIO.OUT, initial=False)
GPIO.setup(light[yellow], GPIO.OUT, initial=False)
GPIO.setup(light[green], GPIO.OUT, initial=True)
GPIO.setup(light[blue], GPIO.OUT, initial=False)
GPIO.setup(light[button], GPIO.IN)

print ("Press button to turn on pedestrian light, Ctrl+C exits the program")

try:
while True:
if GPIO.input(light[button])==True:
GPIO.output(light[green],False)
GPIO.output(light[yellow],True)
time.sleep(0.6)

GPIO.output(light[yellow],False)
GPIO.output(light[red],True)
time.sleep(0.6)

for i in range(30):
GPIO.output(light[blue],True); time.sleep(0.05)
GPIO.output(light[blue],False); time.sleep(0.05)
time.sleep(0.6)

GPIO.output(light[yellow],True)
time.sleep(0.6)

GPIO.output(light[red],False)
GPIO.output(light[yellow],False)
GPIO.output(light[green],True)
time.sleep(2)

except KeyboardInterrupt:
GPIO.cleanup()

————————–
pi@raspberrypi:~ $ cat led-programms.py

import RPi.GPIO as GPIO
import time
import random

#GPIO.setmode(GPIO.BCM)
GPIO.setmode(GPIO.BOARD)

#LED=[4,18,23,24]
LED=[7,12,16,18]

for i in LED:
GPIO.setup(i, GPIO.OUT, initial=0)

z = len(LED); w = 5; t = 0.2

print ("Light effects selection")
print ("1 - cyclical chaser")
print ("2 - chase bidirectional")
print ("3 - ascending and descending")
print ("4 - all flashing simultaneously")
print ("5 - all flashing at random")
print ("Ctrl+C exits the program")

try:
while True:
e = raw_input ("Please, select a pattern: ")

if e == "1":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(t)
GPIO.output(LED[j], False)

elif e == "2":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(t)
GPIO.output(LED[j], False)
for j in range(z-1, -1, -1):
GPIO.output(LED[j], True)
time.sleep(t)
GPIO.output(LED[j], False)

elif e == "3":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(t)
time.sleep(2*t)
for j in range(z-1, -1, -1):
GPIO.output(LED[j], False)
time.sleep(t)
time.sleep(2*t)

elif e == "4":
for i in range(w):
for j in range(z):
GPIO.output(LED[j], True)
time.sleep(2*t)
for j in range(z):
GPIO.output(LED[j], False)
time.sleep(t)

elif e == "5":
for i in range(w*z):
j = random.randint(0,z-1)
GPIO.output(LED[j], True)
time.sleep(t)
GPIO.output(LED[j], False)
else:
print ("Invalid entry")

except KeyboardInterrupt:
GPIO.cleanup()

————————–

На этом всё.
Удачи!

Links:
Работа с модулями: создание, подключение инструкциями import и from
The Python Tutorial » 6. Modules
What is the difference between BOARD and BCM for GPIO pin numbering?
Исключения в python. Конструкция try – except для обработки исключений
Print a list in reverse order with range() in python