ESP32 ve Arduino

ESP32 Röle MQTT: Şebeke Yüklerini Komutlar ve Retained Durumla Anahtarlayın

Bir röle modülünü ESP32'ye bağlayın, bir MQTT komut topic'inden anahtarlayın ve retained durum yayınlayarak her dashboard ve uygulamanın yükün açık mı kapalı mı olduğunu her zaman bilmesini sağlayın.

Bir esp32 röle mqtt projesinde iki kanallı bir röle modülüne bağlı ESP32 kartı
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 ESP32 röle MQTT kontrolcüsü; lambaları, pompaları, fanları veya kontaktörleri mesaj yayınlayabilen herhangi bir uygulamadan, betikten veya dashboard'dan anahtarlamanızı sağlar. Bu eğitimde bir röle modülünü ESP32'ye bağlayacak, bir komut topic'ine abone olacak, röle durumunu retained message olarak yayınlayacak ve yeniden başlatmadan sonra bilinen son durumu geri yükleyeceksiniz. Her şey önce broker.connectmq.com adresinin ücretsiz herkese açık alanında test edilir, ardından production için kimlik bilgilerine taşınır.

ESP32 Röle MQTT Tasarımı Nasıl Çalışır?

Bir röle düğümü IoT'deki en basit kullanışlı aktüatördür, ancak pek çok projenin yanlış gittiği yer de burasıdır. Yaygın hata, MQTT'yi uzaktan bir düğme gibi ele almaktır: bir şey ON yayınlar, ESP32 röleyi anahtarlar ve komutun gerçekten ulaşıp ulaşmadığını kimse bilmez. Daha iyi bir tasarım, birinin ne istediğini cihazın gerçekte ne yaptığından ayırır.

Topic Yön Retained Payload
connectmq/demo/<id>/relay/1/set Uygulamadan ESP32'ye Hayır ON, OFF, TOGGLE
connectmq/demo/<id>/relay/1/state ESP32'den uygulamalara Evet ON veya OFF
connectmq/demo/<id>/status ESP32'den uygulamalara Evet online veya offline (Last Will)

Komut topic'i retained değildir. Öyle olsaydı her yeniden bağlanma eski bir komutu tekrar oynatırdı ve birinin elle kapattığı bir röle aniden yeniden açılabilirdi. Durum topic'i ise retained'dır; böylece bir dakika sonra açılan bir dashboard bir sonraki değişikliği beklemeden mevcut durumu hemen alır. status topic'i MQTT'nin Last Will özelliğini kullanır; böylece aboneler düğüm ağdan düştüğünde bunu öğrenir.

Retained message ve Last Will sizin için yeniyse, MQTT broker'ın ne yaptığına dair genel bakış ikisini de birkaç dakikada açıklar.

Donanım ve Kablolama

İhtiyacınız olanlar:

  • Herhangi bir ESP32 geliştirme kartı (DevKitC, NodeMCU-32S, WROOM veya WROVER modüllerinin hepsi çalışır).
  • Optokuplör girişli 1, 2 veya 4 kanallı bir röle modülü. "High/low level trigger" jumper'lı 5 V olarak satılan modüller en esnek olanlardır.
  • Jumper kablolar ve bir USB kablosu. Şebekeye bağlanan her şey için uygun bir kutu ve klemens blokları.

5 V bir modül için tipik kablolama:

Röle modülü pini ESP32 pini Not
VCC 5V (VIN) Röle bobinini besler
GND GND Ortak toprak
IN1 GPIO 26 Kanal 1 için kontrol sinyali
IN2 GPIO 27 Kanal 2 için kontrol sinyali (isteğe bağlı)

Ucuz röle kartlarının çoğu active-low'dur: giriş GND'ye çekildiğinde röle enerjilenir. Aşağıdaki sketch'te bu mantığı tersine çevirmek için tek bir sabit vardır. Röleler için GPIO 0, 2, 12 ve 15'ten kaçının; bunlar strapping pinleridir ve açılış sırasında tıklayan bir röle hem can sıkıcıdır hem de bazı yüklerde tehlikelidir. GPIO 34 ile 39 yalnızca giriştir ve çalışmaz.

Bir güvenlik notu: şebeke gerilimini anahtarlıyorsanız röle modülü yük için uygun değerde olmalı, yüksek gerilim tarafı kapalı bir kutu içinde bulunmalı ve çalışma yerel elektrik yönetmeliklerine uygun yapılmalıdır. Firmware'i geliştirirken düşük gerilimli bir LED şeridi anahtarlayın veya hiçbir şey bağlamadan tıklamayı dinleyin.

Kütüphaneleri Kurun

Arduino IDE 2.x'te Boards Manager üzerinden Espressif'in esp32 kart paketini, Library Manager üzerinden de Nick O'Leary'nin PubSubClient kütüphanesini kurun. Başka kütüphane gerekmez. Daha önce ESP32'de bir MQTT sketch'i yapmadıysanız ESP32 IoT eğitimi kart kurulumunu ve ilk yayınınızı daha ayrıntılı anlatır.

Eksiksiz ESP32 Röle MQTT Sketch'i

Aşağıdaki sketch istediğiniz sayıda röleyi destekler, döngüyü engellemeden yeniden bağlanmaları yönetir ve her değişiklikten sonra retained durum yayınlar.

#include <WiFi.h>
#include <PubSubClient.h>

// ---------- Yapılandırma ----------
const char* WIFI_SSID     = "YOUR_WIFI";
const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD";

const char* MQTT_HOST = "broker.connectmq.com";
const uint16_t MQTT_PORT = 1883;
const char* DEVICE_ID = "relay-7f3a91";          // bunu benzersiz yapın
const String BASE = String("connectmq/demo/") + DEVICE_ID;

const bool ACTIVE_LOW = true;                     // çoğu röle kartı
const uint8_t RELAY_PINS[] = {26, 27};
const uint8_t RELAY_COUNT = sizeof(RELAY_PINS);
bool relayState[RELAY_COUNT] = {false};
bool restoreWindow = true;                        // açılışta retained durumu bir kez kabul et
unsigned long connectedAt = 0;

WiFiClient net;
PubSubClient mqtt(net);
unsigned long lastAttempt = 0;

void applyRelay(uint8_t i, bool on) {
  relayState[i] = on;
  digitalWrite(RELAY_PINS[i], (on ^ ACTIVE_LOW) ? HIGH : LOW);
}

void publishState(uint8_t i) {
  String topic = BASE + "/relay/" + String(i + 1) + "/state";
  mqtt.publish(topic.c_str(), relayState[i] ? "ON" : "OFF", true);
}

void onMessage(char* topic, byte* payload, unsigned int length) {
  String t(topic);
  String msg;
  for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
  msg.trim();
  msg.toUpperCase();

  // Beklenen: <BASE>/relay/<n>/set veya <BASE>/relay/<n>/state
  int start = BASE.length() + 7;                  // "/relay/" kısmını atla
  int slash = t.indexOf('/', start);
  if (slash < 0) return;
  int n = t.substring(start, slash).toInt();
  if (n < 1 || n > RELAY_COUNT) return;
  uint8_t i = n - 1;
  String leaf = t.substring(slash + 1);

  if (leaf == "state") {
    // Yeniden başlatma öncesindeki retained durum: bir kez geri yükle, sonra yok say
    if (restoreWindow) applyRelay(i, msg == "ON");
    return;
  }
  if (leaf != "set") return;

  if (msg == "ON")          applyRelay(i, true);
  else if (msg == "OFF")    applyRelay(i, false);
  else if (msg == "TOGGLE") applyRelay(i, !relayState[i]);
  else return;                                    // bilinmeyen komutları yok say

  publishState(i);
  Serial.printf("Relay %d -> %s\n", n, relayState[i] ? "ON" : "OFF");
}

bool connectMqtt() {
  String willTopic = BASE + "/status";
  bool ok = mqtt.connect(DEVICE_ID, nullptr, nullptr,
                         willTopic.c_str(), 1, true, "offline");
  if (!ok) {
    Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
    return false;
  }
  mqtt.publish(willTopic.c_str(), "online", true);
  for (uint8_t i = 0; i < RELAY_COUNT; i++) {
    String base = BASE + "/relay/" + String(i + 1);
    mqtt.subscribe((base + "/set").c_str(), 1);
    if (restoreWindow) mqtt.subscribe((base + "/state").c_str(), 1);
  }
  connectedAt = millis();
  Serial.println("MQTT connected");
  return true;
}

void setup() {
  Serial.begin(115200);
  for (uint8_t i = 0; i < RELAY_COUNT; i++) {
    pinMode(RELAY_PINS[i], OUTPUT);
    applyRelay(i, false);                         // Wi-Fi öncesi güvenli varsayılan
  }
  WiFi.mode(WIFI_STA);
  WiFi.setAutoReconnect(true);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  mqtt.setCallback(onMessage);
  mqtt.setKeepAlive(30);
  mqtt.setSocketTimeout(5);
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) return;

  if (!mqtt.connected()) {
    if (millis() - lastAttempt > 5000) {
      lastAttempt = millis();
      connectMqtt();
    }
    return;
  }
  mqtt.loop();

  // İlk bağlantıdan iki saniye sonra geri yükleme penceresini kapat
  if (restoreWindow && millis() - connectedAt > 2000) {
    restoreWindow = false;
    for (uint8_t i = 0; i < RELAY_COUNT; i++) {
      String s = BASE + "/relay/" + String(i + 1) + "/state";
      mqtt.unsubscribe(s.c_str());
      publishState(i);                            // gerçek durumu onayla
    }
  }
}

Geri yükleme penceresi ne işe yarar?

ESP32 bir elektrik kesintisinden sonra yeniden başladığında röleler güvenli OFF konumunda başlar. İlk bağlantıda sketch kısa süreliğine kendi retained state topic'lerine abone olur. Broker elinde tuttuğu son durumu hemen iletir, sketch bunu uygular ve iki saniye sonra aboneliği bırakıp gerçek durumu yeniden yayınlar. Rölelerin her zaman kapalı başlamasını tercih ediyorsanız restoreWindow değerini false yapın. Isıtıcılar gibi kritik yükler için "yeniden başlatmadan sonra her zaman kapalı" genellikle daha güvenli politikadır.

Bunun, broker'ın retained mesajı hâlâ tutmasına dayandığını unutmayın. Retained message'lar broker onları sakladığı sürece yaşar; bu yüzden geri yüklemeyi bir garanti değil bir kolaylık olarak görün ve yükü OFF her zaman kabul edilebilir bir durum olacak şekilde tasarlayın.

Röleyi Bilgisayarınızdan Test Edin

Bir terminal açın ve cihaz önekinizin altındaki her şeyi izleyin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-7f3a91 -v -t "connectmq/demo/relay-7f3a91/#"

İkinci bir terminalde komut gönderin:

mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-7f3a91 -t "connectmq/demo/relay-7f3a91/relay/1/set" -m ON
mosquitto_pub -h broker.connectmq.com -p 1883 -i cmd-7f3a91 -t "connectmq/demo/relay-7f3a91/relay/1/set" -m TOGGLE

Tıklamayı duymalı ve retained durumun geri yansıdığını görmelisiniz:

connectmq/demo/relay-7f3a91/status online
connectmq/demo/relay-7f3a91/relay/1/state ON
connectmq/demo/relay-7f3a91/relay/1/state OFF

Şimdi ESP32'nin fişini çekin. Kabaca bir buçuk keep-alive aralığı içinde broker Last Will'i yayınlar ve abone status offline yazdırır. Bu, bir dashboard'un anahtarı gri göstermek için ihtiyaç duyduğu sinyalin ta kendisidir. broker.connectmq.com bir herkese açık MQTT test broker'ı olduğundan, topic'inizi tahmin eden herkes rölenizi anahtarlayabilir; bu yüzden herkese açık alana asla gerçek bir yük bağlı bırakmayın.

Sorun Giderme Kontrol Listesi

  1. Röle açılışta tıklıyor. Bir strapping pinindesiniz ya da modül active-low ve pin setup() çalışmadan önce boşta kalıyor. GPIO 26/27/32/33'e geçin ve mümkünse pin seviyesini pinMode öncesinde ayarlayın.
  2. Modüldeki LED yanmasına rağmen röle hiç anahtarlamıyor. Pek çok modül bobin için VCC'de 5 V'a ihtiyaç duyar; 3,3 V LED'i yakar ama kontakları çekemez. Bazı kartlarda JD-VCC jumper'ının da takılı olması gerekir.
  3. Komutlar bir kez çalışıyor, sonra duruyor. Seri logda state=-3 (bağlantı koptu) olup olmadığını kontrol edin. İki cihazda aynı client ID'yi kullanmak, birbirlerini sürekli dışarı atmalarına neden olur.
  4. Röle anahtarlandığında ESP32 resetleniyor. Endüktif yükler besleme düşüşlerine ve gürültüye neden olur. Röle bobinini ortak topraklı ayrı bir 5 V kaynaktan besleyin ve yük tarafında snubber veya flyback koruması kullanın.
  5. Durum topic'i yeniden başlatmadan sonra yanlış değer gösteriyor. Başka bir şey state topic'ine retained mesaj yayınlıyor. Oraya yalnızca cihazın kendisi yayın yapmalıdır.
  6. Hiçbir şey gelmiyor. Topic adları büyük/küçük harfe duyarlıdır ve sondaki fazladan bir eğik çizgi farklı bir topic oluşturur.

Kimlik Bilgileri ve TLS ile Production'a Geçin

Gerçek bir kurulum için ConnectMQ portalında bir broker oluşturun ve üretilen kullanıcı adını, parolayı ve client ID'yi kullanın. WiFiClient yerine WiFiClientSecure kullanın, 8883 portuna bağlanın ve kimlik bilgilerini connect() fonksiyonuna verin:

#include <WiFiClientSecure.h>
WiFiClientSecure net;
// setup() içinde: net.setCACert(ROOT_CA_PEM);   // ISRG Root X1 (Let's Encrypt)
mqtt.setServer("broker.connectmq.com", 8883);
mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD",
             willTopic.c_str(), 1, true, "offline");

Client ID'ler verilen kimlik bilgilerine bağlı olduğundan, kendi uydurduğunuz bir ID yerine portalın ürettiği client ID'yi kullanın. Saat senkronizasyonu ve bellek konuları dahil eksiksiz sertifika kurulumu SSL/TLS üzerinden ESP32 MQTT yazısında ele alınmıştır. Röle düğümünüzün kararsız Wi-Fi'ye dayanması gerekiyorsa ESP32 MQTT yeniden bağlanma mantığı yazısındaki geri çekilme (backoff) stratejisini eklemeye de değer.

Tam yönetilen bir MQTT servisi en çok aktüatörler için önemlidir: ulaşamadığınız bir röle, okuyamadığınız bir sensörden daha kötüdür. ConnectMQ ile 8883'te TLS, cihaz başına kimlik bilgileri ve canlı topic gezgininde relay/+/state izleyebileceğiniz veya terminale dokunmadan tarayıcı içi client'tan test komutu yayınlayabileceğiniz bir portal elde edersiniz.

Röle Düğümünü Genişletmek İçin Fikirler

  • Zamanlayıcılar. JSON olarak {"state":"ON","seconds":600} kabul edin ve on dakika sonra otomatik olarak kapatın. Zamanlayıcıyı cihazda tutun ki ağ düşse bile kapanabilsin.
  • Yerel düğme. Röleyi değiştiren ve yeni durumu yayınlayan bir buton ekleyin; böylece fiziksel anahtar ile uygulama hiçbir zaman çelişmez.
  • Kilitlemeler (interlock). Motor yön değiştirme veya iki yollu vanalar için her iki kanalın aynı anda açılmasını uygulamada değil firmware'de reddedin.
  • Servo veya LED kardeşleri. Aynı komut/durum deseni MQTT üzerinden servo kontrolü ve adreslenebilir LED şeritleri için de çalışır.

ConnectMQ ile Başlayın

app.connectmq.com adresinde ücretsiz bir Serverless broker oluşturun, kredi kartı gerekmez. Bir dakikadan kısa sürede kimlik bilgilerinizi, kutudan çıktığı haliyle TLS'i ve rölelerinizin anahtarlanmasını izleyebileceğiniz canlı bir topic gezgini elde edersiniz. Ücretsiz katmanı aştığınızda aynı firmware, kimlik bilgileri dışında hiçbir şeyi değiştirmeden ücretli veya dedicated bir plana geçer.

Sık Sorulan Sorular

Röle komut topic'i retained olmalı mı?

Hayır. Komut topic'ini değil, durum topic'ini retained yapın. Retained bir komut her yeniden bağlanmada tekrar oynatılır ve bir yükü beklenmedik şekilde anahtarlayabilir.

Röle komutları için hangi QoS'u kullanmalıyım?

QoS 1 pratik seçimdir: komut en az bir kez teslim edilir ve ON ile OFF idempotent olduğundan bir kopya zarar vermez. PubSubClient QoS 0 veya 1 ile abone olabilir.

Tek bir ESP32 ile birden fazla röle kontrol edebilir miyim?

Evet. Pinleri RELAY_PINS dizisine ekleyin; her biri kendi relay/<n>/set ve relay/<n>/state topic'lerini alır. Kanal numarasını topic'ten ayrıştırırsanız relay/+/set için tek bir wildcard aboneliği de işe yarar.

ESP32'nin çevrimdışı olduğunu nasıl anlarım?

Retained status topic'ine abone olun. ESP32 bağlandığında online yayınlar; bağlantı düzgün bir disconnect olmadan koparsa broker offline Last Will mesajını yayınlar.

İlgili yazılar

ESP32 NTP MQTT Zaman Damgası: Her Mesaja Doğru Zaman Ekleyin

ESP32 saatini NTP ile eşitleyin, ISO 8601 ve epoch milisaniye zaman damgalarını biçimlendirin ve bunları MQTT payload'larına ekleyin; böylece ölçümler geç yayınlansa bile gerçek alınma zamanlarını korur.

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.