EEM-241 İleri Düzey Programlama
2024-2025 Güz Dönemi
Ders 14 - Raspberry Pi GPIO Programlama
Raspberry Pi GPIO simülatörü: create.withcode.uk
1. Elektriksel güvenlik
Kod yazmadan önce şu kurallar açıklanmalıdır:
- GPIO pinleri 3.3 V mantık seviyesinde çalışır; pine doğrudan 5 V uygulanmamalıdır.
- LED, uygun bir seri direnç olmadan GPIO pinine bağlanmamalıdır.
- Bağlantılar değiştirilirken Raspberry Pi’nin enerjisi kesilmelidir.
- Bir pinin izin verilen akım sınırı aşılmamalıdır.
- GND bağlantısı ortak olmalıdır.
- Pin numarası ve devre bağlantısı çalıştırmadan önce iki kez kontrol edilmelidir.
Donanım sınırları kullanılan Raspberry Pi modelinin resmi belgelerinden doğrulanmalıdır.
2. Pin numaralandırma
RPi.GPIO iki numaralandırma biçimi sunar:
GPIO.BOARD: fiziksel başlık pinlerinin 1, 2, 3… numaralarıGPIO.BCM: işlemcinin GPIO numaraları
Bir programda yalnızca biri seçilmeli ve devre şemasıyla aynı sistem kullanılmalıdır. Bu dersteki örneklerde, mevcut simülatör/devrelerle uyum için BOARD kullanılacaktır.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
Pin eşlemesini görmek için:
print(GPIO.getmode())
3. Dijital çıkış: LED yakıp söndürme
Bu örnekte fiziksel pin 11 çıkış olarak kullanılmaktadır.
import RPi.GPIO as GPIO
import time
LED_PIN = 11
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT, initial=GPIO.LOW)
try:
while True:
GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(1)
GPIO.output(LED_PIN, GPIO.LOW)
time.sleep(1)
except KeyboardInterrupt:
print("Program kullanıcı tarafından durduruldu.")
finally:
GPIO.cleanup()
GPIO.cleanup() pinleri güvenli başlangıç durumuna döndürür. Sonsuz döngülü donanım programlarında finally içinde çağrılması özellikle önemlidir.
4. Tekrarı fonksiyonla azaltma
import RPi.GPIO as GPIO
import time
LED_PIN = 11
def led_yak_sondur(pin, bekleme):
GPIO.output(pin, GPIO.HIGH)
time.sleep(bekleme)
GPIO.output(pin, GPIO.LOW)
time.sleep(bekleme)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT, initial=GPIO.LOW)
try:
for _ in range(5):
led_yak_sondur(LED_PIN, 0.5)
finally:
GPIO.cleanup()
Önce sonlu döngüyle test yapmak, devre doğrulamasını kolaylaştırır.
5. Birden fazla LED: yürüyen ışık
import RPi.GPIO as GPIO
import time
LED_PINLERI = [11, 13, 15, 16, 18, 22]
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PINLERI, GPIO.OUT, initial=GPIO.LOW)
def tek_led_yak(pin, bekleme=0.2):
GPIO.output(pin, GPIO.HIGH)
time.sleep(bekleme)
GPIO.output(pin, GPIO.LOW)
try:
while True:
for pin in LED_PINLERI:
tek_led_yak(pin)
for pin in LED_PINLERI[-2:0:-1]:
tek_led_yak(pin)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
İkinci döngüde uç LED’lerin iki kez art arda yanmaması için [-2:0:-1] dilimi kullanılmıştır.
6. Dijital giriş: Buton okuma
Harici direnç yerine dahili pull-up direnci kullanılabilir. Bu bağlantıda butona basılmadığında giriş HIGH, basıldığında LOW okunur; buna active-low denir.
import RPi.GPIO as GPIO
import time
LED_PIN = 11
BUTON_PIN = 12
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(BUTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
while True:
butona_basildi = GPIO.input(BUTON_PIN) == GPIO.LOW
GPIO.output(LED_PIN, GPIO.HIGH if butona_basildi else GPIO.LOW)
time.sleep(0.02)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
7. Buton sıçraması (debounce)
Mekanik buton tek basışta kısa süreli çok sayıda geçiş üretebilir. Basit olay algılamada bouncetime kullanılabilir.
import RPi.GPIO as GPIO
import time
BUTON_PIN = 12
sayac = 0
def butona_basildi(kanal):
global sayac
sayac += 1
print("Basılma sayısı:", sayac)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(BUTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(
BUTON_PIN,
GPIO.FALLING,
callback=butona_basildi,
bouncetime=200
)
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Callback kısa tutulmalıdır; uzun süren işlem ana program akışında yapılmalıdır.
8. Butona göre yürüyen ışık yönü
import RPi.GPIO as GPIO
import time
LED_PINLERI = [11, 13, 15, 16, 18, 22]
BUTON_PIN = 12
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PINLERI, GPIO.OUT, initial=GPIO.LOW)
GPIO.setup(BUTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def sirayi_oynat(pinler, bekleme=0.15):
for pin in pinler:
GPIO.output(pin, GPIO.HIGH)
time.sleep(bekleme)
GPIO.output(pin, GPIO.LOW)
try:
while True:
if GPIO.input(BUTON_PIN) == GPIO.LOW:
sirayi_oynat(LED_PINLERI)
else:
sirayi_oynat(LED_PINLERI[::-1])
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
9. PWM ile LED parlaklığı
PWM, dijital çıkışı hızlı biçimde açıp kapatarak ortalama gücü değiştirir. Görev oranı (duty cycle) 0–100 arasındadır.
import RPi.GPIO as GPIO
import time
LED_PIN = 11
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LED_PIN, GPIO.OUT)
pwm = GPIO.PWM(LED_PIN, 1000)
pwm.start(0)
try:
for gorev_orani in range(0, 101, 5):
pwm.ChangeDutyCycle(gorev_orani)
time.sleep(0.1)
for gorev_orani in range(100, -1, -5):
pwm.ChangeDutyCycle(gorev_orani)
time.sleep(0.1)
finally:
pwm.stop()
GPIO.cleanup()
PWM her donanım yükünü doğrudan sürmek için uygun değildir. Motor gibi yüklerde uygun sürücü devresi ve geri EMK koruması gerekir.
10. Sınıfla donanım davranışını kapsülleme
import RPi.GPIO as GPIO
import time
class Led:
def __init__(self, pin):
self.pin = pin
GPIO.setup(self.pin, GPIO.OUT, initial=GPIO.LOW)
def yak(self):
GPIO.output(self.pin, GPIO.HIGH)
def sondur(self):
GPIO.output(self.pin, GPIO.LOW)
def yanip_son(self, sure=0.5):
self.yak()
time.sleep(sure)
self.sondur()
GPIO.setmode(GPIO.BOARD)
led = Led(11)
try:
for _ in range(5):
led.yanip_son(0.2)
finally:
GPIO.cleanup()
Bu örnek, 9. haftadaki sınıf bilgisini fiziksel bir bileşenle birleştirir.
11. Bütünleştirici uygulama: Trafik lambası
import RPi.GPIO as GPIO
import time
KIRMIZI = 11
SARI = 13
YESIL = 15
GPIO.setmode(GPIO.BOARD)
GPIO.setup([KIRMIZI, SARI, YESIL], GPIO.OUT, initial=GPIO.LOW)
def durum(kirmizi, sari, yesil, sure):
GPIO.output(KIRMIZI, kirmizi)
GPIO.output(SARI, sari)
GPIO.output(YESIL, yesil)
time.sleep(sure)
try:
while True:
durum(GPIO.HIGH, GPIO.LOW, GPIO.LOW, 3)
durum(GPIO.HIGH, GPIO.HIGH, GPIO.LOW, 1)
durum(GPIO.LOW, GPIO.LOW, GPIO.HIGH, 3)
durum(GPIO.LOW, GPIO.HIGH, GPIO.LOW, 1)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Derste uygulama sırası
- Devre enerjisizken bağlantıları kurun ve numaralandırmayı doğrulayın.
- Tek LED’i sonlu döngüyle sınayın.
try/finallyve kullanıcı kesmesini ekleyin.- LED listesini ve yürüyen ışığı oluşturun.
- Buton girişini önce okuyup yazdırarak sınayın.
- Butonla LED davranışını birleştirin.
- Zaman kalırsa olay algılama ve PWM uygulayın.
Ders sonu alıştırmaları
- Üç LED’i ikili sayaç olarak kullanarak
0–7sayılarını gösterin. - Butona her basıldığında yürüyen ışığın yönünü kalıcı olarak değiştirin.
- İki butonla PWM görev oranını artırıp azaltın.
- Trafik lambasına yaya butonu ve güvenli geçiş sırası ekleyin.
Ledsınıfını birden fazla LED’i yönetenLedGrubusınıfına genişletin.
Dönem sonu proje önerisi
Bir butonla çalışma modu değişen LED kontrol sistemi tasarlayın. Sistem;
- en az üç farklı animasyon içersin,
- geçersiz pin veya görev oranı değerlerini doğrulasın,
try/finallyile her durumda GPIO temizliği yapsın,- fonksiyon veya sınıflarla tekrar eden kodu azaltmalı,
- devre şeması ve kısa kullanım açıklamasıyla teslim edilmelidir.