Panduan · 15 mnt baca

Tutorial MQTT ESP32: Mosquitto, Home Assistant, dan ESPHome

Tutorial MQTT ESP32: instal Mosquitto, kirim data sensor dan kendalikan relay dengan PubSubClient, MQTT Discovery Home Assistant, contoh YAML ESPHome, dan QoS.

Memasangkan ESP32 dengan MQTT adalah cara paling umum agar sensor dan relay di rumahmu bisa saling berbicara dan terhubung ke sistem rumah pintar seperti Home Assistant. MQTT adalah protokol pesan ringan yang dirancang untuk perangkat kecil: ESP32 menaruh suhu yang diukurnya ke sebuah topic seperti “ev/salon/sicaklik”, dan setiap program yang mendengarkan topic itu langsung menerima nilainya. Dengan cara yang sama, ketika kamu mengetuk tombol di aplikasi Home Assistant di ponselmu, perintah “ON” sampai ke ESP32 dalam waktu jauh di bawah satu detik dan menghidupkan relay. Berbeda dengan HTTP, MQTT tidak membuka koneksi baru untuk setiap request; ia bekerja lewat satu koneksi yang tetap terbuka dengan header sekecil dua byte, jadi cepat dan ringan bagi Wi-Fi maupun prosesor.

Di panduan ini kamu akan membuat node rumah pintar yang berfungsi dari nol. Pertama kamu akan mempelajari konsep MQTT: broker, topic, publish, dan subscribe, lalu menginstal broker Mosquitto di Home Assistant atau di Raspberry Pi. Berikutnya kamu akan memakai library PubSubClient untuk mengirim pembacaan suhu dan kelembapan DHT22 dari ESP32, mendengarkan perintah relay, dan menambahkan MQTT Discovery agar perangkat muncul sendiri di Home Assistant. Kita juga akan membahas QoS dan retain, pesan last will (LWT) yang menandai perangkat sebagai “unavailable” ketika koneksi putus, alternatif ESPHome yang mengerjakan hal yang sama tanpa satu baris C++ pun, perbedaan di ESP8266 dan Raspberry Pi Pico W, serta error yang paling umum satu per satu.

Board pengembangan ESP32 yang terhubung ke Home Assistant lewat MQTT
Berkat Wi-Fi bawaannya, ESP32 langsung terhubung ke broker MQTT di jaringan rumahmu; data sensor dan perintah relay mengalir lewat koneksi yang sama.

Apa itu MQTT dan bagaimana cara kerjanya?

MQTT (Message Queuing Telemetry Transport) memakai model publish/subscribe. Di tengahnya ada server yang disebut broker; ESP32, Home Assistant, ponselmu, atau program di komputermu terhubung ke broker sebagai klien. Klien tidak saling mengenal dan tidak tahu alamat IP satu sama lain: satu klien mem-publish pesan ke sebuah topic, dan broker meneruskannya ke semua yang subscribe ke topic itu. Bayangkan seperti kantor pos: ESP32 memasukkan surat ke kotak beralamat “ev/salon/sicaklik”, dan Home Assistant, yang mengawasi kotak itu, langsung menerimanya. Karena koneksi selalu dibuka oleh klien, ESP32 tidak butuh IP statis atau port yang terbuka di router-mu; yang perlu diketahuinya hanya alamat broker.

KonsepFungsinyaContoh
BrokerServer yang menerima pesan dan membagikannya ke para subscriberMosquitto, broker Mosquitto di Home Assistant
KlienPerangkat atau program apa pun yang terhubung ke broker; masing-masing punya client ID yang unikESP32, Home Assistant, MQTT Explorer
TopicAlamat sebuah pesan, terdiri dari level-level yang dipisahkan garis miringev/salon/sicaklik
PublishMengirim pesan ke sebuah topicMengirim nilai “23.4” ke ev/salon/sicaklik
SubscribeMendaftar untuk menerima pesan di sebuah topicESP32 mendengarkan ev/salon/role/komut
PayloadIsi sebuah pesan; teks, angka, atau JSONON, 23.4, {"sicaklik":23.4}
RetainBroker menyimpan pesan terakhir di sebuah topic dan langsung memberikannya ke subscriber baruStatus relay: ON
LWT (last will)Pesan yang di-publish broker atas nama klien jika klien itu terputus secara tak terdugaev/salon/baglanti: offline (status koneksi)
QoSTingkat jaminan pengiriman sebuah pesan (0, 1, atau 2)QoS 1 untuk perintah relay

Kenapa MQTT? Dibandingkan dengan web server, Blynk, dan Telegram

MetodeKelebihanKekuranganPaling cocok untuk
MQTT + Home AssistantLokal dan cepat, dua arah; ratusan perangkat dalam satu dasbor, otomatisasiKamu perlu menjalankan brokerMengelola seluruh rumah dari satu tempat
Web server ESP32Tanpa server tambahan, terbuka di browserSetiap perangkat punya halaman sendiri, tanpa otomatisasi antarperangkatPanel kendali untuk satu perangkat
Blynk IoTDasbor ponsel siap pakai, akses lewat internetBergantung pada cloud, ada batasan di paket gratisPrototipe mobile yang cepat
Bot TelegramNotifikasi instan gratis, tanpa port forwardingTanpa grafik atau dasborAlarm dan perintah sederhana
ESP-NOWBoard ESP saling berbicara tanpa router atau brokerHanya antar-board ESP, tidak langsung sampai ke Home AssistantMembawa data dari sensor berbaterai ke gateway

Singkatnya, MQTT makin unggul ketika jumlah perangkat bertambah: ketika kamu menambahkan sensor baru, kamu tidak menyentuh kode yang sudah ada, cukup mulai mem-publish ke topic baru. Kalau kamu ingin mengendalikan satu perangkat dari browser, panduan web server asinkron ESP32 dan WebSocket lebih cepat membawamu ke sana; untuk notifikasi ponsel lihat bot Telegram ESP32, dan untuk dasbor mobile siap pakai lihat Blynk IoT dengan ESP32. Untuk sensor taman yang di luar jangkauan router-mu, memakai ESP-NOW untuk membawa data ke ESP32 gateway yang terhubung ke MQTT adalah solusi yang bagus.

Struktur topic MQTT dan wildcard

Topic terlihat seperti path folder: “ev/salon/sicaklik” (bahasa Turki untuk rumah/ruang tamu/suhu) punya tiga level dan peka huruf besar-kecil, jadi “Ev/Salon” dan “ev/salon” adalah dua topic yang berbeda. Jangan diawali garis miring (“/ev/salon” membuat level pertama yang kosong), dan hindari spasi serta huruf beraksen; huruf biasa, angka, tanda hubung, dan garis bawah sudah cukup. Ketika subscribe, kamu bisa memakai dua wildcard: + menggantikan tepat satu level (“ev/+/sicaklik” mengembalikan suhu setiap ruangan), sedangkan # mencakup semua yang ada sesudahnya dan hanya boleh muncul di akhir (“ev/#” mengembalikan semua pesan di rumah). Wildcard hanya berlaku ketika subscribe; pesan selalu di-publish ke satu topic yang pasti. Topic yang diawali $ (seperti $SYS) dicadangkan untuk statistik broker sendiri dan tidak ikut tertangkap oleh subscription #. Untuk proyek di panduan ini kita akan memakai susunan berikut:

TopicDi-publish olehDidengarkan olehRetain
ev/salon/sicaklikESP32 (setiap 30 detik)Home AssistantYa
ev/salon/nemESP32 (setiap 30 detik)Home AssistantYa
ev/salon/role/komut (perintah relay)Home Assistant, ponsel, otomatisasiESP32Tidak
ev/salon/role/durum (status relay)ESP32 (setiap kali berubah)Home AssistantYa
ev/salon/baglantiESP32 (pesan online), broker (pesan offline)Home AssistantYa
homeassistant/statusHome Assistant (online ketika mulai)ESP32Tidak

Menginstal broker MQTT: Mosquitto

Broker MQTT gratis yang paling populer adalah Eclipse Mosquitto; bahkan di Raspberry Pi pun ia dengan mudah menangani ratusan pesan per detik. Ada tiga cara mudah untuk menginstalnya: aplikasi resmi Mosquitto broker kalau kamu memakai Home Assistant OS, paket apt di Raspberry Pi atau komputer Linux terpisah, atau installer Mosquitto di Windows. Apa pun pilihanmu, broker memakai port 1883 untuk MQTT tanpa enkripsi dan 8883 untuk MQTT terenkripsi TLS, dan broker hanya perlu berada di jaringan rumah yang sama dengan ESP32. Di Home Assistant, pemasangannya seperti ini:

  1. Di Home Assistant, buka Settings > Apps (di versi lama namanya Add-ons), klik Install app, lalu pilih Mosquitto broker dari daftar.
  2. Klik Install; setelah selesai, klik Start dan biarkan opsi mulai otomatis ketika booting tetap aktif.
  3. Buat pengguna terpisah untuk ESP32: di Settings > People > Users, tambahkan pengguna bernama “esp32” dengan kata sandi yang kuat. Kalau tab ini tidak terlihat, aktifkan Advanced mode di profilmu. Nama “homeassistant” dan “addons” dicadangkan untuk broker, jadi jangan dipakai.
  4. Di halaman Settings > Devices & services, integrasi MQTT biasanya muncul sebagai “Discovered”; klik Configure lalu konfirmasi. Kalau tidak muncul, pakai Add integration, cari MQTT, dan pilih opsi yang mengonfigurasi Mosquitto secara otomatis.
  5. Di kode ESP32 kamu akan memasukkan alamat IP Home Assistant sebagai alamat broker (misalnya 192.168.1.10), 1883 sebagai port, dan pengguna yang baru saja kamu buat.

Di mesin Linux seperti Raspberry Pi atau Ubuntu, pemasangannya hanya butuh beberapa perintah. Instal broker dan alat ujinya dengan sudo apt install mosquitto mosquitto-clients. Buat pengguna “esp32” dengan sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32 lalu ketik kata sandinya dua kali; opsi -c membuat file dari nol, jadi jangan dipakai ketika menambahkan pengguna kedua, kalau tidak pengguna yang sudah ada akan terhapus. Setelah itu buat file bernama local.conf di folder /etc/mosquitto/conf.d/, isi dengan tiga baris di bawah, lalu restart layanannya dengan sudo systemctl restart mosquitto. Di Windows, tambahkan baris yang sama ke file mosquitto.conf di folder instalasi Mosquitto, lalu restart layanan Mosquitto Broker.

BarisArtinya
listener 1883Mendengarkan di port 1883 pada semua antarmuka jaringan; tanpa baris ini, Mosquitto 2.x hanya menerima koneksi dari komputer yang sama
allow_anonymous falseMenolak koneksi tanpa nama pengguna dan kata sandi; di 2.x ini sudah bawaan, tapi menuliskannya secara eksplisit adalah kebiasaan yang baik
password_file /etc/mosquitto/passwd (file kata sandi)Memakai file kata sandi yang kamu buat dengan mosquitto_passwd; kata sandi disimpan di dalamnya dalam bentuk hash
Kalau tidak ada listener yang didefinisikan di konfigurasi, Mosquitto 2.0 ke atas hanya mendengarkan di 127.0.0.1 dan menulis peringatan “Starting in local only mode. Connections will only be possible from clients running on this machine.” ke log-nya. Dalam kondisi itu ESP32 tidak bisa terhubung dan kamu mendapat error rc=-2. Di sisi lain, jangan pernah membuka port 1883 ke internet di router-mu (tanpa port forwarding): lalu lintas MQTT tanpa enkripsi bisa dibaca di tengah jalan, dan relay di rumahmu bisa jatuh ke tangan orang lain. Kalau kamu butuh akses dari luar, pakai VPN atau opsi akses jarak jauh Home Assistant.

Sebelum beralih ke ESP32, uji broker dari komputermu; memisahkan masalah broker dari masalah kode sejak awal menghemat banyak waktu. Di satu terminal, mulai dengarkan semua topic di rumah dengan mosquitto_sub -h 192.168.1.10 -u esp32 -P yourpassword -t "ev/#" -v. Di terminal kedua, ketik mosquitto_pub -h 192.168.1.10 -u esp32 -P yourpassword -t ev/salon/test -m hello. Kalau baris “ev/salon/test hello” muncul di terminal pertama, broker berjalan dan kata sandinya benar. Opsi -v mencetak topic setiap pesan di depannya, dan opsi -r mengirim pesan sebagai retained.

Kalau kamu kurang suka command line, program gratis MQTT Explorer menampilkan setiap topic di broker sebagai pohon, lengkap dengan nilai terbaru dan flag retain. Di dalam Home Assistant kamu juga bisa membuka Settings > Devices & services > MQTT > Configure, mengetik ev/# di kotak “Listen to a topic” lalu mulai mendengarkan, dan memakai bagian “Publish a packet” untuk mengirim perintah ke ESP32 secara manual.

Daftar komponen dan diagram pengkabelan

Untuk proyek ini kamu butuh board pengembangan ESP32, sensor suhu dan kelembapan DHT22, modul relay yang bisa dipicu pada 3,3 V, breadboard, dan kabel jumper. DHT22 lebih presisi daripada DHT11: mengukur suhu sampai ±0,5 °C dan kelembapan kira-kira ±2–5%, serta bekerja dari -40 sampai 80 °C; keluarga sensor ini kami bahas detail di Sensor Suhu dan Kelembapan DHT11. Kalau kamu punya DHT11, cukup ganti DHT22 menjadi DHT11 di kode. Untuk tes koneksi pertama, ESP32 dan kabel USB sudah cukup; sensor dan relay bisa ditambahkan belakangan.

ESP32
ESP32
DHT22
DHT22
Modul relay
Modul relay
SambunganESP32ESP8266 (NodeMCU)Raspberry Pi Pico W
DHT22 VCC3V33V33V3(OUT)
DHT22 DATAGPIO 4D2 (GPIO 4)GP15
DHT22 GNDGNDGNDGND
VCC relayVIN (5V)VIN (5V)VBUS (5V)
IN relayGPIO 26D1 (GPIO 5)GP14
GND relayGNDGNDGND
Pin ESP32, ESP8266, dan Pico bekerja di 3,3 V dan tidak tahan 5 V, karena itulah DHT22 kita beri daya dari pin 3V3. Modul DHT22 tiga pin biasanya sudah punya resistor pull-up di board-nya; kalau kamu memakai sensor polos empat pin, tambahkan resistor 4,7–10 kΩ di antara DATA dan VCC. Kalau kamu akan menghidupmatikan beban listrik PLN 230 V (220 V di Indonesia) dengan relay, kerjakan semua pengkabelan dengan steker dicabut dan minta bantuan orang dewasa; detailnya ada di Apa Itu Modul Relay?. Kamu bisa melihat setiap pin board-mu di alat Pinout.

Menginstal PubSubClient di Arduino IDE

  1. Kalau paket board ESP32 belum terinstal di Arduino IDE, instal dulu; langkah-langkahnya ada di Apa Itu ESP32?.
  2. Buka Tools > Manage Libraries, ketik PubSubClient di kotak pencarian, lalu instal library buatan Nick O'Leary. Kode di panduan ini dikompilasi dengan versi 2.8.
  3. Di jendela yang sama, cari DHT sensor library dan instal library Adafruit; ketika ditanya soal dependensi, pilih Install all agar Adafruit Unified Sensor ikut terinstal.
  4. Kalau kamu mengalami masalah ketika menginstal library, lihat panduan Cara Instal Library Arduino.

Tes pertama: menghubungkan ESP32 ke broker MQTT

Sebelum menambahkan sensor, mari pastikan dengan kode yang paling sederhana bahwa data Wi-Fi, alamat broker, dan kata sandinya benar. Kode di bawah terhubung ke broker, mem-publish “merhaba” (bahasa Turki untuk “halo”) ke topic “test/esp32/durum”, dan mencetak setiap pesan yang datang di “test/esp32/komut” ke Serial Monitor. Ganti nama Wi-Fi, kata sandi, IP broker, dan pengguna MQTT dengan milikmu, upload kodenya, lalu buka Serial Monitor di 115200 baud:

C++ (Arduino IDE)
1#include <WiFi.h>
2#include <PubSubClient.h>
3
4const char* WIFI_SSID = "AgAdi";              // Wi-Fi adın (yalnız 2,4 GHz) / your Wi-Fi name (2.4 GHz only)
5const char* WIFI_PASS = "Sifre123";           // Wi-Fi şifren / your Wi-Fi password
6const char* MQTT_SUNUCU = "192.168.1.10";     // broker'ın IP adresi / broker IP address
7const int   MQTT_PORT = 1883;                 // şifresiz MQTT portu / unencrypted MQTT port
8const char* MQTT_KULLANICI = "esp32";         // broker kullanıcı adı / broker username
9const char* MQTT_SIFRE = "mqttSifre";         // broker şifresi / broker password
10
11WiFiClient wifiIstemci;                       // TCP bağlantısı / TCP connection
12PubSubClient mqtt(wifiIstemci);               // MQTT istemcisi / MQTT client
13
14// Abone olunan konuya mesaj gelince çalışır / runs when a subscribed topic receives a message
15void mesajGeldi(char* topic, byte* payload, unsigned int length) {
16  Serial.print("Mesaj [");
17  Serial.print(topic);
18  Serial.print("] ");
19  for (unsigned int i = 0; i < length; i++) {
20    Serial.print((char)payload[i]);           // payload sonunda \0 yoktur / payload is not null-terminated
21  }
22  Serial.println();
23}
24
25void setup() {
26  Serial.begin(115200);
27  WiFi.mode(WIFI_STA);
28  WiFi.begin(WIFI_SSID, WIFI_PASS);
29  while (WiFi.status() != WL_CONNECTED) {
30    delay(500);
31    Serial.print(".");
32  }
33  Serial.print("\nIP: ");
34  Serial.println(WiFi.localIP());
35
36  mqtt.setServer(MQTT_SUNUCU, MQTT_PORT);     // broker adresi / broker address
37  mqtt.setCallback(mesajGeldi);               // gelen mesaj fonksiyonu / incoming message handler
38}
39
40void loop() {
41  if (!mqtt.connected()) {
42    Serial.print("MQTT baglaniyor... ");
43    if (mqtt.connect("esp32-test", MQTT_KULLANICI, MQTT_SIFRE)) {   // istemci kimliği benzersiz olmalı / client ID must be unique
44      Serial.println("baglandi");
45      mqtt.subscribe("test/esp32/komut");                  // bu konuyu dinle / listen to this topic
46      mqtt.publish("test/esp32/durum", "merhaba");         // ilk mesaj / first message
47    } else {
48      Serial.print("hata, rc=");
49      Serial.println(mqtt.state());                        // hata kodu / error code
50      delay(5000);
51      return;
52    }
53  }
54  mqtt.loop();                                             // mesajları işle, bağlantıyı canlı tut / process messages, keep the connection alive
55}

Begitu kamu melihat “baglandi” (“terhubung”) di Serial Monitor, kirim mosquitto_pub -h 192.168.1.10 -u esp32 -P yourpassword -t test/esp32/komut -m hi dari terminal di komputermu; dalam beberapa milidetik baris “Mesaj [test/esp32/komut] hi” (Mesaj = “pesan”) muncul di Serial Monitor. Kalau koneksinya gagal, kode mencetak kode error dengan mqtt.state() dan mencoba lagi setelah 5 detik. Kode-kode ini memberi tahu dengan tepat di mana masalahnya:

rcNama di PubSubClientArti dan solusi
-4MQTT_CONNECTION_TIMEOUTBroker tidak menjawab tepat waktu; jaringan lemah atau broker kelebihan beban
-3MQTT_CONNECTION_LOSTKoneksi yang sudah terjalin putus; biasanya karena loop() lama tidak dipanggil atau Wi-Fi hilang
-2MQTT_CONNECT_FAILEDKoneksi TCP tidak pernah terbuka: IP atau port salah, broker tidak berjalan, Mosquitto dalam mode local-only, atau firewall memblokir 1883
-1MQTT_DISCONNECTEDKoneksi ditutup dengan rapi (disconnect dipanggil) atau memang belum pernah terhubung
2MQTT_CONNECT_BAD_CLIENT_IDClient ID ditolak; yang dipakai client ID kosong atau tidak valid
4MQTT_CONNECT_BAD_CREDENTIALSNama pengguna atau kata sandi salah (beberapa broker mengembalikan kode ini)
5MQTT_CONNECT_UNAUTHORIZEDTidak diizinkan; Mosquitto mengembalikan kode ini baik untuk kata sandi yang salah maupun untuk upaya terhubung tanpa kredensial

Mengirim data sensor dan mendengarkan perintah relay dengan ESP32

Sekarang mari buat proyek yang sebenarnya. Kode di bawah membaca DHT22 setiap 30 detik dan mem-publish suhu dan kelembapan dengan flag retain, mengendalikan relay dengan perintah ON, OFF, dan TOGGLE yang datang di “ev/salon/role/komut”, lalu melaporkan status baru relay ke “ev/salon/role/durum”. Ketika terhubung, kode menitipkan last will ke broker, memperkenalkan diri ke Home Assistant lewat MQTT Discovery, dan kalau koneksi putus, mencoba lagi setiap 5 detik tanpa memblokir loop(). Berkat blok #if defined(ESP8266) di bagian atas, kode yang sama juga bisa dikompilasi di NodeMCU tanpa perubahan apa pun.

C++ (Arduino IDE)
1#if defined(ESP8266)
2#include <ESP8266WiFi.h>
3#else
4#include <WiFi.h>
5#endif
6#include <PubSubClient.h>
7#include <DHT.h>
8
9// ---- Ayarlar / Settings ----
10const char* WIFI_SSID = "AgAdi";
11const char* WIFI_PASS = "Sifre123";
12const char* MQTT_SUNUCU = "192.168.1.10";        // broker IP (Home Assistant ya da Raspberry Pi) / broker IP (Home Assistant or Raspberry Pi)
13const int   MQTT_PORT = 1883;
14const char* MQTT_KULLANICI = "esp32";
15const char* MQTT_SIFRE = "mqttSifre";
16const char* ISTEMCI_ID = "esp32-salon";          // her cihazda farklı olmalı / must be different on every device
17
18#if defined(ESP8266)
19const int DHT_PIN = 4;                           // NodeMCU D2
20const int ROLE_PIN = 5;                          // NodeMCU D1
21#else
22const int DHT_PIN = 4;                           // ESP32 GPIO 4
23const int ROLE_PIN = 26;                         // ESP32 GPIO 26
24#endif
25const bool ROLE_AKTIF_LOW = true;                // çoğu röle modülü LOW ile çeker / most relay modules switch on LOW
26const unsigned long OLCUM_ARALIGI = 30000;       // 30 saniyede bir ölçüm / one reading every 30 s
27
28// ---- Konular (topic) / Topics ----
29const char* T_SICAKLIK = "ev/salon/sicaklik";
30const char* T_NEM      = "ev/salon/nem";
31const char* T_KOMUT    = "ev/salon/role/komut";  // ON, OFF ya da TOGGLE / ON, OFF or TOGGLE
32const char* T_DURUM    = "ev/salon/role/durum";
33const char* T_BAGLANTI = "ev/salon/baglanti";    // online / offline (son vasiyet / last will)
34const char* T_HA_DURUM = "homeassistant/status"; // HA açılınca "online" yayınlar / HA publishes "online" when it starts
35
36WiFiClient wifiIstemci;
37PubSubClient mqtt(wifiIstemci);
38DHT dht(DHT_PIN, DHT22);
39
40bool roleAcik = false;
41unsigned long sonOlcum = 0;
42unsigned long sonDeneme = 0;
43
44// Röleyi sür ve yeni durumu kalıcı (retain) yayınla / drive the relay and publish the new state as retained
45void roleAyarla(bool acik) {
46  roleAcik = acik;
47  bool seviye = ROLE_AKTIF_LOW ? !acik : acik;
48  digitalWrite(ROLE_PIN, seviye ? HIGH : LOW);
49  mqtt.publish(T_DURUM, acik ? "ON" : "OFF", true);
50  Serial.println(acik ? "Role: ON" : "Role: OFF");
51}
52
53// Tek bir Home Assistant keşif mesajı gönder / send one Home Assistant discovery message
54void kesifYayinla(const char* tur, const char* nesne, const char* ad, const char* ekAlanlar) {
55  char konu[96];
56  snprintf(konu, sizeof(konu), "homeassistant/%s/%s/%s/config", tur, ISTEMCI_ID, nesne);
57  char json[600];
58  snprintf(json, sizeof(json),
59           "{\"name\":\"%s\",\"unique_id\":\"%s_%s\",%s,\"availability_topic\":\"%s\","
60           "\"device\":{\"identifiers\":[\"%s\"],\"name\":\"Salon ESP32\",\"model\":\"ESP32 + DHT22\"}}",
61           ad, ISTEMCI_ID, nesne, ekAlanlar, T_BAGLANTI, ISTEMCI_ID);
62  if (!mqtt.publish(konu, json, true)) {         // false: tampon küçük ya da bağlantı yok / false: buffer too small or not connected
63    Serial.println("Kesif mesaji gonderilemedi");
64  }
65}
66
67// Sıcaklık, nem ve röleyi Home Assistant'a tanıt / announce temperature, humidity and relay to Home Assistant
68void haKesifGonder() {
69  char ek[200];
70  snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"device_class\":\"temperature\",\"unit_of_measurement\":\"°C\",\"state_class\":\"measurement\"", T_SICAKLIK);
71  kesifYayinla("sensor", "sicaklik", "Sıcaklık", ek);
72  snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"device_class\":\"humidity\",\"unit_of_measurement\":\"%%\",\"state_class\":\"measurement\"", T_NEM);
73  kesifYayinla("sensor", "nem", "Nem", ek);
74  snprintf(ek, sizeof(ek), "\"state_topic\":\"%s\",\"command_topic\":\"%s\"", T_DURUM, T_KOMUT);
75  kesifYayinla("switch", "role", "Röle", ek);
76}
77
78// DHT22'yi oku ve değerleri yayınla / read the DHT22 and publish the values
79void olcumGonder() {
80  float t = dht.readTemperature();
81  float h = dht.readHumidity();
82  if (isnan(t) || isnan(h)) {
83    Serial.println("DHT22 okunamadi");
84    return;
85  }
86  char deger[12];
87  snprintf(deger, sizeof(deger), "%.1f", t);     // 23.4 gibi / like 23.4
88  mqtt.publish(T_SICAKLIK, deger, true);
89  snprintf(deger, sizeof(deger), "%.0f", h);     // 45 gibi / like 45
90  mqtt.publish(T_NEM, deger, true);
91  Serial.printf("Sicaklik %.1f C, nem %.0f %%\n", t, h);
92}
93
94// Abone olunan konulara mesaj gelince çalışır / runs when a subscribed topic receives a message
95void mesajGeldi(char* topic, byte* payload, unsigned int length) {
96  // Önce kopyala: yayın yapınca kütüphane aynı tamponu kullanır / copy first: publishing reuses the same buffer
97  String konu = topic;
98  String mesaj;
99  for (unsigned int i = 0; i < length; i++) mesaj += (char)payload[i];
100  mesaj.trim();
101
102  if (konu == T_KOMUT) {
103    if (mesaj == "ON") roleAyarla(true);
104    else if (mesaj == "OFF") roleAyarla(false);
105    else if (mesaj == "TOGGLE") roleAyarla(!roleAcik);
106  } else if (konu == T_HA_DURUM && mesaj == "online") {
107    haKesifGonder();                             // HA yeniden başladı, tanıtımı yenile / HA restarted, announce again
108    mqtt.publish(T_DURUM, roleAcik ? "ON" : "OFF", true);
109  }
110}
111
112bool mqttBaglan() {
113  Serial.print("MQTT baglaniyor... ");
114  // Bağlantı koparsa broker T_BAGLANTI'ya "offline" yazar / if we drop, the broker publishes "offline" to T_BAGLANTI
115  if (!mqtt.connect(ISTEMCI_ID, MQTT_KULLANICI, MQTT_SIFRE, T_BAGLANTI, 1, true, "offline")) {
116    Serial.print("hata, rc=");
117    Serial.println(mqtt.state());
118    return false;
119  }
120  Serial.println("baglandi");
121  mqtt.publish(T_BAGLANTI, "online", true);
122  mqtt.subscribe(T_KOMUT, 1);                    // komutları QoS 1 ile dinle / listen to commands with QoS 1
123  mqtt.subscribe(T_HA_DURUM);
124  haKesifGonder();
125  mqtt.publish(T_DURUM, roleAcik ? "ON" : "OFF", true);
126  return true;
127}
128
129void setup() {
130  Serial.begin(115200);
131  pinMode(ROLE_PIN, OUTPUT);
132  roleAyarla(false);                             // güvenli başlangıç: röle kapalı / safe start: relay off
133  dht.begin();
134
135  WiFi.mode(WIFI_STA);
136  WiFi.begin(WIFI_SSID, WIFI_PASS);
137  Serial.print("Wi-Fi");
138  while (WiFi.status() != WL_CONNECTED) {
139    delay(500);
140    Serial.print(".");
141  }
142  Serial.print(" IP: ");
143  Serial.println(WiFi.localIP());
144
145  mqtt.setServer(MQTT_SUNUCU, MQTT_PORT);
146  mqtt.setCallback(mesajGeldi);
147  mqtt.setBufferSize(1024);                      // keşif JSON'u varsayılan 256 bayta sığmaz / discovery JSON doesn't fit the default 256 bytes
148}
149
150void loop() {
151  if (!mqtt.connected()) {
152    unsigned long simdi = millis();
153    if (sonDeneme == 0 || simdi - sonDeneme >= 5000) {   // 5 sn'de bir dene, loop'u kilitleme / retry every 5 s without blocking
154      sonDeneme = simdi;
155      if (mqttBaglan()) sonOlcum = simdi - OLCUM_ARALIGI;  // bağlanınca hemen ölç / measure right after connecting
156    }
157    return;
158  }
159  mqtt.loop();                                   // gelen komutlar ve keep-alive / incoming commands and keep-alive
160
161  if (millis() - sonOlcum >= OLCUM_ARALIGI) {
162    sonOlcum = millis();
163    olcumGonder();
164  }
165}
BarisFungsinya
mqtt.connect(ISTEMCI_ID, ..., T_BAGLANTI, 1, true, "offline") (terhubung dengan last will)Mendaftarkan last will sambil terhubung: kalau ESP32 terputus secara tak terduga, broker menulis “offline” yang retained ke ev/salon/baglanti
mqtt.publish(T_BAGLANTI, "online", true) (status online)Mengatur status menjadi “online” tepat setelah terhubung; Home Assistant menampilkan perangkat sebagai tersedia lagi
mqtt.subscribe(T_KOMUT, 1)Mendengarkan perintah relay dengan QoS 1; PubSubClient hanya mendukung QoS 0 dan 1 untuk subscription
mqtt.setBufferSize(1024)Memperbesar buffer paket dari bawaan 256 byte; paket discovery terbesar sekitar 355 byte
mqtt.loop()Membaca pesan yang masuk dan mengirim paket keep-alive (PINGREQ); harus dipanggil di setiap putaran loop
ROLE_AKTIF_LOWKebanyakan modul relay menyala dengan sinyal LOW; atur ke false kalau relay-mu menyala dengan HIGH
OLCUM_ARALIGISeberapa sering mengukur (interval pengukuran); DHT22 paling cepat bisa dibaca setiap 2 detik, dan 30–60 detik ideal untuk suhu ruangan

Beberapa detail di kode ini sengaja dibuat begitu. Fungsi mesajGeldi() (“pesan datang”) menyalin topic dan payload ke String terlebih dulu, karena PubSubClient memakai satu buffer untuk pesan masuk sekaligus keluar: begitu kamu memanggil publish() di dalam callback, data yang ditunjuk pointer topic dan payload tertimpa. Payload juga tidak punya penutup \0 seperti string C, jadi kita membaca tepat sebanyak length karakter. Kita memakai retain untuk pembacaan sensor dan status relay agar Home Assistant langsung melihat nilai terakhir setelah restart, bukan menunggu 30 detik. Pengaturan waktu juga memakai millis(): delay() yang panjang di dalam loop() akan menahan paket keep-alive dan broker akan memutus koneksi. Teknik ini kami jelaskan detail di Arduino millis() vs delay().

Jangan pernah mengirim pesan ke topic perintah dengan flag retain. Kalau “ON” yang retained tertinggal di “ev/salon/role/komut”, ESP32 menerima perintah lama itu setiap kali terhubung lagi setelah listrik padam atau Wi-Fi putus, lalu menghidupkan relay sendiri di tengah malam. Kalau kamu tidak sengaja mengirim perintah yang retained, hapus dengan mem-publish pesan retained kosong lewat mosquitto_pub -r -n -t ev/salon/role/komut. Switch MQTT di Home Assistant secara bawaan mengirim perintah tanpa retain.

Tampilannya di Home Assistant: MQTT Discovery

Home Assistant terus-menerus mendengarkan topic yang diawali prefiks homeassistant/. Ketika sebuah perangkat mem-publish konfigurasi JSON ke topic berbentuk homeassistant/[component]/[node]/[object]/config, Home Assistant membuat entity itu secara otomatis; inilah yang disebut MQTT Discovery. Kode kita mengirim tiga pesan: dua untuk sensor (suhu dan kelembapan) di bawah homeassistant/sensor/esp32-salon/... dan satu untuk relay di homeassistant/switch/esp32-salon/role/config. Karena retained, pesan-pesan ini tetap ada setelah Home Assistant restart. Kode juga subscribe ke homeassistant/status: Home Assistant menulis “online” di sana ketika mulai, dan ESP32 mengumumkan dirinya lagi. Kalau perangkatmu banyak, dokumentasi Home Assistant menyarankan menambahkan jeda acak yang kecil sebelum pengumuman ulang ini.

Field JSONArtinyaNilai kita
nameNama tampilan entity; nama perangkat ditambahkan di depannyaSıcaklık (tampil sebagai Salon ESP32 Sıcaklık; bahasa Turki untuk “suhu”)
unique_idID permanen entity; tanpanya, nama dan area entity tidak bisa diedit di antarmukaesp32-salon_sicaklik
state_topicTopic tempat nilai dibacaev/salon/sicaklik
command_topicTopic tujuan perintah switchev/salon/role/komut (perintah relay)
device_classMenentukan ikon, pilihan satuan, dan jenis grafiktemperature, humidity
unit_of_measurementSatuan ukur°C dan %
state_classNilai measurement mengaktifkan statistik jangka panjang dan grafikmeasurement
availability_topicTopic tempat status online/offline dibaca; payload bawaannya online dan offlineev/salon/baglanti
deviceMengelompokkan entity ke dalam satu kartu perangkatidentifiers, name, model (ID, nama, model)

Beberapa detik setelah kode di-upload, perangkat bernama “Salon ESP32” muncul di Settings > Devices & services > MQTT. Kartu perangkatnya berisi sensor suhu dan kelembapan serta satu switch relay; klik suhu untuk membuka grafik riwayatnya, balik switch-nya, dan relay pun berbunyi klik. Kamu bisa menambahkan entity ini ke dasbor, membukanya untuk asisten suara, atau memakainya di otomatisasi: misalnya, aturan seperti “kalau ruang tamu di atas 27 °C, nyalakan relay tempat kipas dicolokkan, dan matikan di bawah 25 °C” hanya butuh beberapa klik. Kalau kamu mencabut ESP32, entity berubah menjadi “Unavailable” paling lama sekitar 22 detik kemudian, tanda bahwa pesan last will bekerja. Kalau kamu tidak ingin memakai discovery, kamu juga bisa mendefinisikan entity yang sama secara manual di configuration.yaml sebagai entri sensor dan switch di bawah mqtt:.

Kalau kamu mengganti nama atau topic perangkat dan entity lama tertinggal di Home Assistant, kirim pesan retained kosong ke topic config yang sesuai: mosquitto_pub -r -n -t homeassistant/sensor/esp32-salon/sicaklik/config. Home Assistant menghapus entity itu, dan juga menghapus perangkatnya kalau tidak ada entity lain yang terpasang. Ketika kamu memberi setiap ESP32 ISTEMCI_ID (client ID) yang berbeda, nilai unique_id otomatis ikut berbeda, jadi kamu bisa menambahkan beberapa ruangan tanpa tertukar.

QoS dan retain: pakai yang mana, dan kapan?

QoS (Quality of Service) menentukan seberapa yakin kamu ingin sebuah pesan sampai ke pihak lain. Satu detail penting: QoS berlaku terpisah di dua ruas. Antara publisher dan broker berlaku QoS publisher, dan antara broker dan subscriber berlaku QoS subscription; jaminan yang didapat subscriber adalah yang lebih rendah dari keduanya. PubSubClient hanya mendukung QoS 0 untuk publish dan QoS 0 serta 1 untuk subscription. Di Wi-Fi rumah, pesan yang hilang dengan QoS 0 sangat jarang, tapi menjadikan subscription perintah QoS 1 tetap asuransi yang murah.

QoSJaminanCara kerjanyaKapan dipakai
0Paling banyak sekaliPesan dikirim sekali tanpa konfirmasi; bisa hilang kalau koneksi putus pada momen ituPembacaan sensor yang sering
1Paling sedikit sekaliPenerima mengonfirmasi dengan PUBACK, dan pesan dikirim ulang kalau konfirmasi tidak datang; pesan bisa sampai dua kaliPerintah relay, alarm
2Tepat sekaliJabat tangan (handshake) empat langkah dengan PUBREC, PUBREL, dan PUBCOMP; level paling lambatHal seperti penghitung, di mana duplikat merugikan; tidak didukung PubSubClient

Flag retain lebih soal ingatan daripada pengiriman: broker hanya menyimpan pesan retained terakhir dari setiap topic dan langsung mengirimkannya ke siapa pun yang subscribe. Flag ini ideal untuk pesan “status terkini” seperti nilai sensor, status relay, dan status online, tapi berbahaya untuk perintah dan kejadian sekali jalan. Last will (LWT) melengkapinya: kalau broker tidak menerima paket apa pun dari sebuah klien selama 1,5 kali periode keep-alive, broker memutuskan koneksi itu hilang dan mem-publish pesan will. Keep-alive bawaan PubSubClient adalah 15 detik, jadi ESP32 yang dicabut tampil sebagai “offline” paling lama sekitar 22 detik kemudian. Kamu bisa mengubahnya dengan baris seperti mqtt.setKeepAlive(30), tapi makin panjang nilainya, makin terlambat kamu menyadari koneksi yang putus.

Alternatif tanpa kode: ESPHome

ESPHome adalah alat gratis yang mengubah perangkat yang kamu deskripsikan di file YAML menjadi firmware ESP32 yang siap di-flash; kamu tidak menulis satu baris C++ pun. Di Home Assistant, instal ESPHome Device Builder dari Settings > Apps, buka antarmukanya, lalu buat konfigurasi dengan wizard New device. Upload pertama dilakukan sekali lewat USB: Chrome atau Edge bisa langsung memprogram board, dan kalau itu tidak berhasil, kamu bisa mem-flash file yang diunduh wizard dengan halaman ESPHome Web. Semua pembaruan berikutnya lewat Wi-Fi (OTA). Konfigurasi di bawah sama dengan proyek Arduino di atas: membaca DHT22 di GPIO 4 setiap 30 detik dan menampilkan relay aktif LOW di GPIO 26 sebagai switch. Data Wi-Fi dan kata sandi dibaca dari file secrets.yaml terpisah dengan !secret:

Kode
1esphome:
2  name: salon-sensor               # küçük harf, rakam ve tire / lowercase, digits and hyphens
3  friendly_name: Salon Sensör
4
5esp32:
6  board: esp32dev
7
8logger:
9
10api:                               # Home Assistant ile doğrudan bağlantı / direct link to Home Assistant
11  encryption:
12    key: !secret api_anahtari
13
14ota:
15  - platform: esphome
16    password: !secret ota_sifresi
17
18wifi:
19  ssid: !secret wifi_ssid
20  password: !secret wifi_sifresi
21  ap:                              # Wi-Fi yoksa kendi ağını açar / opens its own network if Wi-Fi fails
22    ssid: "Salon-Sensor"
23    password: "yedek1234"
24
25captive_portal:
26
27sensor:
28  - platform: dht
29    pin: GPIO4
30    model: DHT22
31    update_interval: 30s
32    temperature:
33      name: "Sıcaklık"
34    humidity:
35      name: "Nem"
36
37switch:
38  - platform: gpio
39    name: "Röle"
40    pin:
41      number: GPIO26
42      inverted: true               # aktif LOW röle / active-LOW relay
43    restore_mode: ALWAYS_OFF       # açılışta kapalı / off at boot
44
45# MQTT ile kullanmak için api: bloğunu sil, bunu aç / to use MQTT, delete api: and uncomment this
46# mqtt:
47#   broker: 192.168.1.10
48#   username: esp32
49#   password: !secret mqtt_sifresi

Ada satu perbedaan yang perlu diingat: secara bawaan ESPHome tidak memakai MQTT, melainkan native API terenkripsinya sendiri. Home Assistant menemukan perangkat itu di jaringan dengan sendirinya dan sama sekali tidak butuh broker. Pilih MQTT hanya kalau kamu ingin sistem lain seperti Node-RED membaca data yang sama, atau kalau kamu tidak memakai Home Assistant. Untuk itu, hapus tanda komentar di baris mqtt: di akhir file dan hapus blok api:; kalau tidak, perangkat akan me-reboot dirinya sendiri setiap kali tidak ada yang terhubung ke native API selama 15 menit (itulah pengaturan reboot_timeout). Dalam mode MQTT, ESPHome mengirim pesan discovery Home Assistant dan pesan online/offline di salon-sensor/status sendiri, jadi semua yang kita kerjakan manual di kode Arduino dilakukannya secara otomatis.

FiturPubSubClient (kode Arduino)ESPHome (YAML)
Menulis kodeKamu menulis semuanya dalam C++Hanya YAML; firmware dikompilasi otomatis
Menambahkan ke Home AssistantKamu mengirim JSON discovery sendiriDitemukan otomatis
FleksibilitasTanpa batas; library dan logika apa pun bisa dipakaiTerbatas pada komponen siap pakai, tapi ratusan sensor didukung; C++ bisa ditambahkan dengan lambda
Pembaruan lewat udara (OTA)Kamu menambahkan ArduinoOTA ke kode sendiriSudah bawaan
Butuh brokerYaTidak, dengan native API
Nilai belajarMengajarkan protokol MQTT dan pemrogramanHasil cepat, menyembunyikan apa yang terjadi di baliknya

MQTT dengan ESP8266 dan Raspberry Pi Pico W

Kode lengkap di atas berjalan tanpa perubahan di board ESP8266 NodeMCU dan Wemos D1 Mini: ketika kamu memilih NodeMCU 1.0 di Tools > Board, blok #if defined(ESP8266) otomatis memilih ESP8266WiFi.h alih-alih WiFi.h, beserta pin D2 dan D1. Di sisi Raspberry Pi Pico W kita memakai modul umqtt.simple dari MicroPython. Modul ini tidak termasuk dalam firmware MicroPython Pico W; instal di Thonny dengan mencari umqtt.simple di Tools > Manage packages, atau ketik import mip; mip.install("umqtt.simple") di REPL ketika sudah terhubung ke Wi-Fi. Sebaliknya, modul dht yang dibutuhkan untuk DHT22 sudah ikut di firmware. Kode di bawah membuat Pico W di dapur mengerjakan tugas pengukuran dan relay yang sama. Agar ringkas, pesan discovery kami tinggalkan; untuk melihat Pico W di Home Assistant, publish JSON discovery yang sama seperti di kode ESP32 dengan topic ev/mutfak (mutfak = “dapur”), atau definisikan entity secara manual di bawah mqtt: di configuration.yaml. Simpan file sebagai main.py dan kode akan berjalan setiap kali board dinyalakan:

MicroPython
1import network, time, dht
2from machine import Pin
3from umqtt.simple import MQTTClient    # önce mip ile kur / install with mip first
4
5WIFI_SSID = "AgAdi"                    # Wi-Fi adın / your Wi-Fi name
6WIFI_PASS = "Sifre123"                 # Wi-Fi şifren / your Wi-Fi password
7MQTT_SUNUCU = "192.168.1.10"           # broker IP / broker IP
8ISTEMCI_ID = "pico-mutfak"             # benzersiz olmalı / must be unique
9
10T_SICAKLIK = b"ev/mutfak/sicaklik"
11T_NEM = b"ev/mutfak/nem"
12T_KOMUT = b"ev/mutfak/role/komut"
13T_DURUM = b"ev/mutfak/role/durum"
14T_BAGLANTI = b"ev/mutfak/baglanti"
15
16sensor = dht.DHT22(Pin(15))            # DHT22 DATA -> GP15
17role = Pin(14, Pin.OUT, value=1)       # aktif LOW röle kapalı başlar / active-LOW relay starts off
18led = Pin("LED", Pin.OUT)              # Pico W dahili LED / Pico W onboard LED
19
20wlan = network.WLAN(network.STA_IF)
21wlan.active(True)
22wlan.connect(WIFI_SSID, WIFI_PASS)
23while not wlan.isconnected():
24    time.sleep(0.5)
25print("IP:", wlan.ifconfig()[0])
26
27def mesaj_geldi(konu, mesaj):          # ikisi de bytes gelir / both arrive as bytes
28    if konu == T_KOMUT and mesaj in (b"ON", b"OFF"):
29        acik = mesaj == b"ON"
30        role.value(0 if acik else 1)
31        led.value(1 if acik else 0)
32        istemci.publish(T_DURUM, mesaj, retain=True)
33
34istemci = MQTTClient(ISTEMCI_ID, MQTT_SUNUCU, user="esp32", password="mqttSifre", keepalive=60)   # Mosquitto kullanıcısı / Mosquitto user
35istemci.set_callback(mesaj_geldi)
36istemci.set_last_will(T_BAGLANTI, b"offline", retain=True)   # son vasiyet / last will
37
38def baglan():
39    while True:
40        try:
41            if not wlan.isconnected():         # Wi-Fi koptuysa yeniden bağlan / reconnect Wi-Fi if it dropped
42                wlan.connect(WIFI_SSID, WIFI_PASS)
43                time.sleep(5)
44            istemci.connect()
45            istemci.publish(T_BAGLANTI, b"online", retain=True)
46            istemci.publish(T_DURUM, b"OFF" if role.value() else b"ON", retain=True)
47            istemci.subscribe(T_KOMUT)
48            print("MQTT baglandi")
49            return
50        except Exception as e:         # MQTTException(5): yetki yok / not authorized
51            print("MQTT hatasi:", e)
52            time.sleep(5)
53
54baglan()
55son = time.ticks_add(time.ticks_ms(), -30000)   # ilk ölçüm hemen / first reading right away
56while True:
57    try:
58        istemci.check_msg()            # bekleyen komut var mı? / any pending command?
59        if time.ticks_diff(time.ticks_ms(), son) >= 30000:
60            son = time.ticks_ms()
61            try:
62                sensor.measure()
63            except OSError:
64                print("DHT22 okunamadi")
65                istemci.ping()         # veri yoksa da bağlantıyı canlı tut / keep the link alive without data
66            else:
67                istemci.publish(T_SICAKLIK, "{:.1f}".format(sensor.temperature()).encode(), retain=True)
68                istemci.publish(T_NEM, "{:.0f}".format(sensor.humidity()).encode(), retain=True)
69    except OSError:
70        print("Baglanti koptu, yeniden baglaniliyor")
71        time.sleep(5)
72        baglan()
73    time.sleep_ms(100)

Ide proyek MQTT ESP32

  • Peta suhu per ruangan: Pasang ESP32 dengan DHT22 atau BME280 di setiap ruangan dan pantau seluruh rumah dalam satu grafik dengan subscription ev/+/sicaklik.
  • Lampu dan stopkontak pintar: Hubungkan relay ke otomatisasi Home Assistant yang menyalakannya ketika matahari terbenam dan mematikannya tengah malam.
  • Sensor pintu dan jendela: Pakai reed switch untuk mengirim pesan MQTT ketika pintu terbuka dan terima notifikasi di ponsel ketika tidak ada orang di rumah.
  • Lampu lorong yang menyala karena gerakan: Biarkan sensor PIR mem-publish gerakan dan otomatisasi Home Assistant menyalakan lampunya.
  • Stasiun penyiram tanaman: Publish nilai sensor kelembapan tanah dan jalankan pompa dengan perintah MQTT ketika tanahnya kering.
  • Pemantauan energi: Ukur arus yang ditarik sebuah alat dengan sensor arus ACS712 dan buat grafik konsumsi hariannya.
  • Sensor bertenaga baterai: Buat node yang mengambil pembacaan, mengirimnya lewat MQTT, lalu tidur lagi; detailnya di Deep Sleep ESP32.

Error MQTT ESP32 yang umum dan solusinya

Gejala atau pesanPenyebabSolusi
rc=-2 terus-menerusIP atau port broker salah, broker tidak berjalan, atau Mosquitto dalam mode local-onlyCek IP, tambahkan listener 1883 ke konfigurasi, izinkan port 1883 di firewall
rc=5Nama pengguna atau kata sandi salah, atau upaya terhubung tanpa kredensialUji kata sandi dari komputermu dengan mosquitto_sub; buat ulang penggunanya kalau perlu
Terhubung, putus setelah beberapa detik, terus berulangDua perangkat memakai client ID yang sama; Mosquitto mencatat “Client esp32-salon already connected, closing old connection.”Beri setiap perangkat ISTEMCI_ID yang unik
Pesan discovery tidak sampai, publish() mengembalikan falseBuffer PubSubClient secara bawaan 256 byte dan JSON-nya tidak muatPanggil mqtt.setBufferSize(1024) di setup()
rc=-3 sering munculdelay() yang panjang di dalam loop() menghentikan paket keep-alive, atau sinyal Wi-Fi lemahAtur waktu dengan millis() dan dekatkan board ke router
Perintah tidak pernah sampai ke ESP32Nama topic berbeda huruf besar-kecil atau ejaannya, atau subscribe() tidak diulang setelah terhubung lagiCek topic dengan mosquitto_sub; taruh baris subscribe() di dalam fungsi koneksi
Relay menyala sendiri ketika mulaiAda pesan retained lama yang tertinggal di topic perintahHapus dengan mosquitto_pub -r -n -t ev/salon/role/komut
Entity menampilkan “Unavailable” di Home AssistantTopic availability berisi offline, atau online ditulis dengan ejaan berbedaPantau ev/salon/baglanti dan pastikan kode mem-publish online setelah terhubung
Karakter sampah alih-alih nilaiPayload tidak diakhiri \0 dan dibaca tanpa memakai lengthSalin payload dalam perulangan sampai length
Perangkat ESPHome reboot setiap 15 menitDalam mode MQTT, blok api: masih ada tapi Home Assistant tidak pernah terhubungHapus blok api: atau tambahkan reboot_timeout: 0s
Ikuti urutan ketika mencari masalah: pertama cek koneksi Wi-Fi dan alamat IP di Serial Monitor, lalu pantau apa yang benar-benar sampai ke broker dengan mosquitto_sub -v -t "#" di komputermu, dan baru setelah itu lihat Home Assistant. Kalau pesan muncul di broker tapi tidak di Home Assistant, masalahnya ada di JSON discovery; kalau tidak pernah sampai ke broker, masalahnya di sisi ESP32. Kalau kamu mentok di tahap Wi-Fi, lihat ESP32 tidak mau terhubung ke Wi-Fi, dan kalau board reset ketika relay berbunyi klik, lihat Brownout dan Guru Meditation ESP32.

Dengan sebuah broker, beberapa topic, dan PubSubClient, ESP32-mu sudah menjadi perangkat rumah pintar yang berbicara dengan bahasa yang sama seperti seisi rumah. Kamu bisa menambahkan sensor baru, ruangan lain, dan board berbeda seperti Pico W ke susunan yang sama, lalu mengelola semuanya dari satu dasbor Home Assistant. Di aplikasi BlueGrays kamu akan menemukan proyek seperti koneksi Wi-Fi ESP32, pengukuran suhu dan kelembapan DHT22, lampu pintar dengan PIR dan relay, kendali real-time dengan WebSocket, dan penyiraman tanaman pintar, langkah demi langkah dengan skema rangkaian dan kode.

Pertanyaan umum

MQTT dipakai untuk apa?

MQTT adalah protokol pesan ringan di mana perangkat mengirim dan menerima pesan lewat broker dengan memakai nama topic. Karena hemat bandwidth dan daya, MQTT ideal bagi perangkat kecil seperti ESP32 untuk mengirim data sensor dan menerima perintah. Home Assistant, Node-RED, dan sebagian besar sistem IoT industri memakai MQTT.

MQTT memakai port berapa?

MQTT tanpa enkripsi secara bawaan memakai port 1883, dan MQTT terenkripsi TLS memakai port 8883. Port WebSocket yang dipakai untuk koneksi browser tergantung broker-nya; di broker Mosquitto di Home Assistant, port-nya 1884. Di jaringan rumah, ESP32 biasanya terhubung ke 1883.

Apakah MQTT butuh koneksi internet?

Tidak. Kalau broker berjalan di Raspberry Pi atau di Home Assistant di rumah, lalu lintas antara ESP32 dan broker sepenuhnya tetap di jaringan lokalmu; sensor dan relay tetap bekerja meskipun internet mati. Kamu hanya butuh internet untuk mengakses sistem dari luar atau untuk memakai broker cloud.

Kenapa ESP32-ku tidak muncul di Home Assistant?

Penyebab yang paling umum adalah pesan discovery yang tidak muat di buffer 256 byte PubSubClient, topic config yang salah ketik, atau kesalahan tanda kutip di JSON. Dengarkan homeassistant/# dengan mosquitto_sub untuk mengecek apakah pesannya sampai ke broker, dan pastikan kode berisi baris mqtt.setBufferSize(1024). Integrasi MQTT di Home Assistant juga harus terhubung ke broker yang sama.

Sebaiknya pakai ESPHome atau MQTT dengan Arduino?

Kalau tujuanmu cepat punya perangkat rumah pintar yang berfungsi, ESPHome lebih sedikit usahanya: kamu menulis YAML, perangkat muncul sendiri di Home Assistant dan diperbarui lewat udara. Kalau kamu ingin mempelajari protokol MQTT, menulis logikamu sendiri, atau bekerja dengan sistem selain Home Assistant, Arduino dengan PubSubClient lebih fleksibel. Keduanya bisa hidup berdampingan dengan nyaman di rumah yang sama.

Apa bedanya QoS 0, 1, dan 2 di MQTT?

QoS 0 mengirim pesan sekali tanpa menunggu konfirmasi, QoS 1 mengirimnya ulang sampai dikonfirmasi tapi pesan bisa sampai dua kali, dan QoS 2 memakai jabat tangan empat langkah untuk menjamin pesan sampai tepat sekali. QoS 0 cukup untuk pembacaan sensor dan QoS 1 untuk perintah. PubSubClient hanya bisa publish dengan QoS 0 dan subscribe dengan QoS 0 atau 1.

Lihat semua proyek
LED Berkedip dengan ESP32
#103Pemula

LED Berkedip dengan ESP32

Mengajarkan penggunaan output GPIO dasar dengan ESP32. Kita membuat efek berkedip dengan menyalakan dan mematikan LED dari pin digital. Versi ESP32 dari proyek blink klasik di Arduino UNO; perintah blink dasar di lingkungan Arduino sama, tetapi susunan pin ESP32 dan level GPIO 3,3 V-nya berbeda dengan Arduino UNO.

4.7(37)
99
Koneksi Wi-Fi STA ESP32 (dengan Layar LCD)
#127Mahir

Koneksi Wi-Fi STA ESP32 (dengan Layar LCD)

Di proyek ini, kita menyambungkan ESP32 ke jaringan Wi-Fi rumah dalam mode Station (STA) dengan cara yang aman dan tahan gangguan. Kita menyimpan SSID dan kata sandi di file secrets.h terpisah agar tidak bocor ke Git, menyiapkan mekanisme sambung ulang otomatis, dan menampilkan tingkat sinyal RSSI dan alamat IP di layar LCD I2C. LED bawaan bekerja sebagai indikator status. Ini adalah pengelola koneksi kelas produksi.

4.4(21)
34
Suhu dan Kelembapan DHT22 ESP32 (dengan Layar LCD)
#117Menengah

Suhu dan Kelembapan DHT22 ESP32 (dengan Layar LCD)

Proyek ini mengukur suhu dan kelembapan sekitar dengan sensor DHT22 dan menampilkan datanya secara real-time di LCD I2C 16x2. Data dibaca dari sensor dengan protokol satu kabel lewat library Adafruit DHT. Proyek ini menjadi dasar untuk stasiun cuaca IoT, otomasi rumah pintar, atau sistem pemantauan lingkungan di rumah kaca. Komunikasi dengan DHT22 dilakukan lewat pin GPIO 4 ESP32.

4.8(38)
56
Lampu Pintar ESP32 (PIR + LDR + Relay + OLED)
#141Mahir
Premium

Lampu Pintar ESP32 (PIR + LDR + Relay + OLED)

Ubah lorong, kamar mandi, atau gudangmu menjadi lampu pintar dengan ESP32! Dengan sensor gerak PIR, sensor cahaya LDR, dan modul relay, kita membuat skenario klasik "lampu menyala ketika ada gerakan dalam gelap"; jika sudah terang, gerakan TIDAK menyalakan lampu, jadi energi hemat di siang hari. Lampu menyala 30 detik; jika gerakan berlanjut, timer diulang. OLED SSD1306 menampilkan status dengan font besar (NYALA / SIANG / MENUNGGU) dan hitung mundur.

4.3(6)
11
Penghitung WebSocket ESP32 (2 Tombol + LCD + Web Real-Time)
#130Mahir
Premium

Penghitung WebSocket ESP32 (2 Tombol + LCD + Web Real-Time)

Di proyek ini, dua tombol yang tersambung ke ESP32 (GPIO 5 menghitung naik, GPIO 4 menghitung turun) mengubah sebuah penghitung. Nilainya langsung diperbarui di LCD I2C 16x2 sekaligus, lewat dukungan WebSocket ESPAsyncWebServer, di setiap browser yang tersambung tanpa memuat ulang halaman. Alih-alih polling HTTP, dipakai satu koneksi yang tetap terbuka, dan ESP32 mengirim nilai baru ke semua orang dengan ws.textAll().

4.5(14)
23
mDNS ESP32: Mengakses Perangkat lewat bluegrays-esp.local (dengan Layar LCD)
#131Mahir
Premium

mDNS ESP32: Mengakses Perangkat lewat bluegrays-esp.local (dengan Layar LCD)

Di proyek ini, kita menambahkan layanan mDNS (Multicast DNS) ke ESP32, sehingga perangkat bisa diakses dengan nama host seperti bluegrays-esp.local, bukan alamat IP. Meskipun IP dari DHCP berubah, perangkat selalu bisa dijangkau dengan nama yang sama. Web server kecil di perangkat menerima perintah kendali LED dari browser lewat alamat http://bluegrays-esp.local/. Layar LCD I2C menampilkan nama host, alamat IP, dan status LED.

4.8(14)
23
Sistem Alarm Gerakan ESP32 (PIR + Buzzer + LED + Telegram)
#145Mahir
Premium

Sistem Alarm Gerakan ESP32 (PIR + Buzzer + LED + Telegram)

Sistem alarm keamanan pintar yang menyalakan buzzer dan LED ketika sensor PIR mendeteksi gerakan, sekaligus mengirim notifikasi instan ke pemilik lewat Telegram. Cooldown 30 detik membatasi seberapa sering alarm berulang; mekanisme ini tidak memvalidasi deteksi PIR atau menghilangkan pemicu palsu. Cocok untuk rumah, garasi, gudang, atau ruang kerja. Dengan ESP32-CAM bisa ditambahkan notifikasi berfoto; dengan ESP32 DevKit V1 klasik, notifikasinya berupa teks.

0.0(0)
9