Raspberry Pi

Raspberry Pi Röle MQTT Kontrolü: Çok Kanallı Röle Kartını Her Yerden Anahtarlayın

4 kanallı bir röle kartını Raspberry Pi'ye bağlayın, her kanalı Python ve gpiozero ile MQTT topic'lerinden kontrol edin ve retained mesajlar sayesinde her rölenin yeniden başlatma veya elektrik kesintisinden sonra doğru duruma dönmesini sağlayın.

Bir raspberry pi röle mqtt projesinde bulut MQTT mesajlarıyla kontrol edilen, gösterge LED'li dört kanallı röle kartına bağlı Raspberry Pi
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

Bir Raspberry Pi röle MQTT kontrolcüsü, modeminizde port açmadan lambaları, pompaları, fanları veya kontaktörleri bir telefondan, bir panelden ya da bir otomasyon betiğinden anahtarlamanızı sağlar. Bu eğitimde çok kanallı bir röle kartını bağlayacak, MQTT topic'lerini röle kanallarına eşleyen bir Python servisi yazacak ve retained mesajlar kullanarak her rölenin yeniden başlatmadan sonra doğru durumda geri gelmesini sağlayacaksınız.

Neye İhtiyacınız Var

Parça Notlar
Raspberry Pi (3B+, 4, 5 veya Zero 2 W) Raspberry Pi OS Bookworm, ağa bağlı
2, 4 veya 8 kanallı röle kartı Optokuplörlü 5 V bobin, 3,3 V uyumlu girişler
Dişi-dişi jumper kablolar Her kanal için bir tane, artı güç ve toprak
gpiozero ve paho-mqtt 2.x içeren Python 3 Bir sanal ortama kurulu
Bir MQTT broker Test için broker.connectmq.com, üretim için özel kimlik bilgileri

Her şeyden önce bir güvenlik notu: röle kartları onlara ne bağlarsanız onu anahtarlar. Şebeke gerilimini kontrol ediyorsanız, kablolama yetkin biri tarafından uygun bir muhafaza içinde ve yüke uygun değerde bir röleyle yapılmalıdır. Öğrenmek için bir 12 V LED şeridi veya küçük bir DC fanı anahtarlayın.

Röle Kartının Kablolanması

Çoğu hobi röle modülünde VCC, GND ve IN1 ile IN4 arası etiketli bir başlık bulunur. Bunları şöyle bağlayın:

Röle pini Raspberry Pi pini
VCC 5 V (fiziksel pin 2)
GND GND (fiziksel pin 6)
IN1 GPIO17 (fiziksel pin 11)
IN2 GPIO27 (fiziksel pin 13)
IN3 GPIO22 (fiziksel pin 15)
IN4 GPIO23 (fiziksel pin 16)

Bu kartların çoğu aktif-düşüktür (active-low): bir girişi toprağa çekmek bobini enerjilendirir. Aşağıdaki kodun active_high=False kullanmasının nedeni budur. Kartınız kapalı beklediğinizde açılıyorsa bu bayrağı tersine çevirin.

JD-VCC jumper'ı olan kartlar, tam yalıtım için bobinleri ayrı bir 5 V kaynaktan beslemenize olanak tanır. Jumper'ı çıkarın, JD-VCC'yi harici kaynaktan besleyin, VCC'yi kartın dokümantasyonunun söylediği gibi Pi'nin 3,3 V veya 5 V hattında tutun ve toprağı yalnızca kılavuz gerektiriyorsa ortak yapın.

Güvenilirlik açısından bir donanım ayrıntısı daha önemlidir. Betiğiniz başlamadan önce GPIO pinleri varsayılan pull dirençlerine sahip girişlerdir; bu yüzden aktif-düşük bir kart açılışta kısa bir süre anahtarlanabilir. Bir güç döngüsü sırasında rölelerinizin ne yaptığını test edin. Böyle bir aksaklık zararlı olacaksa, varsayılan pull değeri "kapalı" seviyesine uyan pinleri seçin veya harici pull dirençleri ekleyin.

Topic Sözleşmesini Tasarlamak

Temiz bir topic düzeni, röle kontrolcüsünü Node-RED, Home Assistant veya bir betik olsun, her istemciden kolayca kullanılabilir kılar:

Topic Yön Payload Retained
connectmq/demo/a91c4e/relays/<n>/set Kontrolcüden Pi'ye ON, OFF (veya retained olmayan TOGGLE) ON/OFF için evet
connectmq/demo/a91c4e/relays/<n>/state Pi'den herkese ON veya OFF Evet
connectmq/demo/a91c4e/relays/status Pi (ve last will) online veya offline Evet

a91c4e yerine kendi rastgele dizenizi yazın. Paylaşımlı bir genel broker'da her topic herkes tarafından okunabilir; bu yüzden benzersiz bir önek test trafiğinizi ayrı tutar. Ayrı set ve state topic'lerinin neden iyi bir uygulama olduğunu hatırlamak isterseniz, MQTT üzerinden Raspberry Pi GPIO rehberi komut ve durum desenini ayrıntılı olarak açıklar.

Retained Durumlar Yeniden Başlatmayı Nasıl Atlatır

Retained mesajlar, elektrik kesintisinden sonra düzgün davranan bir röle kontrolcüsünün anahtarıdır. Broker her topic'teki son retained mesajı saklar ve onu her yeni aboneye hemen teslim eder. Bu size iki faydalı davranış kazandırır:

  1. Paneliniz relays/1/set topic'ine retain bayrağıyla ON yayınladığında broker onu saklar. Pi yeniden başlayıp relays/+/set topic'ine abone olduğunda her kanal için istenen durumu alır ve geri yükler.
  2. Pi relays/1/state topic'ini retain ile yayınladığında, sonradan açılan her panel bir sonraki değişikliği beklemek yerine gerçek durumu hemen görür.

Bir tuzak var: TOGGLE komutunu asla retained yapmayın. Retained bir toggle her yeniden bağlantıda tekrar oynatılır ve röleyi her seferinde tersine çevirir. Aşağıdaki betik bu nedenle retained toggle'ları yok sayar. Mekanizmaya daha derinlemesine bakmak için MQTT retained mesajlar açıklamamızı okuyun.

Python ile Raspberry Pi Röle MQTT Betiği

Bir proje klasörü ve sanal ortam oluşturun:

sudo apt update
sudo apt install -y python3-venv python3-lgpio
mkdir -p ~/relay-mqtt && cd ~/relay-mqtt
python3 -m venv --system-site-packages .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" gpiozero

--system-site-packages bayrağı, sanal ortamın gpiozero'nun Raspberry Pi 5'te ihtiyaç duyduğu ve eski modellerde de çalışan lgpio arka ucunu kullanmasını sağlar. Aşağıdakini relay_mqtt.py olarak kaydedin:

#!/usr/bin/env python3
"""Control a multi-channel relay board from MQTT topics."""
import os
import signal
import sys
import uuid

import paho.mqtt.client as mqtt
from gpiozero import OutputDevice

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"rpi-relay-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/a91c4e/relays")

RELAY_PINS = {1: 17, 2: 27, 3: 22, 4: 23}
ACTIVE_HIGH = False  # most opto-isolated hobby boards are active-low

relays = {
    n: OutputDevice(pin, active_high=ACTIVE_HIGH, initial_value=False)
    for n, pin in RELAY_PINS.items()
}


def publish_state(client, n):
    state = "ON" if relays[n].value else "OFF"
    client.publish(f"{PREFIX}/{n}/state", state, qos=1, retain=True)


def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connection refused: {reason_code}")
        return
    print(f"Connected as {CLIENT_ID}")
    client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
    client.subscribe(f"{PREFIX}/+/set", qos=1)
    for n in relays:
        publish_state(client, n)


def on_message(client, userdata, msg):
    try:
        n = int(msg.topic.split("/")[-2])
    except ValueError:
        return
    if n not in relays:
        print(f"Ignoring unknown channel {n}")
        return

    command = msg.payload.decode(errors="ignore").strip().upper()
    if command in ("ON", "1", "TRUE"):
        relays[n].on()
    elif command in ("OFF", "0", "FALSE"):
        relays[n].off()
    elif command == "TOGGLE":
        if msg.retain:
            print(f"Ignoring retained TOGGLE on channel {n}")
            return
        relays[n].toggle()
    else:
        print(f"Unknown command {command!r} for channel {n}")
        return
    print(f"Relay {n} -> {'ON' if relays[n].value else 'OFF'}")
    publish_state(client, n)


def on_disconnect(client, userdata, flags, reason_code, properties):
    print(f"Disconnected: {reason_code}; paho will reconnect")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.on_message = on_message
client.on_disconnect = on_disconnect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)

if USERNAME:
    client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
    client.tls_set()


def shutdown(signum, frame):
    for relay in relays.values():
        relay.off()
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True)
    client.disconnect()
    sys.exit(0)


signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)

client.connect(BROKER, PORT, keepalive=30)
client.loop_forever(retry_first_connection=True)

python relay_mqtt.py ile çalıştırın. Betik temiz bir kapanışta her röleyi kapatır; servis durduğunda yüklerin çalışmaya devam etmesini tercih ederseniz shutdown içindeki döngüyü kaldırın.

Dizüstü Bilgisayarınızdan Test

Mosquitto istemcilerinin kurulu olduğu herhangi bir makinede ikinci bir terminal açın ve durum topic'lerini izleyin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i laptop-a91c4e \
  -t 'connectmq/demo/a91c4e/relays/#' -v

Ardından kanal 1'i retained bir komutla açın ve kanal 2'yi tersine çevirin:

mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-a91c4e \
  -t 'connectmq/demo/a91c4e/relays/1/set' -m 'ON' -q 1 -r

mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-a91c4e \
  -t 'connectmq/demo/a91c4e/relays/2/set' -m 'TOGGLE' -q 1

Tıklama seslerini duymalı ve relays/1/state ON satırının belirdiğini görmelisiniz. Şimdi Pi'yi yeniden başlatın. Betik yeniden bağlandığında kanal 1 ON durumuna döner, çünkü retained komut hâlâ broker'dadır; kanal 2 ise OFF olarak başlar, çünkü toggle'lar asla retained yapılmaz. Retained bir komutu temizlemek için boş bir retained mesaj yayınlayın: mosquitto_pub ... -t '.../relays/1/set' -r -n.

Servis Olarak Çalıştırın

Bir röle kontrolcüsü açılışta başlamalı ve bir çökmeden sonra yeniden başlamalıdır. /etc/systemd/system/relay-mqtt.service dosyasını oluşturun:

[Unit]
Description=Relay MQTT controller
After=network-online.target
Wants=network-online.target

[Service]
User=pi
WorkingDirectory=/home/pi/relay-mqtt
Environment=MQTT_HOST=broker.connectmq.com
Environment=MQTT_PORT=8883
Environment=MQTT_USERNAME=YOUR_USERNAME
Environment=MQTT_PASSWORD=YOUR_PASSWORD
Environment=MQTT_CLIENT_ID=YOUR_CLIENT_ID
Environment=MQTT_PREFIX=home/garage/relays
ExecStart=/home/pi/relay-mqtt/.venv/bin/python relay_mqtt.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

sudo systemctl daemon-reload && sudo systemctl enable --now relay-mqtt ile etkinleştirin. Servis dosyaları, günlükleme ve ortam dosyalarının tam açıklaması Python MQTT betiğini açılışta çalıştırma yazısındadır. Kullanıcı adınız pi değilse onu düzenleyin.

Test Broker'ından Üretime Geçiş

Genel test broker'ı ilk bir saat için mükemmeldir, ancak topic'inizi tahmin eden herkes rölelerinizi anahtarlayabilir. Gerçek ekipmana bağlı her şey için kimlik doğrulamalı ve TLS'li özel bir broker kullanın. ConnectMQ gibi tamamen yönetilen bir MQTT hizmeti ile portalda bir broker oluşturur, oluşturulan kullanıcı adını, parolayı ve client ID'yi yukarıdaki servis dosyasına kopyalar ve portu 8883 olarak ayarlarsınız. Client ID verilen kimlik bilgilerine bağlıdır; böylece başka bir cihaz kontrolcünüzü taklit edemez. Betik hiç değişmez.

ConnectMQ portalı devreye alma sırasında da yardımcı olur: tarayıcı içi MQTT istemcisi her kanala ON ve OFF yayınlayabilir; canlı topic gezgini de retained durum ve status değerlerini bir bakışta gösterir. Aynı iş için Pi'ye donanım alternatifi istiyorsanız, onu MQTT üzerinden ESP32 röle projesiyle karşılaştırın.

Sorun Giderme

  1. Röleler başlangıçta açılıyor ve açma komutu verildiğinde kapanıyor: kartınız aktif-yüksektir; ACTIVE_HIGH = True olarak ayarlayın.
  2. Karttaki LED'ler yanıyor ama röle tıklamıyor: bobin beslemesi çok zayıf; JD-VCC'yi ayrı bir 5 V kaynaktan besleyin.
  3. Connection refused: Not authorized: kullanıcı adını, parolayı ve client ID'yi kontrol edin veya anonim genel broker'ı kullanırken bunları kaldırın.
  4. Röle yeniden başlatmadan sonra eski bir durumu geri yüklüyor: broker'da eskimiş bir retained komut var; boş bir retained yayınla temizleyin.
  5. GPIO busy hataları: başka bir betik veya servis aynı pinleri kullanıyor; bunu başlatmadan önce onu durdurun.

ConnectMQ ile Başlayın

Gerçek ekipmanı kontrol etmeye hazır mısınız? Kredi kartı gerekmeden ücretsiz Serverless plana kaydolun, bir broker oluşturun ve röle servisinizi TLS üzerinden ona yönlendirin. MQTT 3.1.1 ve 5.0, retained mesajlar ve her anahtarlama olayını izleyebileceğiniz bir portal elde edersiniz. Kavramlara yeni misiniz? Raspberry Pi MQTT eğitimi temelleri anlatır; bulut MQTT broker genel bakışımız da barındırmanın Pi üzerinde Mosquitto çalıştırmaktan ne zaman daha iyi olduğunu açıklar.

Sık Sorulan Sorular

Rölem neden Raspberry Pi yeniden başladıktan sonra durum değiştiriyor?

Broker'dan retained bir komutu tekrar oynatıyordur; bu genellikle istediğiniz şeydir. Durum yanlışsa doğru değeri retain ile yayınlayın veya topic'i boş bir retained mesajla temizleyin.

Röle komutları için QoS 1 kullanabilir miyim?

Evet, kullanmalısınız da. QoS 1 komutun en az bir kez ulaşmasını garanti eder; ON ve OFF idempotent olduğundan yinelenen bir teslim zarar vermez.

Tek bir Raspberry Pi kaç röleyi kontrol edebilir?

Boş GPIO pininiz kadar; bir hobi kartında genellikle sekize kadar. Daha fazla kanal için MCP23017 gibi bir I2C GPIO genişletici kullanın ve aynı topic düzenini koruyun.

Şebeke gerilimli cihazları bu şekilde kontrol etmek güvenli mi?

Yalnızca yüke uygun değerde röleler, uygun bir muhafaza ve yerel elektrik yönetmeliğine göre yapılmış kablolamayla. Gerçek ekipmanı anahtarlayan her şey için her zaman kimliği doğrulanmış TLS bağlantıları kullanın.

İlgili yazılar

RC522 Okuyucu ile Raspberry Pi RFID MQTT Erişim Kaydı

Bir RC522 RFID okuyucuyu Raspberry Pi'ye bağlayın, etiketleri Python ile okuyun, yerel bir izin listesiyle karşılaştırın ve her erişim denemesini kayıt araçlarının, panellerin ve uyarı araçlarının tüketebileceği bir MQTT olayı olarak yayınlayın.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.