ESP32 Mengirim Data Sensor Menggunakan MQTT

MQTT merupakan salah satu protokol komunikasi yang sangat populer dalam sistem Internet of Things atau IoT. Berbeda dengan HTTP yang menggunakan pola request/response, MQTT menggunakan model publish/subscribe sehingga perangkat IoT dapat mengirim dan menerima data melalui sebuah broker.

ESP32 sangat cocok digunakan sebagai MQTT client karena sudah memiliki WiFi bawaan. ESP32 dapat membaca sensor, kemudian melakukan publish data ke MQTT broker. Server atau aplikasi lain yang membutuhkan data tersebut cukup melakukan subscribe pada topic yang sesuai.

Pada artikel ini kita akan membahas cara ESP32 mengirim data sensor menggunakan MQTT, mulai dari konsep broker, publisher, subscriber, topic, QoS, koneksi WiFi, JSON payload, contoh menggunakan Arduino IDE, hingga integrasi dengan backend seperti Laravel.

Apa Itu MQTT?

MQTT adalah protokol messaging ringan yang dirancang untuk komunikasi antar perangkat, terutama pada lingkungan dengan bandwidth terbatas atau koneksi yang tidak selalu stabil.

MQTT menggunakan model publish/subscribe.

Komponen utamanya:

  • Publisher — perangkat yang mengirim pesan.
  • Subscriber — perangkat atau aplikasi yang menerima pesan.
  • Broker — server yang menerima pesan dari publisher dan meneruskannya kepada subscriber.
  • Topic — alamat atau channel tempat pesan dipublikasikan.

Arsitektur MQTT

Contoh sederhana:

+-------------+
|    ESP32    |
|  Publisher  |
+------+------+
       |
       | Publish
       | sensor/room1
       v
+-------------+
| MQTT Broker |
+------+------+
       |
       | Subscribe
       |
       +------------------+
       |                  |
       v                  v
+-------------+      +-------------+
|   Server    |      |  Dashboard  |
|  Subscriber |      | Subscriber  |
+-------------+      +-------------+

ESP32 tidak perlu mengetahui siapa saja yang menerima data. ESP32 cukup publish data ke topic tertentu.

Broker yang bertugas mendistribusikan pesan kepada subscriber.

Mengapa MQTT Cocok untuk IoT?

MQTT memiliki beberapa karakteristik yang membuatnya menarik untuk IoT:

  • Protokol relatif ringan.
  • Menggunakan model publish/subscribe.
  • Publisher tidak perlu mengetahui subscriber.
  • Mendukung Quality of Service atau QoS.
  • Mendukung koneksi persistent.
  • Dapat digunakan pada jaringan dengan bandwidth terbatas.
  • Mendukung komunikasi dua arah.

MQTT sangat berguna ketika satu data sensor perlu dikonsumsi oleh banyak aplikasi.

HTTP vs MQTT

Jika sebelumnya ESP32 mengirim data menggunakan HTTP:

ESP32
  |
  | POST /api/sensor
  v
Server

Dengan MQTT, alurnya berubah:

ESP32
  |
  | Publish
  v
MQTT Broker
  |
  +----> Backend
  |
  +----> Dashboard
  |
  +----> Monitoring

Publisher tidak perlu melakukan request langsung kepada setiap aplikasi yang membutuhkan data.

Komponen MQTT

Publisher

Publisher adalah client yang mengirim pesan ke topic.

Dalam tutorial ini:

ESP32 = Publisher

Subscriber

Subscriber adalah client yang berlangganan topic tertentu.

Contohnya:

Laravel Worker = Subscriber
Dashboard      = Subscriber
Monitoring     = Subscriber

Broker

Broker adalah pusat komunikasi MQTT.

Contoh broker MQTT yang populer antara lain Mosquitto dan berbagai layanan MQTT cloud.

Topic

Topic digunakan untuk mengelompokkan pesan.

Contoh:

iot/esp32-001/temperature
iot/esp32-001/humidity
iot/esp32-001/status

Atau menggunakan satu topic untuk beberapa data sensor:

iot/esp32-001/sensor

Memahami Topic MQTT

Topic dapat dirancang berdasarkan struktur perangkat dan jenis data.

Contoh:

home/living-room/temperature
home/living-room/humidity
home/bedroom/temperature
home/bedroom/humidity

Dengan struktur seperti ini, subscriber dapat memilih topic tertentu sesuai kebutuhan.

Wildcard Topic

MQTT mendukung wildcard untuk subscription.

Wildcard + digunakan untuk satu level:

home/+/temperature

Topic tersebut dapat cocok dengan:

home/living-room/temperature
home/bedroom/temperature
home/kitchen/temperature

Wildcard # digunakan untuk beberapa level:

home/#

Topic tersebut dapat menerima pesan dari berbagai subtopic di bawah home.

MQTT QoS

MQTT memiliki tiga level Quality of Service:

  • QoS 0 — at most once.
  • QoS 1 — at least once.
  • QoS 2 — exactly once.

Secara sederhana:

QoSKarakteristikOverhead
0Pesan dikirim tanpa jaminan delivery.Rendah
1Pesan setidaknya diterima sekali.Sedang
2Delivery dengan mekanisme exactly once.Lebih tinggi

Untuk data sensor yang dikirim berkala, QoS 0 sering kali cukup. Namun, data penting seperti command atau event tertentu mungkin membutuhkan QoS yang lebih tinggi.

QoS Bukan Jaminan Data Tidak Hilang Selamanya

Penting memahami bahwa QoS bekerja pada mekanisme MQTT delivery. QoS tidak otomatis menyelesaikan semua masalah seperti device mati, database gagal, atau subscriber tidak memiliki mekanisme penyimpanan yang benar.

Reliability sistem IoT tetap membutuhkan desain end-to-end.

Menyiapkan MQTT Broker

Untuk pengujian, kita membutuhkan MQTT broker yang dapat diakses oleh ESP32.

Broker dapat dijalankan:

  • Di komputer lokal.
  • Di Ubuntu Server.
  • Di VPS.
  • Di cloud.
  • Menggunakan MQTT service yang dikelola provider.

Untuk tutorial ini, kita akan menggunakan alamat broker sebagai contoh:

192.168.1.100

Port MQTT standar tanpa TLS umumnya adalah:

1883

Sedangkan MQTT yang menggunakan TLS umumnya menggunakan port:

8883

Port aktual tetap bergantung pada konfigurasi broker.

Menginstal Library MQTT untuk ESP32

Arduino IDE memiliki berbagai library MQTT yang dapat digunakan pada ESP32. Salah satu library yang umum digunakan adalah PubSubClient.

Library tersebut menyediakan API sederhana untuk connect, publish, subscribe, dan menerima message.

Struktur Program ESP32 MQTT

Program dasar akan memiliki alur:

Start
  |
  v
Connect WiFi
  |
  v
Connect MQTT Broker
  |
  v
Read Sensor
  |
  v
Publish JSON
  |
  v
Wait
  |
  +---- Repeat

Menghubungkan ESP32 ke WiFi

Gunakan WiFi.h.

#include <WiFi.h>

const char* ssid = "NAMA_WIFI";
const char* password = "PASSWORD_WIFI";

void setup() {
    Serial.begin(115200);

    WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println();
    Serial.println("WiFi connected");
    Serial.println(WiFi.localIP());
}

void loop() {
}

Menghubungkan ESP32 ke MQTT Broker

Gunakan object PubSubClient.

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

const char* mqttServer = "192.168.1.100";
const int mqttPort = 1883;

WiFiClient espClient;
PubSubClient mqttClient(espClient);

Kemudian konfigurasi server MQTT:

mqttClient.setServer(
    mqttServer,
    mqttPort
);

Connect ke MQTT Broker

Kita dapat membuat function khusus untuk koneksi MQTT.

void reconnectMQTT() {
    while (!mqttClient.connected()) {
        Serial.print("Menghubungkan ke MQTT...");

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

        if (mqttClient.connect(clientId.c_str())) {
            Serial.println("connected");
        } else {
            Serial.print("failed, rc=");
            Serial.println(mqttClient.state());

            delay(5000);
        }
    }
}

Client ID sebaiknya unik agar beberapa ESP32 tidak saling menendang dari broker karena menggunakan ID yang sama.

Publish Data MQTT

Setelah terhubung ke broker, ESP32 dapat melakukan publish.

const char* topic = "iot/esp32-001/sensor";

mqttClient.publish(
    topic,
    "Hello MQTT"
);

Pesan tersebut dikirim ke topic:

iot/esp32-001/sensor

Mengirim Data Sensor dalam JSON

Contoh payload:

{
    "device_id": "ESP32-001",
    "temperature": 28.5,
    "humidity": 72.4
}

Dengan PubSubClient, payload dapat dikirim sebagai string:

String payload = "{";
payload += "\"device_id\":\"ESP32-001\",";
payload += "\"temperature\":28.5,";
payload += "\"humidity\":72.4";
payload += "}";

mqttClient.publish(
    "iot/esp32-001/sensor",
    payload.c_str()
);

Menggunakan ArduinoJson

Untuk payload yang lebih kompleks, ArduinoJson dapat digunakan.

#include <ArduinoJson.h>

JsonDocument doc;

doc["device_id"] = "ESP32-001";
doc["temperature"] = 28.5;
doc["humidity"] = 72.4;

String payload;

serializeJson(doc, payload);

mqttClient.publish(
    "iot/esp32-001/sensor",
    payload.c_str()
);

Program ESP32 MQTT Sederhana

Berikut contoh lengkap untuk mengirim data sensor dummy melalui MQTT.

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

const char* ssid = "NAMA_WIFI";
const char* password = "PASSWORD_WIFI";

const char* mqttServer = "192.168.1.100";
const int mqttPort = 1883;

const char* topic =
    "iot/esp32-001/sensor";

WiFiClient espClient;
PubSubClient mqttClient(espClient);

unsigned long lastPublish = 0;
const unsigned long publishInterval = 10000;

void connectWiFi() {
    WiFi.begin(ssid, password);

    Serial.print("Menghubungkan ke WiFi");

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }

    Serial.println();
    Serial.println("WiFi terhubung");
    Serial.println(WiFi.localIP());
}

void reconnectMQTT() {
    while (!mqttClient.connected()) {
        Serial.print("Menghubungkan ke MQTT...");

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

        if (mqttClient.connect(clientId.c_str())) {
            Serial.println("terhubung");
        } else {
            Serial.print("gagal, rc=");
            Serial.println(mqttClient.state());

            delay(5000);
        }
    }
}

void publishSensor() {
    float temperature =
        25.0 + random(0, 100) / 10.0;

    float humidity =
        60.0 + random(0, 300) / 10.0;

    String payload = "{";
    payload += "\"device_id\":\"ESP32-001\",";
    payload += "\"temperature\":";
    payload += String(temperature, 2);
    payload += ",";
    payload += "\"humidity\":";
    payload += String(humidity, 2);
    payload += "}";

    bool success = mqttClient.publish(
        topic,
        payload.c_str()
    );

    if (success) {
        Serial.println("Data berhasil dikirim:");
        Serial.println(payload);
    } else {
        Serial.println("Gagal mengirim data");
    }
}

void setup() {
    Serial.begin(115200);

    randomSeed(micros());

    connectWiFi();

    mqttClient.setServer(
        mqttServer,
        mqttPort
    );
}

void loop() {
    if (!mqttClient.connected()) {
        reconnectMQTT();
    }

    mqttClient.loop();

    unsigned long currentMillis = millis();

    if (
        currentMillis - lastPublish >=
        publishInterval
    ) {
        lastPublish = currentMillis;

        publishSensor();
    }
}

Mengapa mqttClient.loop() Penting?

Method:

mqttClient.loop();

perlu dipanggil secara berkala untuk membantu library memproses komunikasi MQTT.

Jangan membuat program berhenti terlalu lama sehingga koneksi MQTT tidak mendapatkan kesempatan untuk diproses.

Menggunakan Sensor DHT

Sebagai contoh, kita dapat mengganti data dummy dengan sensor DHT22.

#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);

Inisialisasi sensor:

void setup() {
    Serial.begin(115200);

    dht.begin();

    connectWiFi();

    mqttClient.setServer(
        mqttServer,
        mqttPort
    );
}

Membaca sensor:

float temperature = dht.readTemperature();
float humidity = dht.readHumidity();

if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Gagal membaca sensor");
    return;
}

Mengirim Data Sensor DHT ke MQTT

void publishSensor() {
    float temperature = dht.readTemperature();
    float humidity = dht.readHumidity();

    if (isnan(temperature) || isnan(humidity)) {
        Serial.println("Sensor tidak terbaca");
        return;
    }

    String payload = "{";
    payload += "\"device_id\":\"ESP32-001\",";
    payload += "\"temperature\":";
    payload += String(temperature, 2);
    payload += ",";
    payload += "\"humidity\":";
    payload += String(humidity, 2);
    payload += "}";

    mqttClient.publish(
        topic,
        payload.c_str()
    );

    Serial.println(payload);
}

Subscriber MQTT

Untuk melihat data yang dikirim ESP32, kita membutuhkan subscriber.

Subscriber dapat berupa:

  • MQTT client di komputer.
  • Backend server.
  • Dashboard IoT.
  • Service monitoring.
  • ESP32 lainnya.

Misalnya subscriber melakukan subscribe:

iot/esp32-001/sensor

Ketika ESP32 publish:

iot/esp32-001/sensor

{
    "device_id": "ESP32-001",
    "temperature": 28.5,
    "humidity": 72.4
}

Subscriber akan menerima pesan tersebut.

Menguji MQTT dengan Mosquitto Client

Jika Mosquitto client tersedia pada komputer, subscriber dapat dijalankan menggunakan:

mosquitto_sub \
  -h 192.168.1.100 \
  -p 1883 \
  -t "iot/esp32-001/sensor"

Kemudian ESP32 melakukan publish.

Terminal subscriber akan menerima:

{"device_id":"ESP32-001","temperature":28.50,"humidity":72.40}

Menguji Publish dari Command Line

Kita juga dapat menguji broker tanpa ESP32.

mosquitto_pub \
  -h 192.168.1.100 \
  -p 1883 \
  -t "iot/test" \
  -m "Hello MQTT"

Jika subscriber sudah subscribe ke topic tersebut, pesan akan diterima.

Alur Publish dan Subscribe

             Publish
ESP32 ----------------------+
                             |
                             v
                      +-------------+
                      | MQTT Broker |
                      +------+------+
                             |
                 +-----------+-----------+
                 |                       |
                 v                       v
             Subscriber A           Subscriber B
             Backend               Dashboard

Inilah perbedaan utama MQTT dibandingkan pola request/response HTTP.

MQTT Retained Message

MQTT mendukung retained message. Dengan retained message, broker dapat menyimpan pesan terakhir pada sebuah topic dan memberikan pesan tersebut kepada subscriber baru sesuai konfigurasi broker dan subscription.

Contoh:

mqttClient.publish(
    "iot/esp32-001/status",
    "online",
    true
);

Parameter true pada contoh tersebut meminta message menjadi retained.

Fitur ini berguna untuk data seperti:

  • Status device.
  • Konfigurasi terakhir.
  • State perangkat.

Namun retained message perlu digunakan dengan desain topic yang jelas karena broker menyimpan state terakhir tersebut.

Last Will and Testament

MQTT juga mendukung mekanisme Last Will and Testament atau LWT.

Konsepnya memungkinkan broker mempublikasikan pesan tertentu jika client terputus secara tidak normal.

Contoh konsep:

ESP32
  |
  | Connected
  v
status = online

ESP32 mati / koneksi abnormal
  |
  v
Broker
  |
  v
status = offline

Fitur ini sangat berguna untuk monitoring status device.

Contoh Konfigurasi LWT

Library MQTT yang digunakan harus mendukung parameter LWT pada proses connect.

mqttClient.connect(
    clientId.c_str(),
    "iot/esp32-001/status",
    1,
    true,
    "offline"
);

Setelah berhasil terhubung, device dapat mengirim status online:

mqttClient.publish(
    "iot/esp32-001/status",
    "online",
    true
);

Dengan desain seperti ini, dashboard dapat memonitor status device.

Authentication MQTT

Broker production sebaiknya tidak dibiarkan menerima koneksi anonymous tanpa alasan yang jelas.

ESP32 dapat melakukan koneksi menggunakan username dan password jika broker dikonfigurasi untuk authentication.

const char* mqttUser = "esp32";
const char* mqttPassword = "PASSWORD_MQTT";

mqttClient.connect(
    clientId.c_str(),
    mqttUser,
    mqttPassword
);

Credential harus dikelola dengan hati-hati dan tidak sebaiknya dipublikasikan di source code repository.

MQTT dengan TLS

Untuk komunikasi production melalui jaringan yang tidak sepenuhnya terpercaya, gunakan TLS.

Arsitektur sederhananya:

ESP32
  |
  | MQTT over TLS
  |
  | Encrypted
  v
MQTT Broker

ESP32 dapat menggunakan WiFiClientSecure sebagai transport untuk MQTT library yang mendukungnya.

WiFiClientSecure secureClient;

PubSubClient mqttClient(secureClient);

Konfigurasi TLS perlu menggunakan certificate atau trust configuration yang sesuai. Hindari menonaktifkan verifikasi sertifikat untuk deployment production.

Topic Design untuk Banyak Device

Ketika hanya memiliki satu ESP32, topic berikut mungkin sudah cukup:

sensor

Namun, jika memiliki banyak device, gunakan struktur yang konsisten.

Contoh:

devices/esp32-001/sensor
devices/esp32-002/sensor
devices/esp32-003/sensor

Untuk jenis data berbeda:

devices/esp32-001/telemetry
devices/esp32-001/status
devices/esp32-001/command

Struktur seperti ini memudahkan subscriber menentukan data mana yang ingin diterima.

Telemetry dan Command

Dalam project IoT, biasanya terdapat dua arah komunikasi.

ESP32 mengirim telemetry:

devices/esp32-001/telemetry

Server mengirim command:

devices/esp32-001/command

Sehingga arsitekturnya menjadi:

                 MQTT Broker
                 /         \
                /           \
               v             v
            ESP32          Backend
               ^             |
               |             |
               +-------------+
                  Command

ESP32 dapat menjadi publisher sekaligus subscriber.

ESP32 sebagai Publisher dan Subscriber

ESP32 dapat publish data sensor:

devices/esp32-001/telemetry

dan subscribe command:

devices/esp32-001/command

Contohnya server mengirim:

{
    "relay": true
}

ESP32 menerima pesan tersebut dan mengubah GPIO relay.

Callback MQTT

Pada PubSubClient, callback dapat digunakan untuk menangani message yang diterima.

void callback(
    char* topic,
    byte* payload,
    unsigned int length
) {
    Serial.print("Topic: ");
    Serial.println(topic);

    Serial.print("Message: ");

    for (unsigned int i = 0; i < length; i++) {
        Serial.print(
            (char)payload[i]
        );
    }

    Serial.println();
}

Kemudian callback didaftarkan:

mqttClient.setCallback(callback);

Subscribe Command

Setelah koneksi MQTT berhasil:

mqttClient.subscribe(
    "devices/esp32-001/command"
);

Ketika server mengirim command, callback akan dipanggil.

Mengontrol Relay dengan MQTT

Contoh sederhana:

void callback(
    char* topic,
    byte* payload,
    unsigned int length
) {
    String message;

    for (unsigned int i = 0; i < length; i++) {
        message += (char)payload[i];
    }

    if (message == "ON") {
        digitalWrite(RELAY_PIN, HIGH);
    }

    if (message == "OFF") {
        digitalWrite(RELAY_PIN, LOW);
    }
}

Server kemudian dapat publish:

mosquitto_pub \
  -h 192.168.1.100 \
  -t "devices/esp32-001/command" \
  -m "ON"

ESP32 akan menerima command tersebut dan mengubah kondisi relay.

Integrasi MQTT dengan Laravel

Laravel dapat berperan sebagai backend aplikasi, sedangkan MQTT broker menjadi message broker untuk komunikasi dengan device.

Arsitektur:

ESP32
  |
  | MQTT
  v
MQTT Broker
  |
  | Subscriber
  v
Laravel Worker
  |
  +----> Database
  |
  +----> Dashboard
  |
  +----> Alert

Dalam arsitektur ini, Laravel tidak harus menerima koneksi langsung dari setiap ESP32 melalui HTTP.

Menyimpan Data MQTT ke Database

Worker atau service subscriber dapat menerima payload:

{
    "device_id": "ESP32-001",
    "temperature": 28.5,
    "humidity": 72.4
}

Kemudian data disimpan ke database:

SensorReading::create([
    'device_id' => $payload['device_id'],
    'temperature' => $payload['temperature'],
    'humidity' => $payload['humidity'],
]);

Detail implementasi MQTT subscriber di Laravel bergantung pada library MQTT dan arsitektur worker yang digunakan.

MQTT Tidak Menggantikan Database

MQTT broker berfungsi sebagai sistem messaging, bukan pengganti database aplikasi.

Secara sederhana:

MQTT Broker
    |
    | Message delivery
    v
Application
    |
    | Persist
    v
Database

Jika data sensor harus digunakan untuk histori, reporting, atau analitik, backend biasanya perlu menyimpannya ke storage yang sesuai.

Data Sensor Real-Time

MQTT sangat cocok untuk data yang perlu diteruskan ke beberapa subscriber secara near real-time.

Contohnya:

ESP32
  |
  | temperature = 29.2
  v
MQTT Broker
  |
  +----> Dashboard
  |
  +----> Alert Service
  |
  +----> Database
  |
  +----> Analytics

Satu publish dapat digunakan oleh beberapa consumer tanpa ESP32 harus mengirim request terpisah kepada masing-masing service.

Mencegah Data Sensor Membanjiri Broker

Walaupun MQTT ringan, jumlah message tetap harus diperhitungkan.

Misalnya:

10.000 device
x
1 message / second
=
10.000 message / second

Broker, network, subscriber, database, dan monitoring harus mampu menangani traffic tersebut.

Karena itu, frekuensi sensor harus dirancang berdasarkan kebutuhan.

Batching Data Sensor

Jika data tidak membutuhkan real-time penuh, ESP32 dapat menggabungkan beberapa reading.

{
    "device_id": "ESP32-001",
    "readings": [
        {
            "temperature": 28.1,
            "humidity": 70.2
        },
        {
            "temperature": 28.3,
            "humidity": 71.0
        },
        {
            "temperature": 28.5,
            "humidity": 72.4
        }
    ]
}

Dengan demikian jumlah publish dapat dikurangi.

Offline dan Reconnect

Perangkat IoT harus menganggap koneksi jaringan dapat terputus.

Alurnya:

ESP32
  |
  v
WiFi Connected
  |
  v
MQTT Connected
  |
  X Connection Lost
  |
  v
Reconnect WiFi
  |
  v
Reconnect MQTT
  |
  v
Publish kembali

Program MQTT sebaiknya memiliki mekanisme reconnect yang tidak melakukan blocking terlalu lama.

Jangan Retry Tanpa Batas Secara Agresif

Jika broker sedang down dan ribuan ESP32 mencoba reconnect setiap beberapa milidetik, kondisi tersebut dapat memperburuk masalah.

Gunakan interval retry yang wajar dan, pada sistem besar, pertimbangkan exponential backoff atau strategi reconnect yang terkontrol.

Device ID Harus Unik

Setiap ESP32 sebaiknya memiliki identifier unik.

Contohnya:

ESP32-001
ESP32-002
ESP32-003

Jangan menggunakan client ID MQTT yang sama untuk semua device.

Contoh client ID yang dibentuk dari hardware identifier:

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

Metode pembentukan ID perlu disesuaikan dengan kebutuhan dan varian ESP32 yang digunakan.

Timestamp Data

Payload sensor sebaiknya memiliki informasi waktu jika server membutuhkan histori yang akurat.

{
    "device_id": "ESP32-001",
    "temperature": 28.5,
    "humidity": 72.4,
    "timestamp": "2026-09-04T10:15:30Z"
}

Alternatif yang lebih sederhana adalah server memberikan timestamp ketika message diproses.

Sequence Number

Untuk mendeteksi data duplicate atau missing message, device dapat mengirim sequence number.

{
    "device_id": "ESP32-001",
    "sequence": 1025,
    "temperature": 28.5
}

Server dapat menggunakan sequence tersebut untuk membantu mendeteksi kondisi tertentu.

Retained Message untuk Status Device

Topic status dapat menggunakan retained message.

devices/esp32-001/status

Payload:

online

Dengan LWT, broker dapat mengubah state menjadi:

offline

Dashboard kemudian dapat menampilkan:

ESP32-001 -> Online
ESP32-002 -> Offline
ESP32-003 -> Online

Keamanan MQTT

MQTT broker harus diperlakukan sebagai infrastructure penting.

Untuk deployment production, pertimbangkan:

  • Username dan password.
  • TLS.
  • Access Control List atau ACL.
  • Topic permission.
  • Unique credential per device jika diperlukan.
  • Rotasi credential.
  • Firewall.
  • Monitoring koneksi.

ACL MQTT

ACL dapat membatasi topic yang boleh digunakan oleh device.

Misalnya ESP32-001 hanya boleh publish ke:

devices/esp32-001/telemetry
devices/esp32-001/status

dan hanya boleh subscribe:

devices/esp32-001/command

Dengan demikian, device tidak bebas mengakses topic device lainnya.

Jangan Menggunakan Satu Credential untuk Semua Device

Untuk prototype, satu credential mungkin cukup. Namun pada production, credential per device lebih mudah dikelola jika salah satu device harus dicabut aksesnya.

ESP32-001 -> Credential A
ESP32-002 -> Credential B
ESP32-003 -> Credential C

Jika ESP32-002 bermasalah, credential tersebut dapat dinonaktifkan tanpa harus mengganti credential semua device.

Monitoring MQTT

Monitoring broker sebaiknya mencakup:

  • Jumlah connected clients.
  • Jumlah publish message.
  • Jumlah subscribe.
  • Message rate.
  • Connection errors.
  • Authentication failures.
  • Broker CPU dan memory.
  • Network traffic.

Monitoring menjadi semakin penting ketika jumlah device meningkat.

Common Mistakes ESP32 MQTT

1. Client ID Sama

Jika banyak ESP32 menggunakan client ID yang sama, broker dapat memutus koneksi client sebelumnya ketika client baru masuk.

2. Tidak Memanggil mqttClient.loop()

Koneksi MQTT dapat bermasalah jika library tidak mendapatkan kesempatan untuk memproses komunikasi secara berkala.

3. Retry Terlalu Agresif

Reconnect tanpa jeda dapat membebani broker dan jaringan.

4. Topic Tidak Terstruktur

Topic seperti sensor dapat menjadi sulit dikelola ketika device sudah banyak.

5. Broker Tanpa Authentication

Broker production yang terbuka tanpa access control dapat menjadi risiko keamanan.

6. Tidak Memikirkan Duplicate Message

QoS tertentu dan mekanisme retry dapat menyebabkan message diterima lebih dari sekali. Consumer harus dirancang sesuai kebutuhan.

7. Mengirim Data Terlalu Sering

Sensor tidak selalu perlu dipublish setiap beberapa milidetik.

Best Practice ESP32 MQTT

  • Gunakan client ID unik untuk setiap device.
  • Gunakan struktur topic yang konsisten.
  • Pisahkan topic telemetry, status, dan command.
  • Gunakan QoS sesuai kebutuhan.
  • Gunakan retained message untuk state yang memang membutuhkan last known value.
  • Gunakan LWT untuk status device jika diperlukan.
  • Gunakan authentication.
  • Gunakan TLS untuk komunikasi production yang membutuhkan keamanan transport.
  • Terapkan ACL pada broker.
  • Gunakan reconnect yang terkontrol.
  • Hindari blocking loop yang terlalu lama.
  • Validasi payload pada sisi subscriber.
  • Monitor broker dan device.
  • Rancang strategi offline jika data penting tidak boleh hilang.

Contoh Struktur Topic IoT

devices/
|
+-- esp32-001/
|   |
|   +-- telemetry
|   +-- status
|   +-- command
|
+-- esp32-002/
    |
    +-- telemetry
    +-- status
    +-- command

Struktur ini cukup fleksibel untuk dikembangkan menjadi sistem dengan banyak device.

Contoh Alur Lengkap

+----------------+
| Sensor DHT22   |
+-------+--------+
        |
        v
+----------------+
|     ESP32      |
| MQTT Publisher |
+-------+--------+
        |
        | WiFi
        |
        | Publish
        v
+----------------+
|  MQTT Broker   |
+-------+--------+
        |
        +------------------+
        |                  |
        v                  v
+---------------+   +---------------+
| Laravel       |   | Dashboard     |
| Subscriber    |   | Subscriber    |
+-------+-------+   +---------------+
        |
        v
+---------------+
|   Database    |
+---------------+

HTTP atau MQTT?

Pemilihan protokol tergantung kebutuhan project.

KebutuhanHTTPMQTT
REST APISangat cocokTidak berbasis REST
Publish/SubscribeTidak nativeSangat cocok
Komunikasi device banyakDapat digunakanSering lebih sesuai
Request sederhanaSangat mudahMembutuhkan broker
Real-time messagingPerlu desain tambahanCocok
Telemetry IoTBisaSangat umum digunakan

Kapan Sebaiknya Menggunakan MQTT?

MQTT cocok ketika:

  • Banyak device perlu mengirim telemetry.
  • Satu data perlu diterima oleh banyak subscriber.
  • Membutuhkan komunikasi dua arah antara device dan server.
  • Bandwidth terbatas.
  • Membutuhkan model event-driven.
  • Membutuhkan status device secara near real-time.

Kapan HTTP Lebih Sederhana?

HTTP dapat menjadi pilihan yang lebih praktis ketika:

  • Project hanya memiliki sedikit device.
  • Data dikirim secara periodik dengan frekuensi rendah.
  • Backend sudah memiliki REST API.
  • Tidak membutuhkan publish/subscribe.
  • Infrastruktur MQTT belum diperlukan.

Checklist Project ESP32 MQTT

  • ESP32 dapat terhubung ke WiFi.
  • ESP32 dapat terhubung ke MQTT broker.
  • Client ID setiap device unik.
  • Topic memiliki struktur yang jelas.
  • Data sensor dikirim dalam format yang konsisten.
  • Subscriber dapat menerima data.
  • Reconnect ketika koneksi terputus sudah ditangani.
  • QoS dipilih sesuai kebutuhan.
  • Authentication broker sudah dikonfigurasi.
  • TLS digunakan jika dibutuhkan.
  • ACL membatasi akses topic.
  • Message rate sudah diperhitungkan.
  • Database memiliki strategi penyimpanan data sensor.
  • Ada monitoring untuk device dan broker.

Ringkasan

KomponenFungsi
ESP32MQTT client dan publisher/subscriber.
MQTT BrokerMenerima dan meneruskan message.
PublisherMengirim message ke topic.
SubscriberMenerima message dari topic.
TopicChannel atau alamat logical message.
QoSMenentukan level delivery message.
Retained MessageMenyimpan last known message pada topic sesuai konfigurasi broker.
LWTMembantu memberitahukan kondisi disconnect abnormal.
TLSMengamankan transport MQTT.

Kesimpulan

ESP32 mengirim data sensor menggunakan MQTT merupakan pola yang sangat berguna untuk membangun sistem IoT. ESP32 dapat bertindak sebagai publisher yang membaca sensor kemudian mengirim data ke MQTT broker melalui topic tertentu.

Backend, dashboard, atau service lainnya dapat menjadi subscriber dan menerima data tanpa ESP32 harus mengetahui siapa yang menggunakannya.

Konsep publish/subscribe membuat MQTT sangat menarik untuk sistem yang memiliki banyak device atau membutuhkan komunikasi dua arah. Selain telemetry, ESP32 juga dapat subscribe command untuk mengontrol relay, lampu, motor, atau perangkat lainnya.

Untuk project sederhana, HTTP REST API masih dapat menjadi pilihan yang lebih mudah. Namun, ketika kebutuhan mulai berkembang menjadi banyak device, komunikasi event-driven, telemetry near real-time, dan komunikasi dua arah, MQTT dapat menjadi fondasi komunikasi IoT yang lebih sesuai.

Untuk deployment production, jangan berhenti pada fungsi publish saja. Perhatikan juga authentication, TLS, ACL, unique client ID, topic design, QoS, reconnect, retained message, LWT, monitoring, dan strategi penyimpanan data agar sistem IoT tetap aman dan dapat diandalkan.