Raspberry Pi Jam у КАІ Мейкерспейс. Вчимося керувати світлофором Pi-Stop із Python на Raspberry Pi 3, 4 або 5. Відкрий цю сторінку на самій Raspberry Pi — код звідси копіюється просто в термінал.
gpiozero). «Zero» тут — це назва бібліотеки, а не плата Raspberry Pi Zero. Вона однаково працює на Pi 3, Pi 4 і Pi 5, і саме на цих платах ми й працюємо.Що потрібно
- Raspberry Pi 3, 4 або 5 — усі три мають однаковий 40-піновий гребінець GPIO, тож код нижче для них ідентичний;
- Raspberry Pi OS з робочим столом (Bookworm або новіша — та, що ставиться з Raspberry Pi Imager за замовчуванням);
- плата-світлофор Pi-Stop;
- ця сторінка, відкрита в браузері на Raspberry Pi (Chromium);
- відкритий Термінал (чорна іконка з
>_у верхній панелі).
Яка в тебе плата і яка система
cat /proc/device-tree/model; echo; lsb_release -dМає надрукувати щось на кшталт Raspberry Pi 4 Model B Rev 1.5 і назву системи. Якщо там Pi 5 — усе працює так само, але глянь окремий пункт про Pi 5 у розділі «Якщо щось не працює».
1. Підключення Pi-Stop
Вимкни Raspberry Pi, надінь Pi-Stop прямо на контакти GPIO і ввімкни живлення. Плата сідає на чотири контакти непарного ряду — того, що ближче до краю плати:
| Pi-Stop | GPIO-пін | Фізичний пін |
|---|---|---|
| Червоний (R) | 22 | 15 |
| Жовтий (A) | 27 | 13 |
| Зелений (G) | 17 | 11 |
| Земля (GND) | GND | 9 |
Ліва колонка — номери GPIO, саме їх ми пишемо в коді. Права — порядковий номер контакту на гребінці; він потрібен, якщо збираєш світлофор не платою Pi-Stop, а окремими світлодіодами на дротах. На Pi 3, 4 і 5 ця розкладка однакова.
Побачити всю гребінку саме своєї плати можна командою:
pinoutПеревірка, що бібліотека на місці
python3 -c "import gpiozero; print('gpiozero OK')"Має надрукувати gpiozero OK. Якщо ні — дивись розділ «Якщо щось не працює» внизу.
Створюємо теку для програм
mkdir -p ~/svitlofor && cd ~/svitloforУсі наступні програми зберігатимуться сюди. Цю команду досить виконати один раз.
2. Перше блимання
Наступна команда створює файл 01-blink.py з програмою всередині. Копіюй її цілком — разом із рядками << 'EOF' та EOF.
cat > ~/svitlofor/01-blink.py << 'EOF'
from gpiozero import LED
from signal import pause
red = LED(22)
red.blink()
pause()
EOFЗапускаємо:
python3 ~/svitlofor/01-blink.pyЧервоний має блимати без упину. Щоб зупинити програму — натисни Ctrl+C у терміналі.
pause()? blink() блимає у фоні й не затримує програму. У терміналі програма без pause() закінчилась би миттєво — ти б навіть не побачив спалаху. pause() каже: «стій і чекай, поки мене не зупинять».3. Три світла з різною швидкістю
cat > ~/svitlofor/02-blink3.py << 'EOF'
from gpiozero import LED
from signal import pause
red = LED(22)
amber = LED(27)
green = LED(17)
red.blink(1, 1)
amber.blink(2, 2)
green.blink(3, 3)
pause()
EOFpython3 ~/svitlofor/02-blink3.pyЧисла в дужках — це секунди: перше — скільки світло горить, друге — скільки не горить. Тобто blink(3, 3) — найповільніше.
blink(0.2, 0.2) — і зупини Ctrl+C.4. Вмикаємо світла по черзі
Основні команди для світлодіода: on() — увімкнути, off() — вимкнути, toggle() — перемкнути, blink() — блимати. А sleep() робить паузу між командами.
cat > ~/svitlofor/03-sequence.py << 'EOF'
from gpiozero import LED
from time import sleep
red = LED(22)
amber = LED(27)
green = LED(17)
red.on()
sleep(1)
amber.on()
sleep(1)
green.on()
sleep(1)
red.off()
sleep(1)
amber.off()
sleep(1)
green.off()
EOFpython3 ~/svitlofor/03-sequence.pyСвітла загоряються одне за одним, потім так само гаснуть — і програма завершується сама.
5. Робимо це нескінченним — цикл while
cat > ~/svitlofor/04-loop.py << 'EOF'
from gpiozero import LED
from time import sleep
red = LED(22)
amber = LED(27)
green = LED(17)
while True:
red.on()
sleep(1)
amber.on()
sleep(1)
green.on()
sleep(1)
red.off()
sleep(1)
amber.off()
sleep(1)
green.off()
sleep(1)
EOFpython3 ~/svitlofor/04-loop.pywhile True: означає «повторюй вічно». Усе, що всередині циклу, зсунуте вправо на чотири пробіли — саме цей відступ і каже Python, що рядок належить циклу. Зупинка — Ctrl+C.
6. Завдання: справжній світлофор
Тепер ти вмієш вмикати світла окремо й керувати паузами. Збери справжню послідовність українського світлофора:
- Зелений — їдь
- Жовтий — готуйся спинятись
- Червоний — стій
- Червоний і жовтий разом — приготуйся їхати
- Зелений — і все спочатку
Подумай про час: скільки має горіти кожен стан? Зелений і червоний — довго, жовтий — коротко. Спробуй написати сам, і лише потім відкривай підказку.
Показати готовий розв’язок
cat > ~/svitlofor/05-svitlofor.py << 'EOF'
from gpiozero import LED
from time import sleep
red = LED(22)
amber = LED(27)
green = LED(17)
def all_off():
red.off()
amber.off()
green.off()
try:
all_off()
while True:
green.on() # їдь
sleep(5)
green.off()
amber.on() # готуйся спинятись
sleep(2)
amber.off()
red.on() # стій
sleep(5)
amber.on() # червоний + жовтий: приготуйся
sleep(2)
all_off()
except KeyboardInterrupt:
all_off()
print()
print('Світлофор зупинено')
EOFpython3 ~/svitlofor/05-svitlofor.pyБлок try ... except KeyboardInterrupt потрібен, щоб після Ctrl+C світла гасли, а не лишались горіти.
7. Бонус: те саме одним рядком
У gpiozero вже є готовий клас саме для світлофора:
cat > ~/svitlofor/06-bonus.py << 'EOF'
from gpiozero import TrafficLights
from signal import pause
lights = TrafficLights(red=22, amber=27, green=17)
lights.blink()
pause()
EOFpython3 ~/svitlofor/06-bonus.pyСпробуй також lights.on(), lights.off(), lights.green.on() — і подивись документацію: gpiozero.readthedocs.io.
Куди далі
- додати кнопку (
Button) — щоб пішохід перемикав світло; - додати зумер (
Buzzer) — щоб пищав на зелений; - зробити двосторонній перехрестя з двох Pi-Stop.
Якщо щось не працює
ModuleNotFoundError: No module named 'gpiozero'
sudo apt update && sudo apt install -y python3-gpiozero python3-lgpioСтав саме через apt. pip install gpiozero у свіжій Raspberry Pi OS впаде з помилкою externally-managed-environment — це нормально, так і задумано.
У мене Raspberry Pi 5, і щось поводиться інакше
Увесь код на цій сторінці на Pi 5 працює без змін — gpiozero сам звертається до нового контролера через lgpio. Але стара бібліотека RPi.GPIO на Pi 5 не працює взагалі: якщо знайдеш у мережі приклад із import RPi.GPIO, він упаде з помилкою про SOC peripheral base address. Це не поламана плата — просто той приклад старіший за Pi 5. Бери приклади на gpiozero.
Якщо gpiozero на Pi 5 скаржиться на pin factory:
sudo apt install -y python3-lgpioПрограма запустилась і одразу закінчилась, світло не блимає
У програмі з blink() забули pause() в кінці. Без нього програма завершується миттєво.
Помилка про «зайнятий» пін (GPIO busy / device or resource busy)
Десь ще працює попередня програма. Знайди її термінал і натисни Ctrl+C. Якщо не допомогло — перезавантаж Raspberry Pi.
Світла лишились горіти після зупинки
python3 -c "from gpiozero import LED
for p in (22, 27, 17):
LED(p).off()"IndentationError
З’їхали відступи всередині while. Створи файл ще раз кнопкою Копіювати — вона віддає код точно з відступами.
Хочу подивитись, що вийшло у файлі
cat ~/svitlofor/05-svitlofor.pyМатеріал побудовано на вільному ресурсі Raspberry Pi Foundation «Controlling a traffic lights sequence with GPIO Zero» (ліцензія CC BY-SA), адаптовано для роботи в терміналі Raspberry Pi. Питання й реєстрація на воркшопи — makerspace.kai.edu.ua/trainings.