MQTT ESP32: Tutorial Kirim Data Sensor & Kontrol LED dengan PubSubClient

MQTT ESP32 adalah kombinasi paling populer untuk proyek IoT: ESP32 membaca sensor, mengirim datanya ke broker MQTT, dan sekaligus menerima perintah dari dashboard atau aplikasi. Di tutorial ini Anda akan membuat satu program ESP32 yang mengirim data suhu & kelembapan DHT22 dan menerima perintah ON/OFF untuk LED memakai library PubSubClient — lengkap dengan client ID unik, reconnect otomatis, dan status online/offline (Last Will).
Belum paham konsep broker, topik, dan QoS? Baca dulu panduan protokol MQTT. Ingin mencoba MQTT dari komputer tanpa hardware? Lihat tutorial MQTT Python dengan Mosquitto.
Daftar isi:
- Arsitektur dan topik MQTT
- Langkah 1: Arduino IDE dan library
- Langkah 2: Siapkan broker MQTT
- Langkah 3: Wiring ESP32
- Langkah 4: Kode lengkap MQTT ESP32
- Langkah 5: Uji coba
- Koneksi aman ke HiveMQ Cloud (TLS)
- Troubleshooting
- FAQ
Arsitektur MQTT ESP32 yang Akan Dibuat
ESP32 berperan ganda: sebagai publisher (mengirim data sensor) dan subscriber (menerima perintah LED). Broker meneruskan data ke dashboard seperti Node-RED, dan meneruskan perintah dari PC/HP ke ESP32.

| Topik | Arah | Isi |
|---|---|---|
bisaioti/esp32-XXXXXX/sensor | ESP32 → broker | JSON suhu, kelembapan, kekuatan sinyal WiFi |
bisaioti/esp32-XXXXXX/led/set | broker → ESP32 | Perintah ON / OFF |
bisaioti/esp32-XXXXXX/led/state | ESP32 → broker | Status LED terakhir (retained) |
bisaioti/esp32-XXXXXX/status | ESP32 → broker | online / offline (Last Will, retained) |
esp32-XXXXXX dibuat otomatis dari MAC address, sehingga setiap ESP32 punya client ID dan topik sendiri tanpa perlu mengubah kode.
Alat dan Bahan
- ESP32 DevKit (ESP32-WROOM-32 atau sejenisnya) dan kabel USB data.
- Sensor DHT22 (atau DHT11). Jika memakai sensor tanpa modul, tambahkan resistor pull-up 10 kΩ antara DATA dan 3,3 V.
- LED + resistor 220 Ω (opsional — banyak board DevKit sudah punya LED bawaan di GPIO2).
- Breadboard dan kabel jumper.
- Komputer dengan Arduino IDE 2.x dan broker MQTT (Mosquitto lokal atau broker cloud).
Langkah 1 – Siapkan Arduino IDE, Board ESP32, dan Library
- Buka File → Preferences, isi Additional Boards Manager URLs dengan:
https://espressif.github.io/arduino-esp32/package_esp32_index.json - Buka Tools → Board → Boards Manager, cari esp32 (by Espressif Systems), lalu instal.
- Buka Sketch → Include Library → Manage Libraries, instal PubSubClient (Nick O’Leary), DHT sensor library (Adafruit), dan Adafruit Unified Sensor.
- Pilih board ESP32 Dev Module dan port COM yang sesuai.
URL lama dl.espressif.com/dl/package_esp32_index.json yang ada di banyak tutorial sudah tidak diperbarui. Gunakan URL di atas agar mendapat core ESP32 terbaru.
Langkah 2 – Siapkan Broker MQTT
| Pilihan broker | Kapan dipakai | Pengaturan di kode |
|---|---|---|
| Mosquitto di PC / Raspberry Pi | Belajar dan proyek di jaringan lokal | MQTT_SERVER = IP komputer broker, port 1883 |
Broker publik (broker.hivemq.com, test.mosquitto.org) | Uji coba cepat tanpa instalasi — data terbuka untuk umum | Isi nama host, port 1883 |
| HiveMQ Cloud (gratis) | Akses lewat internet dengan login & enkripsi | Port 8883 + TLS, lihat bagian koneksi aman |
Cara instal Mosquitto ada di panduan Windows dan panduan Raspberry Pi / Linux. Karena ESP32 terhubung dari perangkat lain, pastikan mosquitto.conf berisi listener 1883 dan allow_anonymous true (atau user/password), lalu izinkan port 1883 di firewall. ESP32 dan komputer broker harus berada di jaringan WiFi yang sama.
Langkah 3 – Wiring ESP32, DHT22, dan LED
| Komponen | Pin komponen | Pin ESP32 |
|---|---|---|
| DHT22 | VCC | 3V3 |
| DHT22 | DATA | GPIO4 |
| DHT22 | GND | GND |
| LED | Anoda (kaki panjang) melalui resistor 220 Ω | GPIO2 |
| LED | Katoda (kaki pendek) | GND |
Langkah 4 – Kode Lengkap MQTT ESP32
Salin kode berikut ke Arduino IDE, ubah bagian KONFIGURASI (nama WiFi, password, dan alamat broker), lalu upload ke ESP32.
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ====== 1. KONFIGURASI (ganti sesuai jaringan Anda) ======
const char* WIFI_SSID = "NAMA_WIFI";
const char* WIFI_PASSWORD = "PASSWORD_WIFI";
const char* MQTT_SERVER = "192.168.1.5"; // IP komputer yang menjalankan Mosquitto
const int MQTT_PORT = 1883;
const char* MQTT_USER = ""; // kosongkan jika broker tanpa login
const char* MQTT_PASS = "";
#define DHTPIN 4
#define DHTTYPE DHT22 // ganti DHT11 jika memakai DHT11
#define LED_PIN 2
const unsigned long INTERVAL_KIRIM = 5000; // kirim data tiap 5 detik
// =========================================================
DHT dht(DHTPIN, DHTTYPE);
WiFiClient espClient;
PubSubClient mqtt(espClient);
String clientId; // dibuat unik dari MAC address
String topicSensor, topicLedSet, topicLedState, topicStatus;
unsigned long lastSend = 0, lastReconnect = 0;
void setupWiFi() {
Serial.print("Menghubungkan ke WiFi");
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("\nWiFi terhubung, IP: ");
Serial.println(WiFi.localIP());
}
// Dipanggil otomatis setiap ada pesan masuk dari topik yang di-subscribe
void callback(char* topic, byte* payload, unsigned int length) {
String msg;
for (unsigned int i = 0; i < length; i++) msg += (char)payload[i];
msg.trim();
Serial.printf("Pesan masuk [%s]: %s\n", topic, msg.c_str());
if (String(topic) == topicLedSet) {
if (msg == "ON") digitalWrite(LED_PIN, HIGH);
if (msg == "OFF") digitalWrite(LED_PIN, LOW);
// laporkan status LED terbaru (retained)
mqtt.publish(topicLedState.c_str(), digitalRead(LED_PIN) ? "ON" : "OFF", true);
}
}
bool connectMQTT() {
Serial.printf("Menghubungkan ke broker %s sebagai %s ... ", MQTT_SERVER, clientId.c_str());
// Last Will: jika ESP32 mati mendadak, broker mengirim "offline" ke topicStatus
bool ok = mqtt.connect(clientId.c_str(), MQTT_USER, MQTT_PASS,
topicStatus.c_str(), 1, true, "offline");
if (ok) {
Serial.println("berhasil");
mqtt.publish(topicStatus.c_str(), "online", true);
mqtt.subscribe(topicLedSet.c_str(), 1); // subscribe cukup sekali setelah connect
} else {
Serial.printf("gagal, state=%d\n", mqtt.state());
}
return ok;
}
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
dht.begin();
setupWiFi();
// Client ID & topik unik per perangkat, contoh: esp32-A1B2C3
String mac = WiFi.macAddress(); // "AA:BB:CC:A1:B2:C3"
mac.replace(":", "");
clientId = "esp32-" + mac.substring(6);
topicSensor = "bisaioti/" + clientId + "/sensor";
topicLedSet = "bisaioti/" + clientId + "/led/set";
topicLedState = "bisaioti/" + clientId + "/led/state";
topicStatus = "bisaioti/" + clientId + "/status";
mqtt.setServer(MQTT_SERVER, MQTT_PORT);
mqtt.setCallback(callback);
}
void loop() {
// Reconnect tanpa memblokir program (dicoba tiap 5 detik)
if (!mqtt.connected()) {
unsigned long now = millis();
if (lastReconnect == 0 || now - lastReconnect > 5000) {
lastReconnect = now;
connectMQTT();
}
return;
}
mqtt.loop(); // wajib dipanggil sesering mungkin
if (millis() - lastSend >= INTERVAL_KIRIM) {
lastSend = millis();
float suhu = dht.readTemperature();
float hum = dht.readHumidity();
if (isnan(suhu) || isnan(hum)) {
Serial.println("Gagal membaca sensor DHT!");
return;
}
char payload[96];
snprintf(payload, sizeof(payload),
"{\"suhu\":%.1f,\"kelembapan\":%.1f,\"rssi\":%d}",
suhu, hum, WiFi.RSSI());
mqtt.publish(topicSensor.c_str(), payload);
Serial.printf("Kirim ke %s: %s\n", topicSensor.c_str(), payload);
}
}Penjelasan Kode MQTT ESP32
- Client ID unik — dibuat dari MAC address (
esp32-A1B2C3). Dua perangkat dengan client ID sama akan saling memutus koneksi, masalah yang sering terjadi bila memakai ID tetap seperti"ESP32Client". - Last Will — parameter tambahan pada
mqtt.connect()membuat broker mengirimofflineke topik status jika ESP32 mati mendadak. Setelah terhubung, ESP32 mengirimonlinedengan flag retained. - Subscribe sekali setelah connect — bukan di dalam
loop(), sehingga tidak membanjiri broker. Karena ada diconnectMQTT(), langganan otomatis dipulihkan setelah reconnect. - Reconnect tanpa blocking — percobaan ulang dilakukan tiap 5 detik memakai
millis(), bukanwhile+delay(), sehingga program lain tetap berjalan. - Pengiriman berkala dengan
millis()—mqtt.loop()tetap dipanggil terus sehingga perintah LED langsung diproses, tidak tertahandelay(5000). - Payload JSON — satu pesan berisi beberapa nilai sekaligus, mudah diolah di Node-RED, Python, atau database.
Langkah 5 – Uji Coba MQTT ESP32
Buka Serial Monitor (115200 baud). Jika berhasil, akan muncul output seperti ini (client ID Anda akan berbeda):
WiFi terhubung, IP: 192.168.1.50
Menghubungkan ke broker 192.168.1.5 sebagai esp32-A1B2C3 ... berhasil
Kirim ke bisaioti/esp32-A1B2C3/sensor: {"suhu":30.3,"kelembapan":73.6,"rssi":-58}
Pesan masuk [bisaioti/esp32-A1B2C3/led/set]: ONPantau semua pesan dari komputer, lalu kirim perintah ke LED:
# lihat semua data dan status dari ESP32
mosquitto_sub -h 192.168.1.5 -t "bisaioti/#" -v
# nyalakan dan matikan LED (ganti esp32-A1B2C3 dengan client ID Anda)
mosquitto_pub -h 192.168.1.5 -t "bisaioti/esp32-A1B2C3/led/set" -m "ON"
mosquitto_pub -h 192.168.1.5 -t "bisaioti/esp32-A1B2C3/led/set" -m "OFF"Contoh yang tampil di mosquitto_sub:
bisaioti/esp32-A1B2C3/status online
bisaioti/esp32-A1B2C3/sensor {"suhu":30.3,"kelembapan":73.6,"rssi":-58}
bisaioti/esp32-A1B2C3/led/set ON
bisaioti/esp32-A1B2C3/led/state ON
bisaioti/esp32-A1B2C3/status offline <- muncul saat ESP32 dicabut dayanyaSelain terminal, Anda bisa memakai aplikasi MQTT Explorer atau menampilkan data di dashboard — lihat tutorial ESP32 + MQTT + Node-RED. Data yang sama juga bisa dibaca program Python dari tutorial MQTT Python.
Koneksi Aman ke HiveMQ Cloud (TLS, Port 8883)
Jika ESP32 harus terhubung lewat internet, gunakan broker pribadi dengan login dan enkripsi, misalnya HiveMQ Cloud (paket Serverless gratis). Cara membuat cluster dan username/password ada di tutorial HiveMQ Cloud. Di kode ESP32, cukup ubah bagian berikut:
#include <WiFiClientSecure.h> // ganti WiFiClient dengan versi TLS
const char* MQTT_SERVER = "xxxxxxxx.s1.eu.hivemq.cloud"; // Cluster URL
const int MQTT_PORT = 8883; // port TLS
const char* MQTT_USER = "esp32_user";
const char* MQTT_PASS = "PasswordAnda";
WiFiClientSecure espClient; // sebelumnya: WiFiClient espClient;
PubSubClient mqtt(espClient);
// di dalam setup(), sebelum mqtt.setServer(...):
espClient.setInsecure(); // uji coba: enkripsi aktif tanpa verifikasi sertifikatsetInsecure() praktis untuk belajar, tetapi tidak memverifikasi identitas server. Untuk perangkat produksi, gunakan espClient.setCACert(root_ca) dengan sertifikat root CA yang dipakai broker Anda (lihat dokumentasi penyedia broker).
Troubleshooting MQTT ESP32
Gejala / kode mqtt.state() | Penyebab umum | Solusi |
|---|---|---|
| WiFi tidak pernah terhubung | SSID/password salah atau jaringan 5 GHz | ESP32 hanya mendukung WiFi 2,4 GHz; cek SSID dan password |
-2 (connect failed) | IP broker salah, broker mati, atau diblokir firewall | Cek IP broker, listener 1883 di mosquitto.conf, dan firewall |
-4 (timeout) | Jaringan lambat atau port salah | Pastikan port 1883 (tanpa TLS) atau 8883 (TLS) |
4 / 5 (bad credentials / unauthorized) | Username/password salah atau broker menolak anonim | Isi MQTT_USER dan MQTT_PASS sesuai broker |
| Terus terputus-sambung | Dua perangkat memakai client ID sama | Gunakan client ID unik seperti di kode ini |
| Pesan panjang tidak terkirim | Batas paket PubSubClient default 256 byte | Tambahkan mqtt.setBufferSize(512); di setup() |
| “Gagal membaca sensor DHT!” | Wiring salah atau jenis sensor tidak sesuai | Cek pin DATA ke GPIO4 dan DHTTYPE (DHT11/DHT22) |
Tugas Praktikum
- Tambahkan sensor cahaya (LDR di GPIO34) dan kirim nilainya di payload JSON yang sama.
- Buat dashboard Node-RED berisi gauge suhu, grafik kelembapan, dan tombol ON/OFF LED.
- Tampilkan status
online/offlineESP32 di dashboard memakai topik status (Last Will). - Pindahkan koneksi ke HiveMQ Cloud dengan TLS dan bandingkan kestabilannya dengan broker lokal.
FAQ MQTT ESP32
Library MQTT apa yang terbaik untuk ESP32?
PubSubClient paling banyak dipakai dan mudah dipelajari. Keterbatasannya: publish hanya QoS 0 dan subscribe QoS 0/1. Jika butuh publish QoS 1/2, pertimbangkan library lain seperti AsyncMqttClient atau 256dpi/arduino-mqtt.
Apakah ESP32 bisa menjadi broker MQTT?
Bisa dengan library tertentu, tetapi kapasitasnya terbatas. Untuk sistem yang stabil, jalankan broker di PC, Raspberry Pi, server, atau layanan cloud, lalu jadikan ESP32 sebagai client.
Berapa interval kirim data yang ideal?
Untuk monitoring lingkungan, 5–60 detik sudah cukup. Interval terlalu cepat membebani broker dan menghabiskan kuota broker cloud. Ubah nilai INTERVAL_KIRIM sesuai kebutuhan.
Bagaimana menampilkan data MQTT ESP32 di dashboard?
Gunakan Node-RED dengan node mqtt in dan dashboard. Contoh lengkapnya ada di tutorial DHT11 ke Node-RED dan stack ESP32 + Node-RED + InfluxDB.
Kesimpulan
Dengan satu program, ESP32 Anda kini bisa mengirim data sensor dan menerima perintah melalui MQTT secara andal: client ID unik, reconnect otomatis, dan status online/offline. Untuk penerapan di lingkungan pabrik, lanjutkan ke seri ESP32 di industri: kirim data Modbus ke MQTT broker. Ingin belajar ESP32 dan IoT secara terstruktur? Ikuti Training ESP32 Berbasis IoT.
Referensi
- Nick O’Leary, “Arduino Client for MQTT (PubSubClient) – API” – pubsubclient.knolleary.net
- Espressif, “Arduino-ESP32: Installing” – docs.espressif.com
- Eclipse Mosquitto, “mosquitto.conf man page” – mosquitto.org
- HiveMQ, “Getting Started with HiveMQ Cloud” – docs.hivemq.com
Baca Juga:




