ESP32 ve Arduino

ESP8266 MQTT Eğitimi: NodeMCU'yu Bulut Broker'a Bağlayın (Düz ve TLS)

Bir ESP8266 NodeMCU'yu PubSubClient ile bir MQTT broker'a bağlayın, JSON telemetri yayınlayın, karttaki LED'i kontrol edin, ardından sınırlı heap'i kontrol altında tutarak BearSSL ile TLS ekleyin.

Bir bulut broker'a ESP8266 MQTT mesajları gönderen, breadboard üzerindeki NodeMCU ESP8266 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

ESP8266, bir sensörü Wi-Fi'ye bağlamanın hâlâ en ucuz yollarından biridir ve ESP8266 MQTT projeleri onun küçük kaynak ayak izine doğal olarak uyar. Bu eğitimde bir NodeMCU veya Wemos D1 mini'yi PubSubClient ile bir broker'a bağlayacak, JSON telemetri yayınlayacak, karttaki LED'i bilgisayarınızdan açıp kapatacak ve ardından belleği tüketmeden TLS'e geçeceksiniz.

Neye İhtiyacınız Var?

  • Bir NodeMCU v2/v3, Wemos D1 mini veya USB'li herhangi bir ESP8266 kartı.
  • "esp8266 by ESP8266 Community" kart paketi kurulu Arduino IDE 2.x (File → Preferences → Additional boards manager URLs altına https://arduino.esp8266.com/stable/package_esp8266com_index.json ekleyin).
  • Library Manager'dan Nick O'Leary'nin PubSubClient kütüphanesi.
  • Test için bilgisayarınızda Mosquitto komut satırı araçları.
  • 2,4 GHz bir Wi-Fi ağı. ESP8266, 5 GHz'i desteklemez.

İlk adımlar için ConnectMQ tarafından işletilen ücretsiz herkese açık MQTT broker olan broker.connectmq.com adresini kullanacaksınız. Bu broker, 1883 portunda boş olmayan ve benzersiz herhangi bir client ID ile anonim client'ları kabul eder. Onu herkese açık bir ilan panosu gibi düşünün: orada yayınladığınız her şeyi başkaları okuyabilir.

Önemli Kart Ayarları

Kod yazmadan önce Tools menüsünde şunları ayarlayın:

Ayar Önerilen değer Neden
Board NodeMCU 1.0 (ESP-12E Module) veya LOLIN(WEMOS) D1 mini Doğru flash düzeni ve pin adları
CPU Frequency TLS için 160 MHz, aksi halde 80 MHz TLS el sıkışmaları 160 MHz'te çok daha hızlıdır
SSL Support All SSL ciphers (varsayılan) veya Basic SSL ciphers Basic flash tasarrufu sağlar, modern broker'larla yine çalışır
lwIP Variant v2 Lower Memory Sketch'iniz için daha fazla heap bırakır
Upload Speed 921600 (yükleme başarısız olursa 115200'e düşürün) Daha hızlı geliştirme döngüsü

Adım 1: İlk ESP8266 MQTT Sketch'iniz

Aşağıdaki sketch, çoğu modülde active-low olan GPIO2'deki (LED_BUILTIN) dahili LED'i kullanır. Her beş saniyede bir çalışma süresini, sinyal gücünü ve boş heap'i yayınlar ve ON veya OFF komutlarını dinler.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

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;

char deviceId[24];
char topicTelemetry[64];
char topicLedSet[64];
char topicLedState[64];

WiFiClient netClient;
PubSubClient mqtt(netClient);

unsigned long lastPublish = 0;
unsigned long lastAttempt = 0;

void setLed(bool on) {
  digitalWrite(LED_BUILTIN, on ? LOW : HIGH);   // active-low
  mqtt.publish(topicLedState, on ? "ON" : "OFF", true);
}

void onMessage(char* topic, byte* payload, unsigned int length) {
  char msg[16];
  unsigned int n = length < sizeof(msg) - 1 ? length : sizeof(msg) - 1;
  memcpy(msg, payload, n);
  msg[n] = '\0';
  Serial.printf("[%s] %s\n", topic, msg);

  if (strcmp(msg, "ON") == 0)  setLed(true);
  if (strcmp(msg, "OFF") == 0) setLed(false);
}

void connectWifi() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
    Serial.print(".");
  }
  Serial.printf(" connected, IP %s\n", WiFi.localIP().toString().c_str());
}

bool connectMqtt() {
  if (mqtt.connect(deviceId, nullptr, nullptr, topicLedState, 1, true, "offline")) {
    Serial.println("MQTT connected");
    mqtt.subscribe(topicLedSet, 1);
    setLed(false);
    return true;
  }
  Serial.printf("MQTT failed, rc=%d\n", mqtt.state());
  return false;
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);

  // Chip ID'den benzersiz ID, ör. esp8266-3f2a1b
  snprintf(deviceId, sizeof(deviceId), "esp8266-%06x", ESP.getChipId());
  snprintf(topicTelemetry, sizeof(topicTelemetry), "connectmq/demo/%s/telemetry", deviceId);
  snprintf(topicLedSet,    sizeof(topicLedSet),    "connectmq/demo/%s/led/set", deviceId);
  snprintf(topicLedState,  sizeof(topicLedState),  "connectmq/demo/%s/led/state", deviceId);
  Serial.printf("\nDevice ID: %s\n", deviceId);

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

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

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

  if (millis() - lastPublish > 5000) {
    lastPublish = millis();
    char payload[96];
    snprintf(payload, sizeof(payload), "{\"uptime\":%lu,\"rssi\":%d,\"heap\":%u}",
             millis() / 1000, WiFi.RSSI(), ESP.getFreeHeap());
    mqtt.publish(topicTelemetry, payload);
  }
}

Seri monitörü 115200 baud'da açın ve cihaz ID'sini not edin, ardından bilgisayarınızdan abone olun (ID'yi kendinizinkiyle değiştirin):

mosquitto_sub -h broker.connectmq.com -p 1883 -i laptop-3f2a1b -t "connectmq/demo/esp8266-3f2a1b/#" -v

LED'i açıp kapatın:

mosquitto_pub -h broker.connectmq.com -p 1883 -i ctl-3f2a1b -t "connectmq/demo/esp8266-3f2a1b/led/set" -m ON

led/state topic'i retained olduğundan, her yeni abone LED'in açık olup olmadığını hemen öğrenir; kartın gücü kesilirse Last Will bu değeri offline yapar.

Adım 2: ESP8266 Bellek Bütçesini Anlayın

Düz sketch çalıştıktan sonra yayınladığı heap değerini kontrol edin. Basit bir sketch genellikle rahat miktarda boş heap bırakır, ancak TLS tabloyu değiştirir. Varsayılan buffer'larla bir BearSSL oturumu, alma ve gönderme buffer'ları ile sertifika doğrulama işi için büyük, bitişik bir bellek bloğuna ihtiyaç duyar; ESP8266'nın RAM'i ise ESP32'ninkinin yalnızca bir kısmı kadardır.

Pratik sonuçlar:

  • PubSubClient buffer'ını mesajlarınızın izin verdiği kadar küçük tutun. "Ne olur ne olmaz" diye setBufferSize(4096) çağırmak, çalışan ile başarısız olan bir el sıkışma arasındaki fark olabilir.
  • Uzun süre çalışan sketch'lerde String sınıfını yoğun kullanmaktan kaçının; tekrarlanan bellek ayırmalar heap'i parçalar ve boş heap iyi görünse bile TLS el sıkışması günler sonra başarısız olabilir. ESP.getMaxFreeBlockSize() en büyük bitişik bloğu gösterir; önemli olan sayı budur.
  • JSON'u string birleştirme yerine snprintf veya sabit boyutlu bir ArduinoJson belgesiyle oluşturun.

Düzenli olarak büyük payload'lara ihtiyacınız varsa, büyük buffer'lardan kaçınan akış (streaming) teknikleri için PubSubClient buffer boyutu yazısını okuyun.

Adım 3: TLS Üzerinden ESP8266 MQTT

Production için cihazınız, kendi kimlik bilgileriyle 8883 portunda TLS üzerinden özel bir broker'a bağlanmalıdır. ConnectMQ gibi yönetilen bir MQTT broker ile portaldan bir kullanıcı adı, parola ve client ID alırsınız. Sunucu sertifikası Let's Encrypt tarafından verilir, bu yüzden ISRG Root X1 kök sertifikasına güvenirsiniz.

ESP8266 core'u BearSSL kullanır. ESP32'nin aksine sertifika geçerlilik tarihlerini kontrol eder, bu nedenle el sıkışmadan önce saatin doğru olması gerekir.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <time.h>

// ISRG Root X1 (Let's Encrypt kökü), PEM'in tamamını yapıştırın
static const char ROOT_CA[] PROGMEM = R"EOF(
-----BEGIN CERTIFICATE-----
...ISRG Root X1...
-----END CERTIFICATE-----
)EOF";

BearSSL::X509List trustAnchors(ROOT_CA);
BearSSL::WiFiClientSecure tlsClient;
PubSubClient mqtt(tlsClient);

void syncClock() {
  configTime(0, 0, "pool.ntp.org", "time.nist.gov");
  Serial.print("Waiting for NTP");
  time_t now = time(nullptr);
  while (now < 1700000000) {      // geçmişte kalmış herhangi bir zaman damgası
    delay(250);
    Serial.print(".");
    now = time(nullptr);
  }
  Serial.println(" done");
}

void setupTls() {
  syncClock();
  tlsClient.setTrustAnchors(&trustAnchors);
  // İsteğe bağlı: sunucu max fragment length destekliyorsa daha küçük buffer'lar
  if (tlsClient.probeMaxFragmentLength("broker.connectmq.com", 8883, 1024)) {
    tlsClient.setBufferSizes(1024, 1024);
  }
  mqtt.setServer("broker.connectmq.com", 8883);
}

bool connectMqtt() {
  return mqtt.connect("YOUR_CLIENT_ID", "YOUR_USERNAME", "YOUR_PASSWORD");
}

Wi-Fi bağlandıktan sonra setup() içinde setupTls() çağırın. CPU frekansını 160 MHz'e ayarlayın; ilk el sıkışma 80 MHz'te belirgin bir süre alabilir ve yoğun bir döngü içindeki yavaş bir connect() watchdog'unuzun hoşuna gitmez.

Adım 4: Deep Sleep ile Pille Çalışan ESP8266 MQTT

Pek çok ESP8266 sensörü pille çalışır ve yalnızca birkaç dakikada bir rapor vermesi gerekir. Açık ara en büyük güç tüketicisi telsiz modülüdür; bu yüzden kazanan desen şudur: uyan, bağlan, yayınla, bağlantıyı kes, uyu. ESP8266'da deep sleep, GPIO16 (NodeMCU ve D1 mini'de D0) ile RST pini arasında donanımsal bir bağlantı gerektirir, çünkü çip kendini resetleyerek uyanır. Kartınız yükleme sırasında sorun çıkarırsa yüklerken bu kabloyu çıkarın.

void publishAndSleep() {
  connectWifi();
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  if (mqtt.connect(deviceId)) {
    char payload[64];
    snprintf(payload, sizeof(payload), "{\"a0\":%d,\"rssi\":%d}", analogRead(A0), WiFi.RSSI());
    mqtt.publish(topicTelemetry, payload);
    // telsizin gücünü kesmeden önce yığına paketi göndermesi için biraz zaman tanıyın
    for (int i = 0; i < 10; i++) { mqtt.loop(); delay(10); }
    mqtt.disconnect();
  }
  ESP.deepSleep(5 * 60 * 1000000ULL);   // 5 dakika, mikrosaniye cinsinden
}

setup() sonunda publishAndSleep() çağırın ve loop() fonksiyonunu boş bırakın. Birkaç pratik not: her uyanışta bir TLS el sıkışması, düz MQTT'ye göre belirgin şekilde daha fazla zaman ve enerji harcar; bu yüzden güvenlik gereksinimini pil ömrüne karşı tartın ve TLS ile daha uzun uyku aralıklarını değerlendirin. En son okuma için retained message kullanın, böylece uyanışlar arasında açılan dashboard'lar da bir değer görür. Uyuyan cihazlarda varlık bilgisi için Last Will kullanmayın; düzgün bir disconnect() onu asla tetiklemez ve "offline" durumu zaten yanıltıcı olurdu.

ESP8266 MQTT Sorunlarını Giderme

  1. TLS'te rc=-2 ama 1883'te sorun yok: saat senkronize değil, kök sertifika yanlış veya yeterli bitişik heap yok. BearSSL nedenini görmek için tlsClient.getLastSSLError() yazdırın. PubSubClient rc=-2 rehberimiz tüm kodları kapsar.
  2. Rastgele resetler (wdt reset): bir şey çok uzun süre engelliyor. MQTT callback'ine asla uzun delay() çağrıları koymayın ve uzun döngülerde yield() çağırın.
  3. Kart Wi-Fi'ye hiç katılmıyor: yalnızca 5 GHz ağ, yanlış parola veya misafir ağında captive portal.
  4. İkinci bir kart bağlandığında kart bağlantısı kopuyor: iki kart da aynı client ID'yi kullanıyor. Yukarıdaki chip ID yaklaşımı bunu önler.
  5. Birkaç yüz bayttan büyük mesajlar kayboluyor: varsayılan 256 baytlık PubSubClient buffer'ı. Makul ölçüde artırın.
  6. Saatler sonra mesajlar gelmez oluyor: heap parçalanması. getMaxFreeBlockSize() değerini zaman içinde izleyin.

ESP8266 mı ESP32 mi?

ESP8266; tek sensörlü düğümler, röleler ve küçük ekranlar için, özellikle düz MQTT veya ara sıra TLS bağlantılarında son derece yeterlidir. Çok sayıda eş zamanlı TLS oturumuna, Bluetooth'a, daha fazla GPIO'ya veya büyük payload'larla birlikte OTA güncellemeleri için alana ihtiyacınız varsa ESP32'ye geçin. ESP32 ve ESP8266 karşılaştırmamız artıları ve eksileri ele alır; bu kartın yetmediği noktada sonraki adım ESP32 IoT eğitimidir.

ESP8266 Filonuzu ConnectMQ'da Çalıştırın

Prototip çalıştığında onu özel kimlik bilgileri ve TLS ile bir bulut MQTT broker'ına taşıyın. ConnectMQ, TCP 1883 ve TLS 8883 üzerinde MQTT 3.1.1 ve 5.0'ı destekler; portal, kartlarınızın ne yayınladığını kontrol etmek için tarayıcı içi bir MQTT client'ı ve canlı topic gezgini içerir. app.connectmq.com adresinde ücretsiz bir Serverless broker oluşturun, kredi kartı gerekmez.

Sık Sorulan Sorular

ESP8266, TLS üzerinden MQTT kullanabilir mi?

Evet. ESP8266 core'u BearSSL ile gelir ve PubSubClient, BearSSL::WiFiClientSecure ile çalışır. Önce saati senkronize edin, broker'ın kök sertifikasına güvenin ve diğer bellek kullanımını makul düzeyde tutun.

NodeMCU'nun dahili LED'i hangi pini kullanır?

Çoğu NodeMCU ve Wemos D1 mini kartında GPIO2'dir (LED_BUILTIN, D4 olarak da etiketlenir) ve active-low'dur; yani LOW yazmak LED'i yakar.

ESP8266'yı MQTT 5 ile kullanabilir miyim?

PubSubClient yalnızca MQTT 3.1.1'i destekler; bu da çoğu sensör için yeterlidir. Broker, dashboard'lar ve backend'ler gibi MQTT 5 client'larına aynı topic'ler üzerinden yine de hizmet verebilir.

ESP8266'm TLS için neden saate ihtiyaç duyuyor?

BearSSL, sunucu sertifikasının geçerlilik süresi içinde olup olmadığını kontrol eder. Doğru bir saat olmadan cihaz 1970 yılında olduğunu düşünür ve sertifikayı reddeder.

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