Raspberry Pi GPIO MQTT kontrolü sayesinde bir röleyi, LED'i veya buzzer'ı her yerden anahtarlayabilir, butonların ve kontakların durumunu gerçek zamanlı görebilirsiniz; üstelik ağınızda tek bir port açmadan. Bu eğitimde gpiozero ve paho-mqtt kullanarak bir çıkışı MQTT komutlarıyla açıp kapatacak, giriş değişikliklerini gerçekleştikleri anda yayınlayacak ve her şeyi retained durum olarak raporlayacaksınız. Önce broker.connectmq.com ve bir komut satırı istemcisiyle test edecek, ardından özel kimlik bilgilerine geçeceksiniz.
Parçalar Nasıl Bir Araya Geliyor
Pi, bir MQTT broker'a dışarıya doğru bağlanır ve bir komut topic'ine abone olur. MQTT yayınlayabilen her şey (bir telefon uygulaması, Node-RED, bir web paneli, bir betik) bu topic'e ON veya OFF gönderir ve Pi pini anahtarlar. Pin değiştiğinde ya da bir butona basıldığında Pi yeni durumu ayrı bir durum topic'ine yayınlar.
Komut ve durum topic'leri arasındaki bu ayrım, bu eğitimdeki en önemli tasarım kararıdır:
| Topic | Yön | Retained | Örnek payload |
|---|---|---|---|
.../gpio/led/set |
Kontrolcüden Pi'ye | Hayır | ON |
.../gpio/led/state |
Pi'den herkese | Evet | ON |
.../gpio/button/state |
Pi'den herkese | Evet | PRESSED |
.../status |
Pi'den herkese | Evet (Last Will) | online / offline |
Komutlar retained değildir; böylece Pi yeniden başladığında eskimiş bir "ON" tekrar tetiklenmez. Durumlar retained'dır; böylece sonradan bağlanan her panel güncel değerleri hemen görür. Bir panel, kendi gönderdiğini yansıtmak yerine durum topic'ini göstermelidir; çünkü durum topic'i donanımda gerçekte ne olduğunu yansıtır.
Kablolama
330 ohm dirençli bir LED'e (veya bir röle modülüne) ve bir butona ihtiyacınız var.
- LED anodunu (uzun bacak) direnç üzerinden GPIO 17'ye (fiziksel pin 11), katodu toprağa bağlayın.
- Butonu GPIO 27 (fiziksel pin 13) ile toprak arasına bağlayın. gpiozero dahili pull-up direncini etkinleştirir, bu yüzden ek direnç gerekmez.
GPIO pinleri 3,3 V'tur ve yalnızca birkaç miliamper akım verebilir. Röleleri, motorları ve şebeke gerilimindeki her şeyi asla doğrudan değil, uygun bir sürücü kartı veya röle modülü üzerinden sürün. MQTT üzerinden Raspberry Pi röle kontrolü eğitimi bunu güvenli şekilde ele alır.
Kütüphaneleri Kurun
gpiozero, Raspberry Pi OS'ta önceden yüklü gelir ve RP1 G/Ç yongasına sahip Raspberry Pi 5 dahil her modelde çalışan lgpio arka ucunu kullanır. Sistem paketlerini görebilen bir sanal ortam oluşturun, ardından paho-mqtt'yi ekleyin:
sudo apt install -y python3-gpiozero python3-lgpio
python3 -m venv --system-site-packages ~/gpio-mqtt/.venv
source ~/gpio-mqtt/.venv/bin/activate
pip install "paho-mqtt>=2.0"
python -c "import gpiozero, paho.mqtt; print('ok')"
--system-site-packages kullanmak, GPIO kütüphanelerini pip ile derlemekten kurtarır; bu, yeni Pi modellerinde kurulum hatalarının en yaygın kaynağıdır. Kullanıcınızın gpio grubunda olması gerekir; varsayılan kullanıcı zaten bu gruptadır.
Raspberry Pi GPIO MQTT Betiği
import os
import signal
import uuid
import paho.mqtt.client as mqtt
from gpiozero import LED, Button
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"pi-gpio-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("TOPIC_PREFIX", "connectmq/demo/g3p6v2/pi1")
led = LED(17)
button = Button(27, bounce_time=0.05)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(1, 30)
def publish_led_state():
client.publish(f"{PREFIX}/gpio/led/state", "ON" if led.is_lit else "OFF", qos=1, retain=True)
def publish_button_state():
state = "PRESSED" if button.is_pressed else "RELEASED"
client.publish(f"{PREFIX}/gpio/button/state", state, qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print("connect failed:", reason_code)
return
print("connected")
client.subscribe(f"{PREFIX}/gpio/+/set", qos=1)
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
publish_led_state()
publish_button_state()
def on_message(client, userdata, msg):
target = msg.topic.split("/")[-2]
command = msg.payload.decode(errors="ignore").strip().upper()
if target != "led":
return
if command == "ON":
led.on()
elif command == "OFF":
led.off()
elif command == "TOGGLE":
led.toggle()
else:
print("ignored command:", command)
return
publish_led_state()
button.when_pressed = publish_button_state
button.when_released = publish_button_state
client.on_connect = on_connect
client.on_message = on_message
client.connect_async(BROKER, PORT, keepalive=30)
client.loop_start()
try:
signal.pause()
except KeyboardInterrupt:
pass
finally:
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
client.loop_stop()
client.disconnect()
led.off()
Birkaç ayrıntıya dikkat çekmekte fayda var. gpiozero, when_pressed geri çağırmalarını kendi iş parçacığında çalıştırır ve paho'nun publish() fonksiyonu iş parçacığı güvenlidir; dolayısıyla onu geri çağırmanın içinden çağırmak sorun değildir. bounce_time, aksi halde art arda basma ve bırakma olayları üreten mekanik anahtar arkını (bounce) filtreler. on_connect, her yeniden bağlantıdan sonra yeniden abone olur ve durumları yeniden yayınlar; böylece broker her zaman güncel gerçeği tutar. Bilinmeyen komutlar tahmin edilmek yerine yok sayılır.
Başka Bir Makineden Test Edin
Betiği Pi üzerinde çalıştırın, ardından dizüstü bilgisayarınızda her şeyi izlemek için bir terminal, komut göndermek için de başka bir terminal açın:
# terminal 1: watch all topics for this Pi
mosquitto_sub -h broker.connectmq.com -p 1883 -i gpio-watch-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/#" -v
# terminal 2: send commands
mosquitto_pub -h broker.connectmq.com -p 1883 -i gpio-cmd-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/gpio/led/set" -m ON
mosquitto_pub -h broker.connectmq.com -p 1883 -i gpio-cmd-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/gpio/led/set" -m TOGGLE
LED anahtarlanır ve terminal 1 yeni led/state değerini gösterir. Butona basın; button/state değeri PRESSED ile RELEASED arasında değişir. Betiği Ctrl+C ile durdurduğunuzda durum offline olur; bunun yerine gücü keserseniz broker, keepalive süresi dolduktan sonra Last Will mesajını yayınlar.
Ücretsiz genel MQTT broker bu test için idealdir, ancak herkesin genel topic'lerinde okuma ve yayın yapabildiğini unutmayın. Gerçek bir röleyi orada kontrol edilebilir halde bırakmayın.
Daha Fazla Pine Genişletme
Birden fazla çıkışı kontrol etmek için adlandırılmış cihazlardan oluşan bir sözlük tutun ve bunları topic'ten bulun:
from gpiozero import OutputDevice
outputs = {"led": LED(17), "fan": OutputDevice(22), "pump": OutputDevice(23, active_high=False)}
on_message içinde tek LED'i outputs.get(target) ile değiştirin ve eşleşen ad için durumu yayınlayın. Topic'lerde pin numaraları yerine adlar kullanın: kartın kablolamasını değiştirdiğinizde panel bozulmamalıdır. Sıcaklık sensörleri gibi girişler için değişiklik anında değil, bir zamanlayıcıyla yayın yapın; DHT22 MQTT eğitimi bu deseni gösterir.
Çıkışlar İçin Arıza Emniyetli Davranış
İşler ters gittiğinde bir çıkışın ne yapması gerektiğine önceden karar verin, çünkü ağ er ya da geç kopacaktır. Bir lamba için son durumu korumak yeterlidir. Bir pompa, ısıtıcı veya vana içinse bir süre hiçbir komut ya da heartbeat gelmediğinde kapatmak genellikle daha güvenlidir. Basit bir desen: on_message içinde güncellenen bir zaman damgası ve ana döngüde, örneğin on dakikalık sessizlikten sonra çıkışı kapatan ve bağlantı geri geldiğinde yeni durumu yayınlayan bir kontrol.
Başlangıcı da düşünün. gpiozero, nesne oluşturulduğunda çıkışları kapalı konuma getirir; böylece yeniden başlatmanın ardından her çıkış, yeni bir komut gelene kadar bilinen güvenli bir durumda başlar. Süreç gerçekten gerektirmedikçe önceki durumu bir dosyadan geri yüklemek yerine bunu böyle bırakın. Gerektiriyorsa, kimse şaşırmasın diye bu davranışı cihazda ve panelde belgeleyin.
Sorun Giderme
GPIO busyveyalgpio.error: pini başka bir süreç tutuyor. Onu kullanan diğer betikleri veya servisleri durdurun ve iki kopya çalıştırmadığınızı kontrol edin.- No module named lgpio: sanal ortam
--system-site-packagesolmadan oluşturulmuş. Yeniden oluşturun veyapython3-lgpiopaketini kurun. - Komutlar hiçbir şey yapmıyor: topic'in tam olarak doğru olduğunu ve Pi'nin "connected" yazdırdığını kontrol edin. Gerçekte neyin yayınlandığını görmek için önekinizin altında
#'e abone olun. - LED her yeniden başlatmada yanıyor: biri
settopic'ine retained bir mesaj yayınlamış.mosquitto_pub -r -nile o topic'e boş bir retained mesaj yayınlayarak temizleyin. - Rastgele buton olayları:
bounce_timedeğerini artırın veya kabloları kısaltın; uzun, ekransız kablolar parazit toplar.
Üretim Kurulumu
Bir demonun ötesindeki her şey için ConnectMQ üzerinde özel bir broker oluşturun ve betiği portaldan aldığınız MQTT_PORT=8883, MQTT_USERNAME=YOUR_USERNAME, MQTT_PASSWORD=YOUR_PASSWORD ve MQTT_CLIENT_ID=YOUR_CLIENT_ID değerleriyle başlatın. TLS, komutların iletim sırasında okunmasını veya taklit edilmesini önler; cihaz başına kimlik bilgileri de topic'lerinize yalnızca kendi istemcilerinizin yayın yapabilmesini sağlar. Elektrik kesintisinden sonra çıkışların yeniden kontrol altına girmesi için betiği Python MQTT betiğini açılışta çalıştırma yazısındaki adımlarla bir servis olarak çalıştırın. Yönetilen bir MQTT broker sayesinde Pi üzerinde betiğiniz dışında kurulacak veya bakımı yapılacak hiçbir şey kalmaz.
Yeni başlıyorsanız, Raspberry Pi MQTT eğitimi kurulumu ve temelleri anlatır; gpiozero dokümantasyonu ise desteklenen tüm cihaz sınıflarını listeler.
Pi'nizi ConnectMQ ile Her Yerden Kontrol Edin
app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun. ConnectMQ'nun tarayıcı içi MQTT istemcisi, hiçbir şey kurmadan ON ve OFF komutları göndermenizi ve durum topic'lerini izlemenizi sağlar; böylece kaydolduktan birkaç dakika sonra Pi'nizi telefonunuzdan veya dizüstü bilgisayarınızdan kontrol edebilirsiniz.
Sık Sorulan Sorular
gpiozero yerine RPi.GPIO kullanabilir miyim?
RPi.GPIO, Raspberry Pi 5'i desteklemez. lgpio arka uçlu gpiozero tüm güncel modellerde çalışır ve buton arkı filtrelemesi ile iş parçacığı yönetimini sizin yerinize halleder.
Neden durum için retained mesaj kullanılıyor da komutlar için kullanılmıyor?
Retained durum, yeni abonelerin güncel değeri anında görmesini sağlar. Retained bir komut ise Pi her yeniden bağlandığında tekrar oynatılır ve çıkışları beklenmedik şekilde anahtarlar.
Şebeke gerilimli cihazları bu şekilde kontrol etmek güvenli mi?
Yalnızca yetkin biri tarafından kurulmuş, uygun değerlere sahip bir röle modülü veya kontaktör üzerinden ve broker'da TLS ile özel kimlik bilgileri kullanılarak. Şebeke gerilimini asla doğrudan GPIO pinlerinden anahtarlamayın.
Komutlar Pi'ye ne kadar hızlı ulaşır?
Sağlıklı bir bağlantıda MQTT komutları genellikle bir saniyenin çok altında ulaşır; bu da lambalar, röleler ve çoğu otomasyon görevi için fazlasıyla yeterlidir.



