Pembuka bab Proyek Gabungan: satu ESP32 mengendalikan lampu dan kipas kamar lewat relay 2 channel, sambil memantau suhu. Kipas bisa menyala otomatis saat kamar panas, atau dikendalikan manual dari HP.
Proyek ini menggabungkan relay 2 channel (proyek 082), DHT11 (proyek 021), dan logika termostat (proyek 069). Fungsi atur() dipakai untuk kedua relay. Parameter bool& keadaan (dengan tanda &) membuat fungsi mengubah variabel aslinya (lampu atau kipas), bukan salinannya.
Kipas punya dua mode. Mode otomatis menyalakan kipas di atas batas suhu dan mematikannya setelah turun 1 °C di bawah batas. Begitu switch Kipas digeser manual, mode otomatis mati supaya keputusanmu tidak langsung ditimpa sensor. Setiap perubahan relay dikirim kembali ke switch dashboard (retained), jadi posisi switch selalu sesuai keadaan sebenarnya.
Keamanan: pemasangan relay ke lampu dan kipas 220V harus dikerjakan atau diawasi orang yang paham instalasi listrik.
Komponen
| Komponen | Qty | Harga |
|---|---|---|
| ESP32 DOIT DevKit V1 30 pin | 1 | Rp75.000 |
| Modul Relay 2-Channel 5V Arduino ESP32 Optocoupl | 1 | Rp19.400 |
| Modul sensor DHT11 | 1 | Rp12.000 |
| Kabel jumper female-female 10 cm (isi 10)isi 10, terpakai 7 | 1 | Rp3.500 |
| Kabel micro USB data 30 cmopsional, kalau belum punya kabel micro USB data | 1 | Rp11.700 |
| Total (tanpa opsional) | Rp109.900 |
Langkah 1: Rangkai komponen
Sambungkan kabel sesuai gambar di atas. Kalau gambar dan tabel terlihat berbeda, ikuti tabel.
| Dari | Ke | Kabel | |
|---|---|---|---|
| Relay 2 ch 5V (jumper H) DC+ | → | VIN | oranye |
| Relay 2 ch 5V (jumper H) DC− | → | GND | hitam |
| Relay 2 ch 5V (jumper H) IN1 | → | D26 GPIO26 | biru |
| Relay 2 ch 5V (jumper H) IN2 | → | D27 GPIO27 | ungu |
| DHT11 VCC | → | 3V3 | merah |
| DHT11 DATA | → | D4 GPIO4 | hijau |
| DHT11 GND | → | GND | hitam |
Langkah 2: Siapkan dashboard Klenik
Cara cepat: unduh p141.json, ganti budi1234 dengan KODE-mu, lalu import di Klenik (menu titik tiga → Export / Import → Import → Ganti total). Langkah lengkapnya ada di Panduan Klenik.
| Widget | Topic | Setting |
|---|---|---|
| Switch Lampu | ichibot/KODE/p141/lampu | payload ON / OFF |
| Switch Kipas | ichibot/KODE/p141/kipas | payload ON / OFF |
| Switch Kipas Otomatis | ichibot/KODE/p141/otomatis | payload ON / OFF |
| Slider Output Kipas Nyala di Atas | ichibot/KODE/p141/batas | 24–36 °C |
| Gauge Suhu Kamar | ichibot/KODE/p141/suhu | 15–40 °C |
| Gauge Kelembapan | ichibot/KODE/p141/lembap | 0–100 % |
Langkah 3: Upload kode
Library: PubSubClient (Nick O'Leary), DHT sensor library (Adafruit), Adafruit Unified Sensor. Board di Arduino IDE: ESP32 Dev Module.
Isi dulu nama WiFi dan password di bagian ISI DULU, lalu ganti budi1234 di baris topic dengan KODE-mu, lalu upload dan buka Serial Monitor (115200).
// Proyek 141 - Smart Room: Lampu, Kipas, Suhu
// Board: ESP32 DOIT DevKit V1 | Dashboard: klenik.ichibot.id
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
// ===== ISI DULU =====
const char* WIFI_NAMA = "nama-wifi-kamu";
const char* WIFI_PASS = "password-wifi-kamu";
// topic MQTT: ganti budi1234 dengan KODE-mu (sama dengan di dashboard Klenik)
const char* TOPIK_SUHU = "ichibot/budi1234/p141/suhu";
const char* TOPIK_LEMBAP = "ichibot/budi1234/p141/lembap";
const char* TOPIK_LAMPU = "ichibot/budi1234/p141/lampu";
const char* TOPIK_KIPAS = "ichibot/budi1234/p141/kipas";
const char* TOPIK_OTOMATIS = "ichibot/budi1234/p141/otomatis";
const char* TOPIK_BATAS = "ichibot/budi1234/p141/batas";
const char* BROKER = "mqtt.ichibot.id";
WiFiClient wifi;
PubSubClient mqtt(wifi);
DHT dht(4, DHT11);
const int LAMPU = 26, KIPAS = 27; // IN1, IN2 relay 2 channel
bool lampu = false, kipas = false, kipasOtomatis = true;
float batasPanas = 30;
unsigned long terakhir = 0;
void atur(int pin, bool& keadaan, bool v, const char* topik) {
if (v == keadaan) return;
keadaan = v;
digitalWrite(pin, v ? HIGH : LOW);
mqtt.publish(topik, v ? "ON" : "OFF", true); // samakan switch di dashboard
}
void pesanMasuk(char* t, byte* isi, unsigned int panjang) {
String topik = t;
String p;
for (unsigned int i = 0; i < panjang; i++) p += (char)isi[i];
if (topik == TOPIK_LAMPU) atur(LAMPU, lampu, p == "ON", TOPIK_LAMPU);
else if (topik == TOPIK_KIPAS) { kipasOtomatis = false; atur(KIPAS, kipas, p == "ON", TOPIK_KIPAS); } // manual
else if (topik == TOPIK_OTOMATIS) kipasOtomatis = (p == "ON");
else if (topik == TOPIK_BATAS) batasPanas = p.toFloat();
}
void langganan() {
mqtt.subscribe(TOPIK_LAMPU);
mqtt.subscribe(TOPIK_KIPAS);
mqtt.subscribe(TOPIK_OTOMATIS);
mqtt.subscribe(TOPIK_BATAS);
}
sambungWiFi() dan sambungMQTT(): sama di semua proyek (klik untuk lihat)
void sambungWiFi() {
WiFi.begin(WIFI_NAMA, WIFI_PASS);
Serial.print("WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(" OK, IP " + WiFi.localIP().toString());
}
void sambungMQTT() {
while (!mqtt.connected()) {
if (mqtt.connect(WiFi.macAddress().c_str())) {
Serial.println("Terhubung ke Klenik");
langganan();
} else {
Serial.println("Broker gagal, coba lagi 3 detik");
delay(3000);
}
}
}
void setup() {
Serial.begin(115200);
pinMode(LAMPU, OUTPUT);
pinMode(KIPAS, OUTPUT);
dht.begin();
sambungWiFi();
mqtt.setServer(BROKER, 1883);
mqtt.setCallback(pesanMasuk);
}
void loop() {
if (!mqtt.connected()) sambungMQTT();
mqtt.loop();
if (millis() - terakhir < 5000) return;
terakhir = millis();
float suhu = dht.readTemperature();
float lembap = dht.readHumidity();
if (isnan(suhu)) return;
mqtt.publish(TOPIK_SUHU, String(suhu, 1).c_str());
mqtt.publish(TOPIK_LEMBAP, String(lembap, 0).c_str());
if (kipasOtomatis) { // histeresis 1 °C
if (suhu > batasPanas) atur(KIPAS, kipas, true, TOPIK_KIPAS);
else if (suhu < batasPanas - 1) atur(KIPAS, kipas, false, TOPIK_KIPAS);
}
}Langkah 4: Pahami kodenya
- Satu fungsi untuk dua relay.
bool&adalah referensi: fungsi mengubah variabel yang dikirim, bukan salinannya. - Perintah manual mematikan mode otomatis. Nyalakan switch Kipas Otomatis lagi untuk menyerahkan kendali ke sensor.
- Histeresis 1 °C, supaya relay tidak ceklak-ceklik saat suhu tepat di batas.