ESP32 & ESP8266

Panduan Lengkap ESP32: Dari Setup Hingga Proyek IoT Pertama

πŸ”‘ Token

Tutorial komprehensif untuk memulai petualangan IoT dengan ESP32 β€” dari instalasi Arduino IDE hingga monitoring suhu real-time via MQTT

1. Apa Itu ESP32?

ESP32 adalah mikrokontroler System-on-Chip (SoC) yang dikembangkan oleh Espressif Systems asal Shanghai, Tiongkok. Chip ini menjadi sangat populer di kalangan maker dan engineer IoT karena menawarkan konektivitas WiFi dan Bluetooth dalam satu paket hemat daya dan murah.

ESP32 menggunakan prosesor Xtensa dual-core 32-bit LX6 yang berjalan pada frekuensi hingga 240 MHz. Ini menjadikannya jauh lebih powerful dibanding pendahulunya, ESP8266, yang hanya memiliki single-core berjalan di 80 MHz.

πŸ’‘ Tips

ESP32 tersedia dalam berbagai varian modul: ESP32-DevKitC, ESP32-WROOM-32, ESP32-S3, ESP32-C3, dan lain-lain. Untuk tutorial ini, kita akan menggunakan modul ESP32 DevKit v1 yang paling umum dan ramah pemula.

Spesifikasi Utama ESP32

Parameter Spesifikasi
ProsesorXtensa Dual-Core LX6 @ 240 MHz
RAM520 KB SRAM
Flash4 MB (tergantung modul)
WiFi802.11 b/g/n (2.4 GHz)
BluetoothBLE 4.2 + Classic
GPIO34 pin (26 usable)
ADC18 channel, 12-bit
DAC2 channel, 8-bit
SPI / I2C / UART4 / 2 / 3
Operating Voltage2.2V β€” 3.6V
Input Voltage (via USB)5V
Arsitektur Internal ESP32 SoC
⚑
Core 0 (LX6)
Dual-Core 240 MHz
⚑
Core 1 (LX6)
Dual-Core 240 MHz
πŸ“‘
WiFi 2.4GHz
802.11 b/g/n
πŸ“Ά
Bluetooth
BLE 4.2 + Classic
↓
πŸ’Ύ
520 KB SRAM
Memory Internal
πŸ“Š
ADC 12-bit
18 Channel
πŸ”Š
DAC 8-bit
2 Channel
〰️
PWM
16 Channel
πŸ‘†
Touch Pad
10 Channel
↓
πŸ”Œ
GPIO (34)
26 Usable
πŸ”—
SPI (4)
High Speed
πŸ”—
I2C (2)
Sensor Bus
πŸ”—
UART (3)
Serial Comm

Perbandingan ESP32 vs ESP8266 vs Arduino Uno

πŸ”§
ESP32
Rp 40-60rb
  • βœ… Dual-Core 240MHz
  • βœ… RAM 520 KB
  • βœ… Flash 4 MB
  • βœ… WiFi Built-in
  • βœ… BLE + Classic Bluetooth
  • βœ… 34 GPIO
  • ⚑ Tegangan 3.3V
Paling Populer
πŸ“‘
ESP8266
Rp 25-35rb
  • ❌ Single-Core 80MHz
  • ❌ RAM 160 KB
  • βœ… Flash 4 MB
  • βœ… WiFi Built-in
  • ❌ Tanpa Bluetooth
  • ❌ 17 GPIO
  • ⚑ Tegangan 3.3V
Budget Friendly
🟦
Arduino Uno
Rp 60-80rb
  • ❌ Single-Core 16MHz
  • ❌ RAM 2 KB
  • ❌ Flash 32 KB
  • ❌ Perlu WiFi Shield
  • ❌ Tanpa Bluetooth
  • βœ… 14 Digital + 6 Analog
  • ⚑ Tegangan 5V
Legacy / Shield
ℹ️ Kapan Pilih Mana?

Pilih ESP32 jika butuh WiFi + Bluetooth, komputasi lebih berat, atau banyak sensor. Pilih ESP8266 untuk proyek sederhana yang butuh WiFi saja. Pilih Arduino Uno untuk proyek yang membutuhkan tegangan 5V atau shield khusus.

2. Instalasi Arduino IDE dan Setup ESP32

Arduino IDE adalah Integrated Development Environment gratis yang paling banyak digunakan untuk memprogram mikrokontroler, termasuk ESP32. Meskipun ESP32 bukan produk Arduino resmi, board manager komunitas menyediakan dukungan penuh.

Langkah 1: Download dan Instal Arduino IDE 2.x

  1. Kunjungi situs resmi https://www.arduino.cc/en/software
  2. Pilih Arduino IDE 2.x (versi terbaru) untuk sistem operasi Anda
  3. Download dan jalankan installer, ikuti wizard instalasi
  4. Buka Arduino IDE setelah instalasi selesai

Langkah 2: Tambahkan Board ESP32 ke Board Manager

URL Board Manager
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

Caranya:

  1. Buka menu File β†’ Preferences (atau Ctrl + ,)
  2. Pada kolom "Additional Board Manager URLs", paste URL di atas
  3. Jika sudah ada URL lain, pisahkan dengan koma
  4. Klik OK
  5. Buka menu Tools β†’ Board β†’ Boards Manager
  6. Cari "esp32", pilih "esp32 by Espressif Systems"
  7. Klik Install (ukuran sekitar 200-300 MB, tunggu hingga selesai)

Langkah 3: Pilih Board dan Port

  1. Hubungkan ESP32 ke komputer via kabel USB (pastikan kabel data, bukan hanya charging)
  2. Buka menu Tools β†’ Board, pilih "ESP32 Dev Module"
  3. Buka menu Tools β†’ Port, pilih port COM yang muncul (biasanya COM3 atau COM5)
  4. Upload Speed bisa diatur ke 115200
⚠️ Peringatan

Jika ESP32 tidak terdeteksi di port COM, kemungkinan besar Anda perlu menginstal driver CP2102 (untuk modul dengan chip Silicon Labs) atau CH340 (untuk modul dengan chip CH340). Download driver dari situs resmi masing-masing vendor.

3. Program Hello World: LED Blink

Setiap programmer memulai dari "Hello World". Di dunia mikrokontroler, program Hello World adalah LED Blink β€” menyalakan dan mematikan LED secara bergantian. ESP32 memiliki LED internal yang terhubung ke GPIO 2 pada kebanyakan modul DevKit.

Diagram: Rangkaian LED Internal ESP32
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚     ESP32 DevKit     β”‚
  β”‚                      β”‚
  β”‚   GPIO 2 β”€β”€β”€β–Ίβ”œβ”€β”€ GND β”‚
  β”‚        (LED Internal) β”‚
  β”‚                      β”‚
  β”‚   USB ──► 5V / GND   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Catatan: LED internal sudah terpasang pada board DevKit.
  Tidak perlu kabel eksternal untuk percobaan pertama ini.

Tulis kode berikut di Arduino IDE:

C++ β€” led_blink.ino
// Program Blink LED - Hello World ESP32
// IoTHub - https://iothub.id

#define LED_BUILTIN_PIN 2

void setup() {
  // Konfigurasi GPIO 2 sebagai output
  pinMode(LED_BUILTIN_PIN, OUTPUT);

  // Inisialisasi komunikasi serial
  Serial.begin(115200);
  Serial.println("ESP32 LED Blink dimulai!");
}

void loop() {
  // Nyalakan LED
  digitalWrite(LED_BUILTIN_PIN, HIGH);
  Serial.println("LED ON");
  delay(1000);  // Tunggu 1 detik

  // Matikan LED
  digitalWrite(LED_BUILTIN_PIN, LOW);
  Serial.println("LED OFF");
  delay(1000);  // Tunggu 1 detik
}

Cara Upload Program

  1. Klik tombol βœ“ Verify (atau Ctrl + R) untuk kompilasi
  2. Pastikan tidak ada error
  3. Klik tombol β†’ Upload (atau Ctrl + U)
  4. Tunggu hingga muncul pesan "Done uploading"
  5. Buka Tools β†’ Serial Monitor (atau Ctrl + Shift + M)
  6. Atur baud rate ke 115200
Output Serial Monitor: ESP32 LED Blink dimulai! LED ON LED OFF LED ON LED OFF ...
πŸ’‘ Tips Pemula

Jika ESP32 tidak masuk mode upload, coba tahan tombol BOOT pada board saat proses upload dimulai, kemudian lepaskan setelah muncul pesan "Connecting...". Ini adalah fitur bootloader ESP32.

4. Membaca Sensor Suhu DHT11

Sensor DHT11 adalah sensor digital yang murah dan mudah digunakan untuk mengukur suhu dan kelembaban udara. DHT11 memiliki rentang pengukuran suhu 0-50Β°C dengan akurasi Β±2Β°C, dan kelembaban 20-80% dengan akurasi Β±5%.

Kebutuhan Komponen

Diagram: Rangkaian ESP32 + DHT11
       ESP32              DHT11
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚         β”‚        β”‚  β”Œβ”€β”€β”€β”  β”‚
    β”‚   3.3V  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€1 β”‚   β”‚  β”‚
    β”‚         β”‚   β”Œβ”€β”€β”€β”€β”€2 β”‚   β”‚  β”‚
    β”‚  GPIO4  β”œβ”€β”€β”€β”˜    β”‚  β”‚   β”‚  β”‚
    β”‚         β”‚  [10kΞ©] β”‚  β””β”€β”€β”€β”˜  β”‚
    β”‚         β”‚   β”‚     β”‚         β”‚
    β”‚   GND   β”œβ”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€4        β”‚
    β”‚         β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               Pin DHT11: 1=VCC, 2=DATA, 3=NC, 4=GND

Instalasi Library DHT

  1. Buka menu Sketch β†’ Include Library β†’ Manage Libraries
  2. Cari "DHT sensor library" oleh Adafruit
  3. Klik Install (library dependencies seperti Adafruit Unified Sensor akan ikut terinstal)

Program Membaca Sensor DHT11

C++ β€” baca_dht11.ino
// Membaca Sensor Suhu & Kelembaban DHT11
// IoTHub - https://iothub.id

#include "DHT.h"

#define DHT_PIN 4        // GPIO4 terhubung ke pin data DHT11
#define DHT_TYPE DHT11   // Tipe sensor

DHT sensorSuhu(DHT_PIN, DHT_TYPE);

void setup() {
  Serial.begin(115200);
  Serial.println("=== Pembaca Sensor DHT11 ===");

  // Inisialisasi sensor
  sensorSuhu.begin();
  delay(2000);  // Tunggu sensor stabil
}

void loop() {
  // Baca kelembaban
  float kelembaban = sensorSuhu.readHumidity();

  // Baca suhu dalam Celsius
  float suhuC = sensorSuhu.readTemperature();

  // Baca suhu dalam Fahrenheit
  float suhuF = sensorSuhu.readTemperature(true);

  // Cek apakah pembacaan valid
  if (isnan(kelembaban) || isnan(suhuC)) {
    Serial.println("[ERROR] Gagal membaca sensor DHT11!");
    Serial.println("Periksa koneksi kabel dan resistor pull-up.");
    delay(3000);
    return;
  }

  // Hitung Heat Index (indeks panas)
  float heatIndex = sensorSuhu.computeHeatIndex(suhuC, kelembaban, false);

  // Tampilkan hasil ke Serial Monitor
  Serial.println("--- Pembacaan Sensor ---");
  Serial.print("Suhu       : ");
  Serial.print(suhuC, 1);
  Serial.println(" Β°C");

  Serial.print("Kelembaban : ");
  Serial.print(kelembaban, 1);
  Serial.println(" %");

  Serial.print("Heat Index : ");
  Serial.print(heatIndex, 1);
  Serial.println(" Β°C");
  Serial.println();

  delay(5000);  // Baca setiap 5 detik
}
Output Serial Monitor: === Pembaca Sensor DHT11 === --- Pembacaan Sensor --- Suhu : 28.5 Β°C Kelembaban : 72.0 % Heat Index : 30.2 Β°C --- Pembacaan Sensor --- Suhu : 28.0 Β°C Kelembaban : 73.5 % Heat Index : 29.8 Β°C

5. Menghubungkan ESP32 ke WiFi

Salah satu keunggulan terbesar ESP32 adalah konektivitas WiFi bawaan. Dengan beberapa baris kode, ESP32 dapat terhubung ke jaringan WiFi rumah Anda dan mulai berkomunikasi dengan internet atau perangkat lain di jaringan lokal.

Program Koneksi WiFi Dasar

C++ β€” wifi_connect.ino
// Menghubungkan ESP32 ke Jaringan WiFi
// IoTHub - https://iothub.id

#include "WiFi.h"

// Konfigurasi WiFi - ganti dengan kredensial Anda
const char* WIFI_SSID = "NamaWiFiAnda";
const char* WIFI_PASS = "PasswordWiFi";

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

  Serial.println("=== Koneksi WiFi ESP32 ===");

  // Aktifkan mode WiFi Station (client)
  WiFi.mode(WIFI_STA);

  // Mulai koneksi ke jaringan WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  Serial.print("Menghubungkan ke WiFi");
  int attempt = 0;

  // Tunggu hingga terhubung
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    attempt++;

    // Timeout setelah 20 detik
    if (attempt > 40) {
      Serial.println();
      Serial.println("[ERROR] Gagal terhubung ke WiFi!");
      Serial.println("Periksa SSID dan password.");
      return;
    }
  }

  // Informasi koneksi berhasil
  Serial.println();
  Serial.println("[OK] Terhubung ke WiFi!");
  Serial.print("SSID       : ");
  Serial.println(WiFi.SSID());
  Serial.print("IP Address : ");
  Serial.println(WiFi.localIP());
  Serial.print("Gateway    : ");
  Serial.println(WiFi.gatewayIP());
  Serial.print("RSSI       : ");
  Serial.print(WiFi.RSSI());
  Serial.println(" dBm");
  Serial.print("Hostname   : ");
  Serial.println(WiFi.getHostname());
}

void loop() {
  // Monitor status koneksi secara periodik
  static unsigned long lastCheck = 0;

  if (millis() - lastCheck > 30000) {  // Setiap 30 detik
    lastCheck = millis();

    if (WiFi.status() == WL_CONNECTED) {
      Serial.print("[OK] WiFi terhubung - IP: ");
      Serial.println(WiFi.localIP());
    } else {
      Serial.println("[WARN] Koneksi WiFi terputus! Mencoba reconnect...");
      WiFi.reconnect();
    }
  }
}
Output Serial Monitor: === Koneksi WiFi ESP32 === Menghubungkan ke WiFi.... [OK] Terhubung ke WiFi! SSID : RumahKu_5G IP Address : 192.168.1.105 Gateway : 192.168.1.1 RSSI : -45 dBm Hostname : esp32-iot
πŸ’‘ Tips Keamanan

Jangan pernah menyimpan password WiFi langsung dalam kode untuk produksi. Gunakan NVS (Non-Volatile Storage) atau buat captive portal untuk konfigurasi WiFi pertama kali. Untuk tutorial ini, kita hardcode agar sederhana.

6. Mengirim Data ke MQTT Broker

MQTT (Message Queuing Telemetry Transport) adalah protokol komunikasi ringan yang dirancang khusus untuk perangkat IoT. MQTT menggunakan model publish/subscribe dimana perangkat mengirim (publish) data ke topik tertentu, dan subscriber menerima data dari topik yang diminati.

Diagram: Arsitektur MQTT
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     Publish      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     Deliver      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  ESP32   β”‚ ──────────────►  β”‚    MQTT     β”‚  ──────────────► β”‚Dashboard β”‚
β”‚ (Sensor) β”‚  topic: sensor/  β”‚   Broker    β”‚   topic: sensor/ β”‚ /Grafana β”‚
β”‚          β”‚  suhu/ruang1     β”‚  (Mosquitto)β”‚   suhu/ruang1    β”‚          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                     β”‚
                                     β”‚ Subscribe
                                     β–Ό
                              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                              β”‚  Aplikasi   β”‚
                              β”‚  Mobile App β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

  Topik (Topic) adalah string seperti: "iothub/esp32/suhu"
  Pesan (Payload) berisi data, misal: {"suhu": 28.5, "kelembaban": 72}

Instalasi Library MQTT

  1. Buka Sketch β†’ Include Library β†’ Manage Libraries
  2. Cari "PubSubClient" oleh Nick O'Leary
  3. Klik Install
ℹ️ Broker MQTT untuk Testing

Untuk percobaan, Anda bisa menggunakan broker MQTT publik gratis dari test.mosquitto.org (tanpa autentikasi). Untuk produksi, instal broker Mosquitto di Raspberry Pi atau gunakan layanan cloud seperti HiveMQ, AWS IoT, atau EMQX.

C++ β€” mqtt_publish.ino
// Mengirim Data Sensor ke MQTT Broker
// IoTHub - https://iothub.id

#include "WiFi.h"
#include "PubSubClient.h"

// === Konfigurasi WiFi ===
const char* WIFI_SSID = "NamaWiFiAnda";
const char* WIFI_PASS = "PasswordWiFi";

// === Konfigurasi MQTT ===
const char* MQTT_SERVER = "test.mosquitto.org";
const int   MQTT_PORT   = 1883;
const char* MQTT_TOPIC  = "iothub/demo/esp32";
const char* CLIENT_ID   = "esp32_kelas_iot_001";

// Objek klien
WiFiClient espClient;
PubSubClient mqtt(espClient);

void koneksiMQTT() {
  while (!mqtt.connected()) {
    Serial.print("Menghubungkan ke MQTT broker...");

    if (mqtt.connect(CLIENT_ID)) {
      Serial.println(" [OK] Terhubung!");

      // Publish pesan pertama
      mqtt.publish(MQTT_TOPIC, "ESP32 telah online!");
    } else {
      Serial.print(" [GAGAL] rc=");
      Serial.print(mqtt.state());
      Serial.println(" | Coba lagi dalam 5 detik...");
      delay(5000);
    }
  }
}

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

  // Koneksi WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("WiFi connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" OK!");

  // Konfigurasi MQTT
  mqtt.setServer(MQTT_SERVER, MQTT_PORT);

  // Hubungkan ke broker
  koneksiMQTT();
}

void loop() {
  // Pastikan MQTT tetap terhubung
  if (!mqtt.connected()) {
    koneksiMQTT();
  }
  mqtt.loop();

  // Simulasi data sensor
  float suhu = 25.0 + (random(0, 100) / 10.0);
  float kelembaban = 60.0 + (random(0, 200) / 10.0);

  // Format payload JSON
  char payload[128];
  snprintf(payload, sizeof(payload),
    "{\"suhu\":%.1f,\"kelembaban\":%.1f,\"uptime\":%lu}",
    suhu, kelembaban, millis() / 1000);

  // Publish ke broker MQTT
  if (mqtt.publish(MQTT_TOPIC, payload)) {
    Serial.print("[PUBLISH] ");
    Serial.println(payload);
  } else {
    Serial.println("[ERROR] Gagal publish!");
  }

  delay(10000);  // Kirim setiap 10 detik
}
Output Serial Monitor: WiFi connecting... OK! Menghubungkan ke MQTT broker... [OK] Terhubung! [PUBLISH] {"suhu":28.5,"kelembaban":72.3,"uptime":10} [PUBLISH] {"suhu":27.8,"kelembaban":68.1,"uptime":20} [PUBLISH] {"suhu":29.2,"kelembaban":75.6,"uptime":30}

7. Proyek: Monitoring Suhu Real-time

Sekarang kita akan menggabungkan semua yang telah dipelajari ke dalam satu proyek utuh: sistem monitoring suhu real-time menggunakan ESP32, sensor DHT11, dan MQTT. Data suhu akan dikirim ke broker MQTT setiap 15 detik dan bisa dipantau dari aplikasi MQTT client di HP atau komputer.

Arsitektur Sistem

Diagram: Arsitektur Monitoring Suhu Real-time
  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
  β”‚  DHT11     │────►│  ESP32  │────►│ MQTT Broker  │────►│  Dashboard  β”‚
  β”‚  Sensor    β”‚GPIO β”‚  + WiFi β”‚WiFi β”‚ (Mosquitto)  β”‚ TCP β”‚  / App HP   β”‚
  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                              β”‚
                                              β”‚ Subscribe
                                              β–Ό
                                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                       β”‚  Node-RED /  β”‚
                                       β”‚  Grafana     β”‚
                                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Program Lengkap Proyek Monitoring

C++ β€” monitoring_suhu.ino
// =============================================
// Proyek: Monitoring Suhu Real-time via MQTT
// IoTHub - https://iothub.id
// =============================================

#include "WiFi.h"
#include "PubSubClient.h"
#include "DHT.h"

// === Pin & Sensor ===
#define DHT_PIN 4
#define DHT_TYPE DHT11
#define LED_STATUS 2

// === WiFi Config ===
const char* WIFI_SSID = "NamaWiFiAnda";
const char* WIFI_PASS = "PasswordWiFi";

// === MQTT Config ===
const char* MQTT_SERVER   = "test.mosquitto.org";
const int   MQTT_PORT     = 1883;
const char* MQTT_TOPIC_DATA   = "iothub/monitoring/suhu";
const char* MQTT_TOPIC_ALERT = "iothub/monitoring/alert";
const char* MQTT_TOPIC_CMD   = "iothub/monitoring/cmd";
const char* CLIENT_ID        = "esp32_monitor_suhu_01";

// === Threshold ===
const float SUHU_BAHAYA = 35.0;   // Suhu bahaya dalam Celsius
const float SUHU_WASPADA = 30.0;  // Suhu waspada
const int   INTERVAL_KIRIM = 15000; // Kirim setiap 15 detik

// === Objek ===
DHT dht(DHT_PIN, DHT_TYPE);
WiFiClient espClient;
PubSubClient mqtt(espClient);

// === Variabel Global ===
unsigned long lastKirim = 0;
int totalPengiriman = 0;
int totalError = 0;
bool modeDebug = false;

// === Callback saat menerima pesan MQTT ===
void onMessage(char* topic, byte* payload, unsigned int length) {
  String pesan = "";
  for (unsigned int i = 0; i < length; i++) {
    pesan += (char)payload[i];
  }

  Serial.print("[CMD] Diterima di topik '");
  Serial.print(topic);
  Serial.print("': ");
  Serial.println(pesan);

  // Handle perintah sederhana
  if (pesan == "status") {
    char statusMsg[128];
    snprintf(statusMsg, sizeof(statusMsg),
      "{\"total_pengiriman\":%d,\"total_error\":%d,\"uptime\":%lu}",
      totalPengiriman, totalError, millis() / 1000);
    mqtt.publish(MQTT_TOPIC_DATA, statusMsg);
    Serial.println("[CMD] Status dikirim.");
  } else if (pesan == "debug_on") {
    modeDebug = true;
    Serial.println("[CMD] Mode debug diaktifkan.");
  } else if (pesan == "debug_off") {
    modeDebug = false;
    Serial.println("[CMD] Mode debug dinonaktifkan.");
  }
}

void setupWiFi() {
  Serial.print("WiFi: Menghubungkan ke ");
  Serial.print(WIFI_SSID);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  int attempt = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    if (++attempt > 40) {
      Serial.println(" [GAGAL]");
      ESP.restart();  // Restart jika gagal
    }
  }

  Serial.println(" [OK]");
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());

  // Kedipkan LED sebagai indikator WiFi terhubung
  for (int i = 0; i < 5; i++) {
    digitalWrite(LED_STATUS, HIGH);
    delay(100);
    digitalWrite(LED_STATUS, LOW);
    delay(100);
  }
}

void setupMQTT() {
  mqtt.setServer(MQTT_SERVER, MQTT_PORT);
  mqtt.setCallback(onMessage);
  mqtt.setBufferSize(256);
}

void hubungkanMQTT() {
  while (!mqtt.connected()) {
    Serial.print("MQTT: Menghubungkan...");

    // Buat pesan LWT (Last Will and Testament)
    char lwtMsg[] = "{\"status\":\"offline\"}";

    if (mqtt.connect(CLIENT_ID, MQTT_TOPIC_DATA, 1, true, lwtMsg)) {
      Serial.println(" [OK]");
      digitalWrite(LED_STATUS, HIGH);

      // Subscribe ke topik perintah
      mqtt.subscribe(MQTT_TOPIC_CMD);
      Serial.println("Subscribed ke: " + String(MQTT_TOPIC_CMD));

      // Publish status online (retained)
      mqtt.publish(MQTT_TOPIC_DATA, "{\"status\":\"online\"}", true);
    } else {
      Serial.print(" [GAGAL, rc=");
      Serial.print(mqtt.state());
      Serial.println("]");
      digitalWrite(LED_STATUS, LOW);
      delay(3000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_STATUS, OUTPUT);

  Serial.println("╔════════════════════════════════════╗");
  Serial.println("β•‘  Monitoring Suhu Real-time v1.0   β•‘");
  Serial.println("β•‘  IoTHub - https://iothub.id       β•‘");
  Serial.println("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•");

  dht.begin();
  setupWiFi();
  setupMQTT();
  hubungkanMQTT();
}

void loop() {
  if (!mqtt.connected()) {
    hubungkanMQTT();
  }
  mqtt.loop();

  unsigned long sekarang = millis();

  if (sekarang - lastKirim >= INTERVAL_KIRIM) {
    lastKirim = sekarang;

    // Baca sensor
    float suhu = dht.readTemperature();
    float kelembaban = dht.readHumidity();

    // Validasi pembacaan
    if (isnan(suhu) || isnan(kelembaban)) {
      totalError++;
      Serial.println("[ERROR] Pembacaan sensor gagal!");
      return;
    }

    // Hitung heat index
    float heatIndex = dht.computeHeatIndex(suhu, kelembaban, false);

    // Tentukan level status
    const char* level;
    if (suhu >= SUHU_BAHAYA) {
      level = "BAHAYA";
    } else if (suhu >= SUHU_WASPADA) {
      level = "WASPADA";
    } else {
      level = "AMAN";
    }

    // Format payload JSON
    char payload[256];
    snprintf(payload, sizeof(payload),
      "{\"suhu\":%.1f,\"kelembaban\":%.1f,\"heat_index\":%.1f,"
      "\"level\":\"%s\",\"wifi_rssi\":%d,\"uptime\":%lu,\"msg_count\":%d}",
      suhu, kelembaban, heatIndex, level,
      WiFi.RSSI(), sekarang / 1000, totalPengiriman + 1);

    // Publish data
    bool sukses = mqtt.publish(MQTT_TOPIC_DATA, payload);

    if (suhu >= SUHU_WASPADA) {
      // Kirim alert ke topik terpisah
      char alertMsg[128];
      snprintf(alertMsg, sizeof(alertMsg),
        "{\"alert\":\"SUHU %s\",\"suhu\":%.1f,\"level\":\"%s\"}",
        suhu >= SUHU_BAHAYA ? "BAHAYA" : "WASPADA",
        suhu, level);
      mqtt.publish(MQTT_TOPIC_ALERT, alertMsg);

      // Kedipkan LED untuk alert
      for (int i = 0; i < 3; i++) {
        digitalWrite(LED_STATUS, LOW);
        delay(200);
        digitalWrite(LED_STATUS, HIGH);
        delay(200);
      }
    }

    if (sukses) {
      totalPengiriman++;
      Serial.printf("[%d] Suhu: %.1fΒ°C | RH: %.1f%% | %s\n",
        totalPengiriman, suhu, kelembaban, level);
    } else {
      totalError++;
      Serial.println("[ERROR] Gagal mengirim data!");
    }

    if (modeDebug) {
      Serial.print("[DEBUG] Payload: ");
      Serial.println(payload);
    }
  }
}
πŸ’‘ Cara Pantau Data

Gunakan aplikasi MQTT Explorer (desktop) atau MQTT Dashboard (Android) untuk subscribe ke topik iothub/monitoring/suhu. Anda akan melihat data JSON berisi suhu, kelembaban, dan status yang diperbarui setiap 15 detik. Kirim perintah status atau debug_on ke topik iothub/monitoring/cmd untuk mengontrol ESP32 dari jarak jauh.

Memperluas Proyek

Setelah proyek dasar berjalan, Anda bisa mengembangkannya lebih lanjut:

8. Troubleshooting Umum

Berikut adalah masalah yang paling sering dihadapi saat bekerja dengan ESP32, beserta solusinya:

ESP32 Tidak Terdeteksi di Port COM

⚠️ Masalah Umum #1

Gejala: Tidak ada port COM yang muncul di Arduino IDE saat ESP32 dicolokkan.

Solusi:

  • Pastikan menggunakan kabel USB data (bukan kabel charge-only)
  • Instal driver CP2102 dari Silicon Labs atau CH340 dari situs resmi
  • Coba port USB yang berbeda atau kabel yang lain
  • Di Windows, cek Device Manager untuk melihat apakah driver terinstal dengan benar

Gagal Upload: "A fatal error occurred: Failed to connect to ESP32"

πŸ”΄ Masalah Umum #2

Gejala: Proses upload stuck di "Connecting..." lalu timeout.

Solusi:

  • Tahan tombol BOOT di board ESP32 saat upload dimulai
  • Lepaskan tombol BOOT setelah muncul pesan "Writing at 0x..."
  • Jika sering terjadi, tambahkan kapasitor 10Β΅F antara EN dan GND
  • Pastikan upload speed di 115200 (bukan 921600)

WiFi Gagal Terhubung (Timeout)

⚠️ Masalah Umum #3

Gejala: ESP32 stuck di "Menghubungkan ke WiFi..." terus-menerus.

Solusi:

  • Periksa SSID dan password (case-sensitive!)
  • Pastikan router berjalan di band 2.4 GHz (ESP32 tidak mendukung 5 GHz)
  • Coba dekatkan ESP32 ke router
  • Nonaktifkan sementara firewall atau MAC filtering di router
  • Panggil WiFi.disconnect() sebelum WiFi.begin()

Sensor DHT11 Membaca NaN / Error

⚠️ Masalah Umum #4

Gejala: Nilai sensor selalu NaN atau tidak valid.

Solusi:

  • Pasang resistor pull-up 10kΞ© antara pin DATA dan VCC
  • Periksa urutan pin DHT11 (1=VCC, 2=DATA, 3=NC, 4=GND)
  • Tambahkan delay 2 detik setelah sensorSuhu.begin()
  • Pastikan library yang benar terinstal (Adafruit DHT library)
  • Cek apakah pin GPIO yang digunakan benar (GPIO4 dalam tutorial ini)

Tabel Troubleshooting Cepat

Gejala Kemungkinan Penyebab Solusi
Board panas berlebihan Short circuit atau tegangan berlebih Periksa koneksi, jangan beri tegangan 5V ke pin GPIO
Reset berulang (crash loop) Error di loop() atau watchdog timeout Tambahkan delay(), cek stack overflow
MQTT putus-putus Sinyal WiFi lemah / broker overload Perbaiki sinyal, gunakan broker lokal
ADC pembacaan tidak akurat WiFi menggunakan ADC internal Gunakan ADC2 saat WiFi aktif, atau gunakan pin ADC1
Kode kompilasi lambat Library besar, toolchain baru Bersihkan cache (File β†’ Preferences β†’ verbose)

9. Quiz: Uji Pemahamanmu!

Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang ESP32 dan IoT:

Pertanyaan 1: Berapa frekuensi clock maksimum prosesor ESP32?

a) 80 MHz
b) 240 MHz
c) 160 MHz
d) 320 MHz

Pertanyaan 2: Protokol apa yang paling cocok untuk komunikasi ringan antara perangkat IoT dan server?

a) HTTP
b) FTP
c) MQTT
d) SMTP

Pertanyaan 3: Komponen apa yang WAJIB ditambahkan saat menggunakan sensor DHT11 agar pembacaan stabil?

a) Resistor pull-up 10kΞ©
b) Kapasitor 100Β΅F
c) Transistor NPN
d) Dioda zener 3.3V

Pertanyaan 4: Pernyataan berikut yang BENAR tentang ESP32 vs Arduino Uno adalah...

a) Arduino Uno memiliki WiFi built-in
b) ESP32 beroperasi pada tegangan 5V
c) Arduino Uno memiliki RAM 512 KB
d) ESP32 memiliki dual-core dan Bluetooth

Pertanyaan 5: Apa fungsi tombol BOOT pada board ESP32 saat proses upload?

a) Menghapus semua program yang tersimpan
b) Memasukkan ESP32 ke mode bootloader untuk flashing
c) Mengatur ulang konfigurasi WiFi
d) Mengubah baud rate serial
← Sebelumnya Kembali ke Beranda Selanjutnya β†’ Artikel Lainnya