ESP32 ve Arduino

ESP32 MQTT Broker'a Bağlanamıyor: Gerçekten İşe Yarayan 12 Çözüm

ESP32'niz bir MQTT broker'a bağlanamadığında izlenecek sistematik bir sorun giderme rehberi: Wi-Fi, DNS, portlar, TLS sertifikaları, kimlik bilgileri, client ID'ler ve PubSubClient durum kodları.

ESP32'nin MQTT broker'a neden bağlanamadığını gösteren ESP32 kartının yanındaki hata ayıklama kontrol listesi
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

ESP32'niz bir MQTT broker'a bağlanamadığında neden neredeyse her zaman, yanlış Wi-Fi bandından düz bir porttaki TLS istemcisine kadar uzanan, öngörülebilir bir düzine sorundan biridir. Bu rehber size sistematik bir kontrol sırası sunar, her PubSubClient hata kodunun ne anlama geldiğini açıklar ve her düzeltmenin broker.connectmq.com üzerinde nasıl doğrulanacağını gösterir.

Hata Koduyla Başlayın

Herhangi bir şeyi değiştirmeden önce bağlantının nerede başarısız olduğunu bulun. PubSubClient nedeni client.state() aracılığıyla bildirir. connect() her false döndürdüğünde bunu yazdırın:

if (!mqtt.connect(clientId.c_str())) {
  Serial.printf("MQTT connect failed, state=%d\n", mqtt.state());
}
state() Sabit Genellikle ne anlama gelir
-4 MQTT_CONNECTION_TIMEOUT Sunucu keepalive süresi içinde yanıt vermedi
-3 MQTT_CONNECTION_LOST Bağlantı kurulduktan sonra koptu
-2 MQTT_CONNECT_FAILED TCP veya TLS bağlantısı hiç açılamadı
-1 MQTT_DISCONNECTED İstemcinin bağlantısı düzgünce kesildi
1 MQTT_CONNECT_BAD_PROTOCOL Broker protokol sürümünü kabul etmiyor
2 MQTT_CONNECT_BAD_CLIENT_ID Client ID reddedildi
3 MQTT_CONNECT_UNAVAILABLE Broker kullanılamıyor
4 MQTT_CONNECT_BAD_CREDENTIALS Yanlış kullanıcı adı veya parola
5 MQTT_CONNECT_UNAUTHORIZED İstemci yetkili değil

Bu ayrım işe yarar: negatif kodlar sorunun MQTT'nin altında (ağ, DNS, TCP, TLS) olduğunu, pozitif kodlar ise broker'ın yanıt verip sizi reddettiğini gösterir. -2 sizi 1–6 numaralı çözümlere, 4 veya 5 ise 7–9 numaralı çözümlere yönlendirir.

Önce Broker Tarafının Çalıştığını Kanıtlayın

Firmware'e dokunmadan önce broker'ı olası nedenler arasından çıkarın. Aynı ağdaki bir bilgisayardan şunu çalıştırın:

mosquitto_sub -h broker.connectmq.com -p 1883 -i pc-test-4821 -t 'connectmq/demo/4821/#' -v

İkinci bir terminalde:

mosquitto_pub -h broker.connectmq.com -p 1883 -i pc-pub-4821 -t connectmq/demo/4821/hello -m test

Mesaj ulaşırsa broker ve internet yolu çalışıyordur; sorun ESP32'de veya onun ağ segmentindedir. Bilgisayarınızdan da ulaşmıyorsa önce ağınızın güvenlik duvarını kontrol edin. Herkese açık MQTT test broker'ı sayfası test edebileceğiniz portları ve sınırları listeler.

Ağ Seviyesindeki Çözümler (Negatif Durum Kodları)

1. Wi-Fi'ın 2,4 GHz'de Gerçekten Bağlı Olduğundan Emin Olun

ESP32 (5 GHz destekli yeni varyantlar hariç) yalnızca 2,4 GHz ağlarla konuşur. Her iki bant için tek SSID kullanan çift bantlı bir router genellikle çalışır, ancak yalnızca 5 GHz olan bir SSID asla çalışmaz. İşlem sırasını da kontrol edin: WiFi.status() == WL_CONNECTED olmadan önce mqtt.connect() çağırmak her zaman -2 ile başarısız olur. WiFi.localIP() ve WiFi.RSSI() değerlerini yazdırın; yaklaşık -80 dBm'den zayıf bir sinyal, broker sorunu gibi görünen aralıklı hatalara yol açar.

2. DNS Çözümlemesini Kontrol Edin

Hostname çözümlenmezse TCP bağlantısı hiç başlamaz. Doğrudan test edin:

IPAddress ip;
if (WiFi.hostByName("broker.connectmq.com", ip)) {
  Serial.println(ip);
} else {
  Serial.println("DNS lookup failed");
}

Buradaki bir hata, DHCP'nin sağladığı DNS sunucusuna veya DNS girişi olmayan bir statik IP yapılandırmasına işaret eder. Statik adres için WiFi.config() kullandığınızda ağ geçidini ve bir DNS sunucusunu da verin.

3. Portu İstemci Sınıfıyla Eşleştirin

Bu tek başına en yaygın hatadır. WiFiClient düz TCP konuşur ve 1883 portunu kullanmalıdır. WiFiClientSecure TLS konuşur ve 8883 portunu kullanmalıdır. Bunları karıştırmak, başka hiçbir ipucu vermeden -2 veya -4 üretir.

İstemci sınıfı Port Taşıma
WiFiClient 1883 TCP üzerinden düz MQTT
WiFiClientSecure 8883 TLS üzerinden MQTT
WebSocket kütüphaneleri 8083 / 8084 (yol /mqtt) WebSocket / secure WebSocket üzerinden MQTT

PubSubClient WebSocket konuşmaz; bu yüzden 8083 ve 8084 portları yalnızca tarayıcı istemcileri ve WebSocket destekli kütüphaneler içindir.

4. TLS Sertifika Doğrulamasını Düzeltin

WiFiClientSecure ile eksik veya yanlış bir CA sertifikası el sıkışmanın sessizce başarısız olmasına neden olur. ConnectMQ bir Let's Encrypt sertifikası kullanır; bu yüzden ISRG Root X1 kökünü setCACert() ile yükleyin. Suçlunun TLS olduğunu doğrulamak için geçici olarak secureClient.setInsecure() çağırın: bağlantı birden çalışırsa CA'nız yanlıştır. setInsecure()'u üretime göndermeyin. Ayrıntılar için TLS hatasını secureClient.lastError(buf, sizeof(buf)) ile okuyun ve eksiksiz bir güvenli kurulum için SSL/TLS üzerinden ESP32 MQTT yazısına bakın.

5. TLS'e Yeterli Bellek ve Zaman Verin

TLS el sıkışmaları onlarca kilobayt heap gerektirir. Sketch'iniz büyük tamponlar, görüntü verisi veya birkaç güvenli istemci ayırıyorsa el sıkışma -2 ile başarısız olur. Bağlanmadan hemen önce ESP.getFreeHeap() yazdırın. Saati de kontrol edin: sertifika doğrulaması tarihleri karşılaştırır ve bazı kütüphaneler geçerli bir saat ister. Bağlanmadan önce configTime() ile NTP eşitlemesi yapmak, kafa karıştırıcı hataların bütün bir sınıfını önler.

6. Ağ Yolunda Engellenen Portları Kontrol Edin

Misafir Wi-Fi, kurumsal ağlar ve bazı mobil hotspot'lar giden 1883 veya 8883 trafiğini engeller. Yukarıdaki bilgisayar testi yalnızca farklı bir ağdan çalıştıysa, ESP32'yi bir telefon hotspot'unda deneyin. Orada bağlanıyorsa asıl ağ MQTT portlarını filtreliyordur ve bunları açması için ağ yöneticisine ihtiyacınız vardır.

Broker Seviyesindeki Çözümler (Pozitif Durum Kodları)

7. Boş Olmayan, Benzersiz Bir Client ID Kullanın

Her istemcinin kendi client ID'sine ihtiyacı vardır. Aynı sabit kodlanmış ID ile yüklenen iki cihaz birbirini broker'dan tekrar tekrar düşürür; bu da -3 durumuyla rastgele kopmalar gibi görünür. Boş bir client ID de broker.connectmq.com'un public alanı dahil birçok broker tarafından reddedilir. ID'yi çipin MAC adresinden türetin:

String clientId = "esp32-" + String((uint32_t)ESP.getEfuseMac(), HEX);

8. Portaldaki Kimlik Bilgilerini ve Client ID'yi Birebir Kullanın

Özel bir ConnectMQ broker'da client ID, verilen kimlik bilgilerine bağlıdır. Oluşturulan kullanıcı adı ve parolayı kullanırken kendi client ID'nizi uydurursanız, parola doğru olsa bile broker bağlantıyı 5 koduyla reddeder. Üç değeri de portaldan kopyalayın: YOUR_CLIENT_ID, YOUR_USERNAME, YOUR_PASSWORD. Koda yapıştırırken görünmeyen sondaki boşluklara dikkat edin.

9. Engellenmeden Önce Yeniden Deneme Fırtınalarını Durdurun

Gecikmesiz bir yeniden bağlanma döngüsü broker'a saniyede çok sayıda bağlantı denemesi gönderebilir. Yanlış kimlik bilgileriyle bu özellikle zararlıdır; çünkü ConnectMQ, flood korumasının bir parçası olarak tekrarlanan başarısız girişlerden sonra IP adreslerini engeller. Denemeler arasında bekleyin ve her başarısızlıktan sonra gecikmeyi artırın:

unsigned long nextAttempt = 0;
unsigned long backoff = 2000;

void ensureMqtt() {
  if (mqtt.connected() || millis() < nextAttempt) return;
  if (mqtt.connect(clientId.c_str())) {
    backoff = 2000;
    mqtt.subscribe("connectmq/demo/4821/cmd");
  } else {
    Serial.printf("connect failed, state=%d, retry in %lu ms\n", mqtt.state(), backoff);
    nextAttempt = millis() + backoff;
    backoff = min(backoff * 2, 60000UL);
  }
}

Engellemeyen yapı aynı zamanda loop()'un yanıt verebilir kalmasını sağlar. ESP32 MQTT yeniden bağlanma rehberi sağlam yeniden bağlanma mantığını daha derinlemesine ele alır.

Bağlandıktan Sonra Kopan Bağlantılar İçin Çözümler

10. mqtt.loop()'u Yeterince Sık Çağırın

PubSubClient keepalive ping'lerini yalnızca loop() içinde gönderir ve gelen paketleri yalnızca orada okur. Keepalive aralığından (varsayılan 15 saniye) uzun bir delay() veya engelleyen bir sensör okuması broker'ın istemcinin öldüğünü düşünmesine neden olur ve -3 ya da -4 görürsünüz. Uzun gecikmeleri millis() zamanlayıcılarıyla değiştirin veya keepalive'ı mqtt.setKeepAlive(30) ile yükseltin. Kart ayrıca yeniden başlıyorsa MQTT projelerinde ESP32 task watchdog sıfırlamaları hakkında okuyun.

11. Büyük Mesajlar İçin Tamponu Büyütün

PubSubClient'ın varsayılan paket tamponu, topic ve başlık dahil 256 bayttır. Daha büyük bir yayın sessizce başarısız olur: publish() false döndürür ve boyutu aşan gelen bir mesaj atılır. Bağlanmadan önce en büyük mesajınıza göre boyutlandırılmış şekilde mqtt.setBufferSize(1024) çağırın.

12. Public Broker Sınırlarına Uyun

broker.connectmq.com'un public alanı mesaj başına 64 KB, istemci başına saniyede 10 mesaj, istemci başına 10 abonelik ve en fazla 8 topic seviyesine izin verir. Sıkı bir döngüde yayın yapan veya çok sayıda topic'e abone olan bir sketch bu sınırları aştığı için bağlantıdan düşürülebilir. Yayın hızını sınırlayın, çok sayıda tekil abonelik yerine tek bir wildcard abonelik kullanın ve connectmq/demo/4821/room/temp gibi topic'leri kısa tutun.

Bir Teşhis Sketch'i

Takıldığınızda bunu yükleyin. Her aşamayı ayrı ayrı raporlar, böylece zincirin tam olarak nerede koptuğunu görürsünüz:

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

const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";
const char* HOST = "broker.connectmq.com";

WiFiClient net;
PubSubClient mqtt(net);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) { delay(250); Serial.print('.'); }
  Serial.printf("\nWi-Fi OK  ip=%s rssi=%d\n", WiFi.localIP().toString().c_str(), WiFi.RSSI());

  IPAddress ip;
  if (!WiFi.hostByName(HOST, ip)) { Serial.println("DNS FAILED"); return; }
  Serial.printf("DNS OK    %s\n", ip.toString().c_str());

  if (!net.connect(HOST, 1883)) { Serial.println("TCP 1883 FAILED"); return; }
  Serial.println("TCP OK");
  net.stop();

  String id = "esp32-diag-" + String((uint32_t)ESP.getEfuseMac(), HEX);
  mqtt.setServer(HOST, 1883);
  if (mqtt.connect(id.c_str())) {
    Serial.println("MQTT OK");
    mqtt.publish("connectmq/demo/4821/diag", "hello from diag");
  } else {
    Serial.printf("MQTT FAILED state=%d\n", mqtt.state());
  }
}

void loop() { mqtt.loop(); }

mosquitto_sub'ı connectmq/demo/4821/# üzerinde çalışır halde tutun; her şey çalıştığı anda teşhis mesajını göreceksiniz.

Test Broker'ında Çalışıp Üretimde Çalışmıyorsa

Üretimdeki hataların çoğu 3, 4 ve 8 numaralı çözümlere dayanır: WiFiClientSecure'a geçmeden 8883 portuna geçmek, CA sertifikasını unutmak veya portal kimlik bilgileriyle kendi uydurduğunuz bir client ID kullanmak. Her seferinde tek bir şeyi değiştirin ve hata kodunu yazdırmaya devam edin. ESP32 IoT eğitimi her iki modda da sorunsuz bağlanan eksiksiz bir proje gösterir; bir MQTT broker'ın ne yaptığı yazısı da broker'ın belirli bağlantıları neden reddettiğini açıklar.

ConnectMQ ile ESP32'nizi Çevrimiçi Yapın

Cihaz test broker'ına bağlandıktan sonra onu app.connectmq.com adresinde, kredi kartı gerekmeden, ücretsiz Serverless planındaki özel bir broker'a taşıyın. Portalın tarayıcı içi MQTT istemcisi ve canlı topic gezgini, trafiği hem cihaz tarafından hem de sunucu tarafından doğrulamayı kolaylaştırır. ConnectMQ, kutudan çıktığı haliyle 8883 portunda TLS sunan yönetilen bir MQTT broker'dır; bu yüzden ESP32'de ihtiyacınız olan tek sertifika public Let's Encrypt köküdür.

Sık Sorulan Sorular

PubSubClient rc=-2 ne anlama gelir?

TCP veya TLS bağlantısının açılamadığı, dolayısıyla broker'ın hiç MQTT paketi görmediği anlamına gelir. Wi-Fi'ı, DNS'i, port ve istemci sınıfı eşleşmesini, CA sertifikasını ve boş heap'i kontrol edin.

ESP32'm neden bağlanıp birkaç saniyede bir bağlantıyı kesiyor?

Genellikle başka bir cihaz aynı client ID'yi kullanıyordur ya da mqtt.loop() keepalive ping'lerini gönderecek kadar sık çağrılmıyordur. Her cihaza benzersiz bir ID verin ve uzun engelleyen gecikmeleri kaldırın.

PubSubClient ile 8083 veya 8084 portunu kullanabilir miyim?

Hayır. Bunlar WebSocket portlarıdır ve PubSubClient yalnızca ham TCP veya TLS üzerinden MQTT konuşur. WiFiClient ile 1883'ü veya WiFiClientSecure ile 8883'ü kullanın.

Parola doğru olduğu halde kimlik bilgilerim neden reddediliyor?

Verilmiş kimlik bilgileri olan özel bir broker'da client ID bunlara bağlıdır. Oluşturulan kullanıcı adı ve parolayla birlikte portalda gösterilen client ID'yi birebir kullanın.

İ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.