Pendahuluan

Di artikel sebelumnya kita sudah membuat Web Server ESP32 (#6) untuk monitoring sensor DHT22 lewat browser. Itu bagus untuk akses lokal, tapi di dunia IoT nyata, banyak perangkat perlu mengirim data ke satu sistem pusat — tanpa saling tahu IP masing-masing.

Di sinilah protokol MQTT (Message Queuing Telemetry Transport) berperan. MQTT adalah standar de facto untuk komunikasi IoT: ringan, cepat, dan cocok untuk ESP32 yang mengirim data sensor secara berkala.

Dalam tutorial ini, kamu akan belajar konsep dasar MQTT dan membuat ESP32 mem-publish data suhu & kelembaban DHT22 (#5) ke broker MQTT publik.

Apa itu MQTT?

MQTT menggunakan pola publish/subscribe (pub/sub):

  • Publisher — perangkat yang mengirim data (ESP32 kamu)
  • Subscriber — perangkat/aplikasi yang menerima data (HP, server, Home Assistant (#21))
  • Broker — server perantara yang meneruskan pesan berdasarkan topic
  • Topic — "alamat" pesan, misalnya kodingindonesia/esp32/dht22

ESP32 tidak perlu tahu siapa yang membaca datanya. Cukup publish ke topic tertentu — broker yang mengurus sisanya.

DHT22 · GPIO 4 suhu · kelembaban ESP32 publish PubSubClient Mosquitto · :1883 test.mosquitto.org PUB MQTT Explorer subscribe · laptop Subscriber lain HA · Python · Node-RED SUB topic · kodingindonesia/esp32/dht22
ESP32 publish JSON DHT22 → broker → banyak subscriber. Pola kebalikan kontrol relay (#8) (subscribe perintah).

Analogi sederhana: MQTT seperti grup WhatsApp. ESP32 mengirim pesan ke grup (topic), siapa saja yang ada di grup (subscriber) bisa membaca — tanpa perlu chat langsung ke setiap orang.

MQTT vs HTTP — Kapan Pakai Apa?

AspekHTTPMQTT
ModelRequest–ResponsePublish–Subscribe
Ukuran headerLebih besarSangat ringan
KoneksiBuka–tutup tiap requestPersistent (tetap terhubung)
Cocok untukAPI web, upload fileSensor IoT, telemetry real-time

Perbandingan lebih dalam: REST API vs MQTT (#20).

Yang Kamu Butuhkan

  • ESP32 DevKit + sensor DHT22 (wiring sama seperti tutorial DHT22 (#5))
  • Arduino IDE dengan board ESP32 terinstall
  • Koneksi WiFi
  • Aplikasi subscriber MQTT (opsional): MQTT Explorer di laptop, atau app MQTT Client di HP

Prasyarat: Sudah paham koneksi WiFi ESP32 dan cara membaca sensor DHT22. Jika belum, baca Menghubungkan ESP32 ke WiFi (#4) dan Membaca Sensor DHT22 (#5). Disarankan juga sudah membaca Web Server ESP32 + DHT22 (#6).

Wiring DHT22 Ringkas

Pin sama dengan artikel DHT22 (#5) — DATA di GPIO 4:

ESP32 DevKit 3.3V GND GPIO 4 DATA DHT22 1-wire · 3.3V VCC GND DATA 3.3V→VCC · GND→GND · GPIO4→DATA · pull-up 10kΩ DATA→3.3V Modul breakout biasanya sudah punya pull-up internal
Wiring pin-ke-pin DHT22 — konsisten dengan DHT22 (#5) dan proyek gabungan (#9).

Install Library

Install library berikut lewat Arduino IDE → Sketch → Include Library → Manage Libraries:

  1. PubSubClient — oleh Nick O'Leary (client MQTT untuk Arduino/ESP32)
  2. DHT sensor library — oleh Adafruit (+ Adafruit Unified Sensor)

Broker MQTT untuk Latihan — Eclipse Mosquitto

Untuk tutorial ini kita memakai test server resmi dari proyek Eclipse Mosquitto — broker MQTT open source yang populer di dunia IoT:

  • Host: test.mosquitto.org
  • Port: 1883 (MQTT plain, tanpa TLS)
  • Autentikasi: tidak perlu username/password

Penting — broker bukan website: test.mosquitto.org adalah server MQTT, bukan halaman web. Jika kamu ketik alamat itu di browser Chrome/Firefox, akan muncul error — itu normal. MQTT berjalan di port 1883, bukan port 80/443. ESP32 dan MQTT Explorer yang terhubung ke broker, bukan browser biasa.

Keamanan: Broker publik hanya untuk belajar dan uji coba. Jangan kirim data sensitif. Untuk production, pasang broker Mosquitto pribadi (#16) di Raspberry Pi/VPS dengan autentikasi, lalu amankan dengan MQTT over TLS (#17).

Kode Program: ESP32 + DHT22 + MQTT

Ganti placeholder GANTI_SSID_WIFI / GANTI_PASSWORD_WIFI, lalu upload. Untuk produksi tanpa hardcode, lihat NVS + WiFiManager (#12).

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

// ── WiFi ──────────────────────────────────────────────
const char* ssid     = "GANTI_SSID_WIFI";
const char* password = "GANTI_PASSWORD_WIFI";

// ── MQTT Broker ───────────────────────────────────────
const char* mqttServer = "test.mosquitto.org";
const int   mqttPort   = 1883;
const char* mqttTopic  = "kodingindonesia/esp32/dht22";

// ── DHT22 ───────────────────────────────────────────
#define DHT_PIN  4
#define DHT_TYPE DHT22
DHT dht(DHT_PIN, DHT_TYPE);

WiFiClient espClient;
PubSubClient mqttClient(espClient);

unsigned long waktuKirimTerakhir = 0;
const unsigned long intervalKirim = 5000; // kirim setiap 5 detik

void koneksiWiFi() {
  Serial.print("Menghubungkan ke WiFi");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWiFi terhubung!");
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

void koneksiMQTT() {
  mqttClient.setServer(mqttServer, mqttPort);

  while (!mqttClient.connected()) {
    Serial.print("Menghubungkan ke MQTT broker...");
    // Client ID unik agar tidak bentrok dengan perangkat lain
    String clientId = "ESP32-Kindo-" + String(random(0xffff), HEX);

    if (mqttClient.connect(clientId.c_str())) {
      Serial.println(" terhubung!");
    } else {
      Serial.print(" gagal, rc=");
      Serial.print(mqttClient.state());
      Serial.println(" — coba lagi dalam 5 detik");
      delay(5000);
    }
  }
}

void kirimDataSensor() {
  float suhu       = dht.readTemperature();
  float kelembaban = dht.readHumidity();

  if (isnan(suhu) || isnan(kelembaban)) {
    Serial.println("Gagal membaca DHT22, lewati pengiriman.");
    return;
  }

  // Payload JSON
  String payload = "{";
  payload += "\"suhu\":" + String(suhu, 2) + ",";
  payload += "\"kelembaban\":" + String(kelembaban, 2) + ",";
  payload += "\"device\":\"ESP32-001\"";
  payload += "}";

  if (mqttClient.publish(mqttTopic, payload.c_str())) {
    Serial.println("Data terkirim: " + payload);
  } else {
    Serial.println("Gagal publish ke MQTT!");
  }
}

void setup() {
  Serial.begin(115200);
  randomSeed(micros());
  dht.begin();
  koneksiWiFi();
  koneksiMQTT();
}

void loop() {
  // Jaga koneksi MQTT tetap hidup
  if (!mqttClient.connected()) {
    koneksiMQTT();
  }
  mqttClient.loop();

  // Kirim data sensor secara berkala
  if (millis() - waktuKirimTerakhir >= intervalKirim) {
    waktuKirimTerakhir = millis();
    kirimDataSensor();
  }
}

Uji Coba: Subscribe ke Topic yang Sama

Setelah ESP32 berjalan, buka Serial Monitor (115200 baud). Kamu harus melihat log Data terkirim: {...} setiap 5 detik.

Sekarang subscribe ke topic yang sama untuk melihat data masuk:

Opsi 1 — MQTT Explorer (Laptop, disarankan)

  1. Download MQTT Explorer
  2. Buat koneksi baru: Host test.mosquitto.org, Port 1883
  3. Connect → cari topic kodingindonesia/esp32/dht22
  4. Kamu akan melihat JSON suhu & kelembaban update setiap 5 detik

Opsi 2 — mosquitto_sub (Terminal)

mosquitto_sub -h test.mosquitto.org -t "kodingindonesia/esp32/dht22" -v

Perintah mosquitto_sub adalah tool CLI dari paket Mosquitto — tersedia di Linux, Mac, dan Windows setelah install Mosquitto.

Memahami Struktur Topic

Topic MQTT menggunakan hierarki seperti folder:

kodingindonesia/esp32/dht22
└── organisasi / perangkat / jenis-data

Best practice penamaan topic:

  • Gunakan huruf kecil dan slash / sebagai pemisah
  • Jangan mulai dengan $ — reserved untuk sistem broker
  • Gunakan wildcard saat subscribe: kodingindonesia/# (semua sub-topic)

Di proyek gabungan (#9) topic sensor menjadi .../dht22/data (JSON) agar lebih terstruktur — pola yang sama, subtopic lebih rapi.

QoS (Quality of Service)

MQTT punya 3 level QoS yang menentukan jaminan pengiriman:

  • QoS 0 — kirim sekali, tanpa konfirmasi (paling ringan, default PubSubClient)
  • QoS 1 — minimal sekali sampai (ada ACK)
  • QoS 2 — tepat sekali sampai (paling andal, paling berat)

Untuk data sensor suhu yang dikirim tiap 5 detik, QoS 0 sudah cukup — jika satu paket hilang, paket berikutnya segera menyusul. Detail LWT & retained: MQTT TLS / QoS / LWT (#17).

Tips & Troubleshooting

  • rc=-2 saat connect: Broker tidak terjangkau. Cek koneksi internet WiFi.
  • rc=4 (bad credentials): Broker butuh username/password — test.mosquitto.org port 1883 tidak perlu auth.
  • Broker tidak bisa dibuka di browser: Normal. Pakai MQTT Explorer atau ESP32, bukan Chrome.
  • Data tidak muncul di subscriber: Pastikan topic sama persis, case-sensitive.
  • ESP32 reconnect terus: Client ID bentrok — kode di atas sudah pakai ID random.
  • Nilai suhu NaN: Cek wiring DHT22 dan resistor pull-up 10kΩ.
  • PubSubClient buffer kecil: Jika payload panjang, tambahkan mqttClient.setBufferSize(512); di setup().

Gabungkan dengan Web Server (Artikel Sebelumnya)

MQTT dan Web Server (#6) bisa jalan bersamaan di ESP32:

  • Web Server → monitoring lokal via browser di rumah
  • MQTT → kirim data ke cloud/dashboard/Home Assistant (#21)

Keduanya komplementer — bukan pengganti satu sama lain. Capstone dual-channel: Dashboard Web + MQTT (#10).

Langkah Selanjutnya

Pro tip: Ubah topic menjadi unik untuk kamu, misalnya kodingindonesia/anton/esp32/dht22, agar tidak bentrok dengan peserta tutorial lain yang memakai topic yang sama di broker publik.