Pada artikel sebelumnya, kita sudah berhasil membuat ESP32 menjadi Web Server yang bisa diakses dari browser. Sistem tersebut bekerja dengan baik, tetapi memiliki satu batasan: ESP32 harus berada di jaringan WiFi yang sama dengan perangkat yang mengaksesnya. Jika Anda berada di luar rumah, Anda tidak bisa memantau atau mengendalikan perangkat tersebut.
Di artikel ini, kita akan membahas MQTT (Message Queuing Telemetry Transport) — protokol komunikasi yang dirancang khusus untuk kebutuhan IoT, dan menjadi standar industri untuk menghubungkan perangkat-perangkat IoT yang tersebar di berbagai lokasi melalui internet.
Kita akan membangun sistem di mana ESP32 mempublikasikan data sensor BMP280 ke Node-RED Dashboard yang bisa dilihat dari manapun, dan Node-RED bisa mengirimkan perintah balik ke ESP32 untuk mengendalikan LED. Sebagai broker MQTT, kita akan menggunakan EMQX Cloud — layanan managed broker yang sudah dibahas di tutorial EMQX Cloud sebagai MQTT Broker.
Apa Itu MQTT?
MQTT (Message Queuing Telemetry Transport) adalah protokol komunikasi berbasis model publish–subscribe yang dirancang untuk perangkat dengan keterbatasan bandwidth dan resource. Protokol ini sangat ringan, efisien, dan ideal untuk komunikasi IoT melalui jaringan yang tidak stabil sekalipun.
Model Publish–Subscribe
Berbeda dengan model request-response yang digunakan HTTP (yang kita pakai di Web Server), MQTT menggunakan model publish–subscribe di mana:
- Publisher — perangkat yang mengirimkan data ke broker. Publisher tidak perlu tahu siapa yang menerima datanya.
- Subscriber — perangkat atau aplikasi yang mendaftar untuk menerima data dari topic tertentu. Subscriber tidak perlu tahu siapa yang mengirimkan datanya.
- Broker — server perantara yang menerima semua pesan dari publisher dan mendistribusikannya ke subscriber yang relevan.
Publisher (ESP32) ── publish ──▶ Broker (EMQX Cloud) ── distribute ──▶ Subscriber (Node-RED)
Subscriber (Node-RED) ── publish ──▶ Broker ── distribute ──▶ Subscriber (ESP32)Satu entitas (seperti ESP32 kita) bisa sekaligus menjadi publisher dan subscriber pada saat bersamaan.
Topic MQTT
Setiap pesan MQTT dikirim ke sebuah topic — sebuah string teks yang menjadi alamat tujuan pesan. Topic menggunakan tanda / sebagai pemisah hierarki, mirip seperti path URL.
Contoh struktur topic yang baik:
ruangan/suhu
ruangan/tekanan
ruangan/kipas/kontrol
ruangan/kipas/statusSubscriber mendaftar ke topic yang diminati. Jika Node-RED mendaftar ke ruangan/suhu, maka setiap kali ESP32 mempublikasikan data ke topic tersebut, Node-RED akan menerimanya secara otomatis — kapanpun dan dari manapun, selama keduanya terhubung ke broker yang sama.
QoS (Quality of Service)
MQTT menyediakan tiga level QoS untuk menjamin keandalan pengiriman pesan:
| Level | Nama | Jaminan Pengiriman |
|---|---|---|
| QoS 0 | At most once | Pesan dikirim sekali, tanpa konfirmasi. Mungkin hilang. |
| QoS 1 | At least once | Pesan dijamin sampai, tapi mungkin duplikat. |
| QoS 2 | Exactly once | Pesan dijamin sampai tepat sekali. |
Untuk sebagian besar proyek sensor IoT, QoS 1 adalah pilihan yang seimbang antara keandalan dan efisiensi.
Kenapa MQTT Lebih Baik dari HTTP untuk IoT?
| Aspek | HTTP (Web Server) | MQTT |
|---|---|---|
| Arsitektur | Request-Response | Publish-Subscribe |
| Overhead | Besar (header HTTP panjang) | Sangat kecil (header 2 byte) |
| Koneksi | Stateless (buka-tutup tiap request) | Persistent (selalu terhubung) |
| Arah data | Client harus polling | Server bisa push data kapanpun |
| Skalabilitas | Terbatas | Sangat baik (jutaan device) |
| Akses jarak jauh | Butuh IP publik / port forwarding | Cukup terhubung ke broker yang sama |
| Cocok untuk | Dashboard web, REST API | IoT sensor, real-time monitoring |
Persiapan: EMQX Cloud sebagai Broker MQTT
Untuk tutorial ini, kita menggunakan EMQX Cloud Serverless sebagai broker MQTT. EMQX Cloud adalah layanan managed broker yang berarti kita tidak perlu mengelola server sendiri — cukup daftar, buat deployment, dan broker siap digunakan.
Panduan lengkap membuat akun dan deployment EMQX Cloud sudah tersedia di artikel terpisah: Tutorial EMQX Cloud sebagai MQTT Broker
Ikuti panduan di artikel tersebut untuk menyelesaikan langkah-langkah berikut sebelum melanjutkan:
- Registrasi akun di emqx.com (bisa menggunakan Google)
- Buat Project baru di EMQX Cloud Console
- Deploy broker dengan tipe Serverless (gratis)
- Catat connection info dari halaman Overview deployment Anda:
- Connection Address (contoh:
xxxxxxxx.ala.dedicated.emqx.cloud) - Port MQTTS:
8883(TLS/SSL)
- Connection Address (contoh:
- Buat credentials (username dan password) di menu Authentication
Setelah selesai, Anda akan memiliki detail koneksi seperti ini yang akan digunakan di kode ESP32:
MQTT Broker Host : xxxxxxxx.ala.dedicated.emqx.cloud
MQTT Port : 8883
Username : nama_user_anda
Password : password_andaCatatan tentang Port: EMQX Cloud Serverless menggunakan port 8883 dengan enkripsi TLS/SSL secara default untuk koneksi yang aman.
Persiapan Hardware
Komponen yang dibutuhkan sama seperti artikel-artikel sebelumnya:
| Komponen | Keterangan |
|---|---|
| ESP32 DevKit | Mikrokontroler utama |
| Sensor BMP280 | Sensor suhu dan tekanan (I2C) |
| LED + Resistor 330Ω | Output yang akan dikendalikan dari Node-RED |
Wiring BMP280:
| Pin BMP280 | Pin ESP32 |
|---|---|
| VCC | 3.3V |
| GND | GND |
| SCL | GPIO 22 |
| SDA | GPIO 21 |
Wiring LED:
Jika Anda ingin menggunakan LED internal pada ESP32 bisa menggunakan GPIO 2.
| Komponen | Koneksi |
|---|---|
| LED (anoda) | GPIO 4 via resistor 330Ω |
| LED (katoda) | GND |
Instalasi Library
Untuk menggunakan MQTT pada ESP32, kita membutuhkan library PubSubClient karya Nick O’Leary.
Cara instalasi:
- Buka Arduino IDE
- Pilih menu Sketch → Include Library → Manage Libraries
- Cari “PubSubClient”
- Install PubSubClient by Nick O’Leary
- Restart Arduino IDE
Library lain yang dibutuhkan sudah familiar dari artikel sebelumnya: Adafruit BMP280 dan Adafruit Unified Sensor.
Memahami Topik yang Akan Digunakan
Sebelum menulis kode, kita tentukan terlebih dahulu struktur topic yang akan digunakan:
| Topic | Arah Data | Keterangan |
|---|---|---|
esp32/suhu | ESP32 → Broker → Node-RED | Data suhu dari BMP280 |
esp32/tekanan | ESP32 → Broker → Node-RED | Data tekanan dari BMP280 |
esp32/output | Node-RED → Broker → ESP32 | Perintah ON/OFF untuk LED |
Latihan: ESP32 + BMP280 + MQTT
Jika deployment EMQX Cloud Anda hanya mendukung koneksi terenkripsi (TLS/SSL via port 8883), gunakan WiFiClientSecure sebagai ganti WiFiClient.
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
const char* ssid = "NAMA_WIFI_ANDA";
const char* password = "PASSWORD_WIFI_ANDA";
const char* mqtt_server = "ALAMAT_BROKER_EMQX_ANDA.emqx.cloud";
const int mqtt_port = 8883;
const char* mqtt_user = "USERNAME_ANDA";
const char* mqtt_password = "PASSWORD_ANDA";
const char* client_id = "ESP32-TLS-Monitor";
const char* TOPIC_SUHU = "esp32/suhu";
const char* TOPIC_TEKANAN = "esp32/tekanan";
const char* TOPIC_OUTPUT = "esp32/output";
const int PIN_LED = 4;
// Gunakan WiFiClientSecure untuk TLS
WiFiClientSecure espClientSecure;
PubSubClient mqtt(espClientSecure);
Adafruit_BMP280 bmp;
unsigned long lastPublish = 0;
void callback(char* topic, byte* payload, unsigned int length) {
String pesan = "";
for (unsigned int i = 0; i < length; i++) pesan += (char)payload[i];
Serial.print("[MQTT/TLS] Diterima [");
Serial.print(topic);
Serial.print("]: ");
Serial.println(pesan);
if (String(topic) == TOPIC_OUTPUT) {
if (pesan == "on") digitalWrite(PIN_LED, HIGH);
if (pesan == "off") digitalWrite(PIN_LED, LOW);
}
}
void setupWifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi OK: " + WiFi.localIP().toString());
}
void reconnectMQTT() {
while (!mqtt.connected()) {
Serial.print("MQTT (TLS) connecting...");
if (mqtt.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("OK");
mqtt.subscribe(TOPIC_OUTPUT);
} else {
Serial.print("rc=");
Serial.print(mqtt.state());
Serial.println(" retry in 5s");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(PIN_LED, OUTPUT);
digitalWrite(PIN_LED, LOW);
if (!bmp.begin(0x76)) {
Serial.println("BMP280 gagal!");
while (1);
}
setupWifi();
// Nonaktifkan verifikasi sertifikat CA untuk kemudahan
// (untuk produksi, gunakan sertifikat CA yang valid)
espClientSecure.setInsecure();
mqtt.setServer(mqtt_server, mqtt_port);
mqtt.setCallback(callback);
mqtt.setBufferSize(512);
}
void loop() {
if (!mqtt.connected()) reconnectMQTT();
mqtt.loop();
if (millis() - lastPublish > 10000) {
lastPublish = millis();
float suhu = bmp.readTemperature();
float tekanan = bmp.readPressure() / 100.0F;
char bufS[10], bufT[10];
dtostrf(suhu, 1, 2, bufS);
dtostrf(tekanan, 1, 2, bufT);
mqtt.publish(TOPIC_SUHU, bufS);
mqtt.publish(TOPIC_TEKANAN, bufT);
Serial.printf("[Sensor] Suhu: %s °C | Tekanan: %s hPa\n", bufS, bufT);
}
}
Catatan:
setInsecure()menonaktifkan verifikasi sertifikat CA, yang memudahkan koneksi saat pengembangan. Untuk lingkungan produksi, gunakanespClientSecure.setCACert(root_ca_cert)dengan sertifikat CA yang sesuai dari EMQX Cloud.

Node-RED: Dashboard dan Kontrol
Node-RED adalah platform pemrograman visual berbasis flow yang sangat populer untuk integrasi IoT. Kita akan menggunakannya untuk menerima data sensor dari ESP32 dan menampilkannya di dashboard, sekaligus mengirim perintah balik ke ESP32.
Instalasi Node-RED
Node-RED bisa diinstal di berbagai platform. Cara termudah untuk mencoba adalah menggunakan Node.js di laptop Anda:
# Install Node-RED via npm
npm install -g --unsafe-perm node-red
# Jalankan Node-RED
node-redSetelah berjalan, buka browser dan akses http://localhost:1880.
Alternatif lainnya adalah menggunakan Node-RED di Raspberry Pi atau menggunakan layanan cloud Node-RED Online (seperti flowfuse.com).
Instalasi Node-RED Dashboard
Node-RED memerlukan plugin tambahan untuk fitur dashboard (gauge, chart, tombol):
- Di Node-RED, klik ikon menu ☰ di pojok kanan atas
- Pilih Manage palette
- Tab Install, cari
@flowfuse/node-red-dashboard - Klik Install dan tunggu proses selesai
- Restart Node-RED
Konfigurasi MQTT di Node-RED
Pertama, kita perlu mendaftarkan broker EMQX Cloud ke Node-RED:
- Seret node mqtt in dari panel kiri ke canvas
- Klik dua kali node tersebut untuk konfigurasi
- Di kolom Server, klik ikon edit (pensil)
- Isi detail broker:
- Name: EMQX Cloud
- Server: alamat broker EMQX Anda
- Port: 1883 (atau 8883 untuk TLS)
- Client ID: NodeRED-Client-001
- Tab Security → isi Username dan Password sesuai credentials EMQX Cloud Anda
- Klik Update, lalu Done

Membangun Flow Node-RED
Berikut adalah deskripsi flow yang perlu dibuat. Flow ini terdiri dari dua bagian: menerima data sensor (subscribe) dan mengirim perintah (publish).
Flow 1 — Tampilkan Suhu di Dashboard:
[mqtt in: esp32/suhu] → [gauge: Suhu] + [chart: Grafik Suhu]Konfigurasi node mqtt in:
- Server: EMQX Cloud (yang sudah dikonfigurasi)
- Topic:
esp32/suhu - QoS: 1
- Output: String
Konfigurasi node gauge:
- Group: Pilih atau buat grup baru “Monitoring Ruangan”
- Label: Suhu
- Units: °C
- Range: min 0, max 50
Flow 2 — Tampilkan Tekanan di Dashboard:
[mqtt in: esp32/tekanan] → [gauge: Tekanan]Konfigurasi gauge tekanan: Units: hPa, Range: 300–1100.
Flow 3 — Tombol Kontrol LED:
[button: LED ON] → [mqtt out: esp32/output]
[button: LED OFF] → [mqtt out: esp32/output]Konfigurasi node button LED ON:
- Label: Nyalakan LED
- Payload:
on(string)
Konfigurasi node button LED OFF:
- Label: Matikan LED
- Payload:
off(string)
Konfigurasi node mqtt out:
- Server: EMQX Cloud
- Topic:
esp32/output - QoS: 1
Flow 4 — Status LED:
[mqtt in: esp32/status] → [text: Status LED]
JSON Flow Lengkap
Untuk kemudahan, berikut adalah JSON flow yang bisa langsung di-import ke Node-RED:
- Di Node-RED, klik menu ☰ → Import
- Copy-paste JSON berikut lalu klik Import:
[
{
"id": "b49c9123e1247cbb",
"type": "ui-text",
"z": "e7a848484862d727",
"group": "111197957f279af9",
"order": 1,
"width": 0,
"height": 0,
"name": "Status LED",
"label": "Status",
"format": "{{msg.payload}}",
"layout": "row-left",
"style": false,
"font": "",
"fontSize": 16,
"color": "#717171",
"wrapText": false,
"className": "",
"value": "payload",
"valueType": "msg",
"x": 670,
"y": 200,
"wires": []
},
{
"id": "111197957f279af9",
"type": "ui-group",
"name": "Kontrol LED",
"page": "5e26a927f59b30b6",
"width": 6,
"height": 1,
"order": 2,
"showTitle": true,
"className": "",
"visible": "true",
"disabled": "false",
"groupType": "default"
},
{
"id": "5e26a927f59b30b6",
"type": "ui-page",
"name": "Belajar ESP32: MQTT",
"ui": "6d202475f7070186",
"path": "/page1",
"icon": "home",
"layout": "grid",
"theme": "f781f228d02476ac",
"breakpoints": [
{
"name": "Default",
"px": "0",
"cols": "3"
},
{
"name": "Tablet",
"px": "576",
"cols": "6"
},
{
"name": "Small Desktop",
"px": "768",
"cols": "9"
},
{
"name": "Desktop",
"px": "1024",
"cols": "12"
}
],
"order": 1,
"className": "",
"visible": "true",
"disabled": "false"
},
{
"id": "6d202475f7070186",
"type": "ui-base",
"name": "My Dashboard",
"path": "/dashboard",
"appIcon": "",
"includeClientData": true,
"acceptsClientConfig": [
"ui-notification",
"ui-control"
],
"showPathInSidebar": false,
"headerContent": "page",
"navigationStyle": "default",
"titleBarStyle": "default",
"showReconnectNotification": true,
"notificationDisplayTime": 1,
"showDisconnectNotification": true,
"allowInstall": false
},
{
"id": "f781f228d02476ac",
"type": "ui-theme",
"name": "Default Theme",
"colors": {
"surface": "#ffffff",
"primary": "#0094CE",
"bgPage": "#eeeeee",
"groupBg": "#ffffff",
"groupOutline": "#cccccc"
},
"sizes": {
"density": "default",
"pagePadding": "12px",
"groupGap": "12px",
"groupBorderRadius": "4px",
"widgetGap": "12px"
}
},
{
"id": "7316a7a928f70a02",
"type": "global-config",
"env": [],
"modules": {
"@flowfuse/node-red-dashboard": "1.30.2"
}
}
]
Catatan: Setelah import, Anda perlu mengkonfigurasi ulang node-node MQTT di atas untuk menghubungkannya ke broker EMQX Cloud Anda (dengan mengklik dua kali setiap node dan mengisi detail server). Node-node UI (gauge, chart, button, text) juga perlu dikaitkan ke grup dashboard yang Anda buat.
Mengakses Dashboard
Setelah flow dikonfigurasi dan di-deploy, buka http://localhost:1880/dashboard untuk melihat dashboard. Anda akan melihat gauge suhu dan tekanan yang berubah setiap 10 detik seiring ESP32 mengirimkan data, serta dua tombol untuk mengendalikan LED.

Eksperimen Tambahan: Auto-Reconnect yang Lebih Baik
Salah satu tantangan umum pada proyek IoT adalah koneksi yang tidak stabil. Berikut pola reconnect yang lebih robust dibanding yang ada di contoh sebelumnya — menggunakan millis() agar tidak memblokir eksekusi program saat menunggu reconnect:
unsigned long lastReconnectAttempt = 0;
bool reconnectNonBlocking() {
if (millis() - lastReconnectAttempt < 5000) return false;
lastReconnectAttempt = millis();
Serial.print("MQTT: mencoba reconnect...");
if (mqtt.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("OK");
mqtt.subscribe(TOPIC_OUTPUT);
mqtt.publish(TOPIC_STATUS, "ESP32 reconnected");
return true;
}
Serial.print("Gagal. rc=");
Serial.println(mqtt.state());
return false;
}
void loop() {
if (!mqtt.connected()) {
reconnectNonBlocking();
} else {
mqtt.loop();
if (millis() - lastPublish > PUBLISH_INTERVAL) {
lastPublish = millis();
publishSensor();
}
}
}
Perbedaan dari reconnectMQTT() sebelumnya: fungsi ini tidak blocking — alih-alih looping di tempat selama !mqtt.connected(), ia langsung return false jika belum waktunya mencoba. Ini memastikan loop() tetap berjalan normal meski koneksi sedang terputus.
Gambaran Arsitektur Sistem Lengkap
Dengan semua komponen yang sudah kita siapkan, berikut gambaran arsitektur sistem secara keseluruhan:
┌──────────────────┐
│ BMP280 Sensor │
│ (Suhu, Tekanan) │
└────────┬─────────┘
│ I2C
┌────────▼─────────────────────────────────┐
│ ESP32 DevKit │
│ Publisher: esp32/suhu, esp32/tekanan │
│ Subscriber: esp32/output │
│ Output: LED (GPIO 4) │
└────────┬─────────────────────────────────┘
│ MQTT over WiFi / Internet
┌────────▼─────────────────────────────────┐
│ EMQX Cloud Broker │
│ (Managed MQTT, Port 1883/8883) │
└────────┬─────────────────────────────────┘
│ MQTT
┌────────▼─────────────────────────────────┐
│ Node-RED │
│ Subscriber: esp32/suhu, esp32/tekanan │
│ Publisher: esp32/output │
│ Dashboard: Gauge, Chart, Button │
└──────────────────────────────────────────┘
│ HTTP
┌────────▼─────────────────────────────────┐
│ Browser (PC / Mobile) │
│ http://localhost:1880/ui │
└──────────────────────────────────────────┘
Keunggulan arsitektur ini: ESP32 dan Node-RED tidak perlu berada di jaringan yang sama. Selama keduanya terhubung ke internet dan menggunakan broker EMQX Cloud yang sama, data akan mengalir dengan lancar — dari sensor di kamar ke dashboard di laptop Anda yang mungkin berada di kafe seberang kota.
Kesimpulan
MQTT adalah tulang punggung dari sebagian besar sistem IoT modern. Dengan model publish–subscribe yang efisien dan overhead yang sangat kecil, MQTT memungkinkan ribuan perangkat IoT saling berkomunikasi melalui satu broker tanpa membebani jaringan.
Poin-poin penting yang sudah kita pelajari:
- MQTT menggunakan model publish–subscribe melalui perantara broker
- Setiap pesan dikirim ke sebuah topic — string hierarkis yang menjadi alamat tujuan
- EMQX Cloud menyediakan broker MQTT terkelola yang siap digunakan tanpa perlu setup server sendiri
- Library PubSubClient memungkinkan ESP32 terhubung ke broker MQTT dengan mudah
- Fungsi
mqtt.loop()wajib dipanggil setiap iterasi untuk memproses pesan masuk - Untuk koneksi TLS (port 8883), gunakan
WiFiClientSecuredengansetInsecure()untuk pengembangan dtostrf()digunakan untuk mengkonversifloatkechar arraysebelum dipublish- Node-RED menyediakan dashboard visual yang bisa menampilkan data sensor dan mengirim perintah ke ESP32 hanya dengan drag-and-drop
Dengan menggabungkan MQTT dan Node-RED, kita telah membangun fondasi dari sebuah sistem IoT yang sesungguhnya — dapat dimonitor dan dikendalikan dari mana saja di seluruh dunia, selama ada koneksi internet.

