Pendahuluan
Dari artikel-artikel sebelumnya kita sudah belajar:
- Membaca sensor DHT22 (tutorial DHT22 (#5))
- Publish data suhu ke MQTT (artikel MQTT (#7))
- Subscribe perintah ON/OFF untuk relay lampu (artikel relay (#8))
Kali ini kita menggabungkan keduanya dalam satu sketch — pola yang dipakai di smart home nyata: ESP32 mengirim data sensor sekaligus menerima perintah kontrol dari broker yang sama.
Hasil akhirnya: kamu bisa lihat suhu di MQTT Explorer dan nyalakan/matikan lampu dari HP, tanpa upload ulang kode yang berbeda.
Yang Kamu Butuhkan
- ESP32 DevKit + kabel jumper
- Sensor DHT22 + resistor pull-up 10kΩ
- Modul relay 1 channel (5V)
- Lampu kecil untuk latihan (LED/soket aman)
- Library: DHT sensor library, PubSubClient, ArduinoJson (v6 atau v7)
- MQTT Explorer
Keamanan listrik: Untuk latihan gunakan lampu LED kecil atau lampu desk aman. Jangan menyentuh kabel AC 220V tanpa pengalaman — sama seperti artikel relay (#8).
Prasyarat: Sudah paham dasar MQTT, wiring DHT22, dan modul relay. Baca Membaca Sensor DHT22 (#5), MQTT ESP32 (#7), dan Kontrol Lampu Relay (#8) jika belum.
Topologi MQTT Proyek Ini
Kita pakai broker publik Eclipse Mosquitto test.mosquitto.org:1883 (sama seperti artikel sebelumnya):
| Arah | Topic | Isi pesan |
|---|---|---|
| ESP32 → Broker (publish) | kodingindonesia/esp32/dht22/data | JSON: {"suhu":28.5,"kelembaban":65.2} |
| Broker → ESP32 (subscribe) | kodingindonesia/esp32/lampu/kontrol | ON atau OFF |
Catatan: Di artikel MQTT (#7) topic sensor adalah kodingindonesia/esp32/dht22 (payload teks). Di proyek gabungan kita pakai subtopic .../dht22/data + JSON agar lebih terstruktur. Topic kontrol relay sama dengan artikel relay (#8).
Broker bukan website —
test.mosquitto.orgtidak dibuka di browser. Gunakan ESP32 atau MQTT Explorer.
Pro tip: Ganti segmen topic dengan nama unik, misalnya
kodingindonesia/anton/esp32/..., agar tidak bentrok dengan peserta tutorial lain. Jangan kontrol perangkat produksi lewat broker publik tanpa autentikasi.
Wiring Ringkas
Pin konsisten dengan DHT22 (#5) dan relay (#8):
- DHT22 DATA → GPIO 4 (+ pull-up 10kΩ ke 3.3V)
- DHT22 VCC → 3.3V · GND → GND
- Relay IN → GPIO 26 · VCC → 5V · GND → GND
Kode Lengkap: Publish Suhu + Subscribe Relay
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>
#include <ArduinoJson.h>
const char* ssid = "GANTI_SSID_WIFI";
const char* password = "GANTI_PASSWORD_WIFI";
const char* mqttServer = "test.mosquitto.org";
const int mqttPort = 1883;
const char* topicSensor = "kodingindonesia/esp32/dht22/data";
const char* topicKontrol = "kodingindonesia/esp32/lampu/kontrol";
#define DHT_PIN 4
#define DHT_TYPE DHT22
#define RELAY_PIN 26
const bool RELAY_ON = LOW; // sesuaikan jika modul active HIGH
const bool RELAY_OFF = HIGH;
DHT dht(DHT_PIN, DHT_TYPE);
WiFiClient espClient;
PubSubClient mqttClient(espClient);
bool lampuMenyala = false;
unsigned long terakhirPublish = 0;
const unsigned long intervalPublish = 10000; // 10 detik
void setLampu(bool nyala) {
lampuMenyala = nyala;
digitalWrite(RELAY_PIN, nyala ? RELAY_ON : RELAY_OFF);
Serial.println(nyala ? "Lampu: ON" : "Lampu: OFF");
}
void callbackMQTT(char* topic, byte* payload, unsigned int length) {
String pesan;
for (unsigned int i = 0; i < length; i++) {
pesan += (char)payload[i];
}
pesan.trim();
pesan.toUpperCase();
Serial.print("Perintah di ");
Serial.print(topic);
Serial.print(": ");
Serial.println(pesan);
if (pesan == "ON") {
setLampu(true);
} else if (pesan == "OFF") {
setLampu(false);
}
}
void koneksiWiFi() {
Serial.print("Menghubungkan ke WiFi");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi terhubung!");
}
void koneksiMQTT() {
mqttClient.setServer(mqttServer, mqttPort);
mqttClient.setCallback(callbackMQTT);
mqttClient.setBufferSize(512);
while (!mqttClient.connected()) {
Serial.print("MQTT connect...");
String clientId = "ESP32-Combo-" + String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str())) {
Serial.println(" OK");
mqttClient.subscribe(topicKontrol);
Serial.print("Subscribe: ");
Serial.println(topicKontrol);
} else {
Serial.print(" gagal rc=");
Serial.println(mqttClient.state());
delay(5000);
}
}
}
void publishSensor() {
float suhu = dht.readTemperature();
float kelembaban = dht.readHumidity();
if (isnan(suhu) || isnan(kelembaban)) {
Serial.println("Gagal baca DHT22");
return;
}
StaticJsonDocument<128> doc;
doc["suhu"] = round(suhu * 10) / 10.0;
doc["kelembaban"] = round(kelembaban * 10) / 10.0;
char buffer[128];
serializeJson(doc, buffer);
if (mqttClient.publish(topicSensor, buffer)) {
Serial.print("Publish ");
Serial.print(topicSensor);
Serial.print(": ");
Serial.println(buffer);
} else {
Serial.println("Publish gagal");
}
// Bonus: matikan lampu otomatis jika suhu > 30°C
if (suhu > 30.0 && lampuMenyala) {
Serial.println("Suhu tinggi — lampu dimatikan otomatis");
setLampu(false);
}
}
void setup() {
Serial.begin(115200);
randomSeed(micros());
pinMode(RELAY_PIN, OUTPUT);
setLampu(false);
dht.begin();
koneksiWiFi();
koneksiMQTT();
delay(2000); // stabilkan DHT22 sebelum baca pertama
}
void loop() {
if (WiFi.status() != WL_CONNECTED) {
koneksiWiFi();
}
if (!mqttClient.connected()) {
koneksiMQTT();
}
mqttClient.loop();
unsigned long sekarang = millis();
if (sekarang - terakhirPublish >= intervalPublish) {
terakhirPublish = sekarang;
publishSensor();
}
}
Library ArduinoJson: Install via Library Manager — cari ArduinoJson by Benoit Blanchon. Kode di bawah memakai sintaks v6 (
StaticJsonDocument). Jika pakai v7, ganti denganJsonDocument doc;— lihat dokumentasi ArduinoJson.
Uji Coba
- Upload kode, buka Serial Monitor (115200 baud)
- Pastikan muncul log
Publish kodingindonesia/esp32/dht22/data: {"suhu":...}setiap 10 detik - Buka MQTT Explorer → connect ke
test.mosquitto.org:1883 - Lihat topic
kodingindonesia/esp32/dht22/data— payload JSON suhu & kelembaban - Publish ke
kodingindonesia/esp32/lampu/kontrolpesanON/OFF→ relay bereaksi - Tiup panas ke DHT22 (atau pegang sensor) — jika suhu > 30°C dan lampu nyala, lampu mati otomatis
Alternatif: mosquitto_sub / mosquitto_pub (Terminal)
# Lihat data sensor (subscribe)
mosquitto_sub -h test.mosquitto.org -t "kodingindonesia/esp32/dht22/data" -v
# Nyalakan / matikan lampu (publish)
mosquitto_pub -h test.mosquitto.org -t "kodingindonesia/esp32/lampu/kontrol" -m "ON"
mosquitto_pub -h test.mosquitto.org -t "kodingindonesia/esp32/lampu/kontrol" -m "OFF"
Tool CLI dari paket Mosquitto — Linux, Mac, dan Windows setelah install Mosquitto.
Alur Program
setup()— WiFi, MQTT connect, subscribe topic kontrolloop()—mqttClient.loop()memproses pesan subscribe- Setiap 10 detik — baca DHT22, publish JSON ke topic sensor
callbackMQTT()— terima ON/OFF, ubah relay- Logika bonus — auto-off lampu saat suhu tinggi
Ini pola edge device klasik di IoT: telemetri + kontrol dalam satu firmware.
Tips & Troubleshooting
- Publish OK, subscribe tidak jalan: Pastikan
mqttClient.loop()dipanggil di setiap iterasiloop(). - JSON terpotong: Naikkan
setBufferSize(512)atau lebih. - Compile error ArduinoJson: Pastikan versi library cocok — v6 pakai
StaticJsonDocument, v7 pakaiJsonDocument. - rc=-2 saat connect MQTT: WiFi atau broker tidak terjangkau — cek internet.
- rc=4 (bad credentials):
test.mosquitto.orgport 1883 tidak perlu auth. - ESP32 restart saat relay + WiFi aktif: Power supply relay terpisah 5V, GND common dengan ESP32.
- Suhu selalu NaN: Cek wiring DHT22, pull-up 10kΩ, dan tunggu 2 detik setelah
dht.begin(). - Topic tidak muncul di Explorer: Topic case-sensitive — harus sama persis. Coba wildcard
kodingindonesia/esp32/#. - Ingin interval lebih cepat: Ubah
intervalPublish— jangan terlalu agresif di broker publik (hormati resource bersama).
Langkah Selanjutnya
- Dashboard hybrid Web Server + MQTT (#10) — monitoring lokal & remote dalam satu sketch
- Integrasi Home Assistant (#21) — sensor MQTT + switch relay di satu dashboard
- Atau pakai ESPHome (#22) — node DHT22 + relay tanpa coding Arduino
- Dashboard & otomasi visual dengan Node-RED (#23) — flow MQTT drag-and-drop
- Automasi gerak dengan sensor PIR + lampu MQTT (#24) — debounce & hold time
- Broker Mosquitto pribadi (#16) di Raspberry Pi dengan username/password
- Simpan histori suhu ke database lewat subscriber Python → MySQL (#18)
- Pelajari deep sleep (#11) ESP32 untuk hemat baterai pada node sensor
Selamat! Dengan artikel ini, kamu sudah menyelesaikan rangkaian proyek ESP32 + MQTT dari sensor hingga aktuator. Ini fondasi solid sebelum masuk ke platform cloud atau home automation lengkap.
Langkah Selanjutnya — Firmware Lanjut (Seri 2)
Sketch gabungan ini memakai satu loop() — cocok untuk belajar. Saat proyek butuh sensor dan MQTT berjalan paralel tanpa saling blocking, lanjut ke FreeRTOS multi-task (#31): task sensor, task WiFi/MQTT, dan antrean data.