1. Apa itu Firebase?
Firebase adalah platform pengembangan aplikasi Backend-as-a-Service (BaaS) yang dikembangkan oleh Google. Firebase menyediakan berbagai layanan siap pakai seperti database, autentikasi, hosting, cloud functions, dan banyak lagi β sehingga pengembang tidak perlu membangun backend dari nol.
Dalam konteks IoT, Firebase sangat populer karena menyediakan Realtime Database yang memungkinkan sinkronisasi data secara real-time antara perangkat (misalnya ESP32) dan cloud tanpa perlu menulis kode server yang rumit.
Realtime Database vs Cloud Firestore
Firebase menyediakan dua jenis layanan database utama:
- Realtime Database β Menyimpan data dalam format JSON tree dan menyinkronkan secara real-time ke semua klien yang terhubung. Sangat cocok untuk IoT karena pembaruan data terjadi instan (milidetik).
- Cloud Firestore β Database dokumen generasi terbaru yang lebih scalable dengan fitur query lanjutan. Namun, Firestore memiliki latensi yang sedikit lebih tinggi dan lebih cocok untuk aplikasi web/mobile skala besar.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Firebase Realtime Database β β β β ESP32 βββ Firebase βββ Web Dashboard β β (Sensor) (JSON Tree) (Monitoring) β β β β β Sinkronisasi instan (milidetik) β β β Simpel untuk data sensor time-series β β β Library Arduino resmi tersedia β β β οΈ Query terbatas (tidak ada range query kompleks) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β Cloud Firestore β β β β ESP32 βββ Firestore βββ Web Dashboard β β (Sensor) (Dokumen) (Monitoring) β β β β β Query lanjutan & indexing otomatis β β β Scaling horizontal lebih baik β β β οΈ Latensi lebih tinggi untuk real-time β β β οΈ Library Arduino tidak resmi (community) β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Untuk proyek IoT yang membutuhkan sinkronisasi data real-time dengan perangkat mikrokontroler, Realtime Database adalah pilihan yang lebih tepat. Firestore lebih cocok untuk aplikasi web atau mobile yang membutuhkan query data kompleks.
Fitur Firebase yang Relevan untuk IoT
| Fitur | Kegunaan untuk IoT |
|---|---|
| Realtime Database | Menyimpan dan menyinkronkan data sensor secara instan |
| Cloud Functions | Menjalankan logika otomatis (trigger saat data berubah) |
| Firebase Auth | Autentikasi perangkat IoT dengan token & API key |
| Security Rules | Kontrol akses baca/tulis per path database |
| Hosting | Menyimpan dashboard monitoring IoT |
| Cloud Messaging | Mengirim notifikasi ke aplikasi mobile saat data berubah |
| Billing (Free Tier) | 1 GB penyimpanan, 10 GB/bulan transfer data, 50K baca/hari |
2. Setup Firebase Project
Sebelum menghubungkan ESP32 dengan Firebase, kamu perlu membuat project di Firebase Console dan mendapatkan kredensial yang diperlukan.
Langkah 1: Buat Project Firebase
- Buka browser dan kunjungi https://console.firebase.google.com/
- Login dengan akun Google kamu
- Klik tombol "Add project" (Proyek baru)
- Masukkan nama project, misalnya
iot-monitoring-project - Nonaktifkan opsi Google Analytics (opsional, tidak wajib untuk IoT)
- Klik "Create project" dan tunggu hingga selesai
Langkah 2: Aktifkan Realtime Database
- Di Firebase Console, pilih project yang baru dibuat
- Di menu sidebar kiri, klik "Realtime Database"
- Klik tombol "Create Database"
- Pilih lokasi server terdekat (misal:
us-central1atauasia-southeast1) - Pilih mode "Start in test mode" (untuk pengembangan)
- Klik "Enable"
Langkah 3: Dapatkan API Key & Konfigurasi
- Di menu sidebar, klik ikon gear (βοΈ) β "Project settings"
- Pilih tab "General"
- Scroll ke bagian "Your apps"
- Klik ikon "</>" (web app) β register app web dengan nama
- Salin konfigurasi yang ditampilkan, terutama bagian:
const firebaseConfig = {
apiKey: "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "iot-monitoring-project.firebaseapp.com",
databaseURL: "https://iot-monitoring-project-default-rtdb.firebaseio.com",
projectId: "iot-monitoring-project",
storageBucket: "iot-monitoring-project.appspot.com",
messagingSenderId: "123456789012",
appId: "1:123456789012:web:abcdef1234567890"
};
Nilai databaseURL adalah yang paling penting untuk ESP32. URL ini memiliki format: https://<nama-project>-default-rtdb.firebaseio.com. Simpan URL ini baik-baik karena akan digunakan di kode Arduino.
Langkah 4: Aktifkan Anonymous Authentication
Untuk kemudahan pengujian, aktifkan autentikasi anonymous:
- Klik menu "Authentication" di sidebar
- Pilih tab "Sign-in method"
- Klik "Anonymous" β Enable β Save
3. Struktur Database Firebase untuk IoT
Desain struktur database yang baik sangat penting dalam proyek IoT. Firebase Realtime Database menggunakan struktur JSON tree, sehingga kita perlu merancangnya agar efisien untuk pembacaan dan penulisan data.
Prinsip Desain Database IoT
- Flat sebisa mungkin β Hindari nesting terlalu dalam, karena setiap baca di Firebase dihitung untuk setiap node yang dibaca
- Pisahkan data berdasarkan fungsi β Pisahkan data sensor (telemetry), data kontrol (command), dan metadata perangkat
- Gunakan timestamp β Selalu sertakan timestamp untuk setiap data point
- Batasi data historis β Gunakan
limitToLast()untuk menghindari pembacaan data yang terlalu besar
iot-monitoring-project-default-rtdb
β
βββ devices/
β βββ esp32_001/
β β βββ info/
β β β βββ name: "Sensor Ruangan Tamu"
β β β βββ location: "Lantai 1"
β β β βββ status: "online"
β β β
β β βββ sensor/
β β β βββ temperature: 28.5
β β β βββ humidity: 65.2
β β β βββ timestamp: 1687238400000
β β β βββ history/
β β β βββ 1687238400000: { temp: 28.5, hum: 65.2 }
β β β βββ 1687238460000: { temp: 28.7, hum: 65.0 }
β β β βββ 1687238520000: { temp: 28.3, hum: 65.4 }
β β β
β β βββ control/
β β βββ relay1: false
β β βββ relay2: true
β β βββ led: true
β β
β βββ esp32_002/
β βββ ...
β
βββ alerts/
β βββ 1687238400000:
β β βββ device: "esp32_001"
β β βββ type: "high_temp"
β β βββ message: "Suhu melebihi 35Β°C"
β β βββ read: false
β β
βββ settings/
βββ auto_relay: true
βββ temp_threshold_high: 35.0
βββ temp_threshold_low: 20.0
Dengan struktur di atas, ESP32 hanya perlu membaca path /devices/esp32_001/control untuk mengecek status relay tanpa harus mengunduh seluruh database. Ini sangat hemat bandwidth dan kuota Firebase gratis.
4. ESP32 + Firebase: Kirim Data Sensor
Sekarang saatnya menghubungkan ESP32 dengan Firebase! Kita akan menggunakan library Firebase ESP32 Client oleh mobizt yang merupakan library paling populer dan lengkap untuk Firebase IoT.
Instalasi Library Firebase
- Buka Arduino IDE
- Menu Tools β Manage Libraries (atau Ctrl+Shift+I)
- Di kolom pencarian, ketik:
Firebase ESP32 Client - Install library "Firebase ESP32 Client" oleh mobizt (versi terbaru)
Wiring: ESP32 + DHT11
| DHT11 Pin | ESP32 Pin | Keterangan |
|---|---|---|
| VCC (+) | 3.3V | Tegangan input |
| Data (Out) | GPIO 4 | Pin data sensor |
| NC | β | Tidak terpakai |
| GND (-) | GND | Ground |
Jangan lupa pasang resistor pull-up 10kΞ© antara pin VCC dan Data pada DHT11.
Kode: Kirim Suhu & Kelembaban ke Firebase
/*
* Kirim Data Sensor DHT11 ke Firebase Realtime Database
* ESP32 + Firebase ESP32 Client Library
* IoTHub - Tutorial Firebase IoT
*/
#include <WiFi.h>
#include <Firebase_ESP32.h>
#include <DHT.h>
// ===== KONFIGURASI WiFi =====
#define WIFI_SSID "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"
// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"
// ===== KONFIGURASI SENSOR =====
#define DHT_PIN 4
#define DHT_TYPE DHT11
// ===== INISIALISASI =====
DHT dht(DHT_PIN, DHT_TYPE);
FirebaseData firebaseData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;
// Interval pengiriman data (dalam milidetik)
unsigned long previousMillis = 0;
const long interval = 10000; // Kirim data setiap 10 detik
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== Firebase IoT: Kirim Data Sensor ===");
// Inisialisasi sensor DHT
dht.begin();
Serial.println("Sensor DHT11 aktif");
// Koneksi WiFi
Serial.print("Menghubungkan WiFi");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("WiFi terhubung! IP: ");
Serial.println(WiFi.localIP());
// Konfigurasi Firebase
firebaseConfig.database_url = FIREBASE_HOST;
firebaseConfig.api_key = FIREBASE_AUTH;
Firebase.begin(&firebaseConfig, &firebaseAuth);
// Aktifkan auto-reconnect WiFi
Firebase.reconnectWiFi(true);
// Set ukuran buffer data rx/tx
firebaseData.setResponseSize(1024);
Serial.println("Firebase terhubung! Mulai mengirim data...");
}
void loop() {
unsigned long currentMillis = millis();
// Kirim data sesuai interval yang ditentukan
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Baca data dari sensor DHT11
float suhu = dht.readTemperature(); // Celsius
float kelembaban = dht.readHumidity();
// Validasi pembacaan sensor
if (isnan(suhu) || isnan(kelembaban)) {
Serial.println("Gagal membaca sensor DHT11!");
return;
}
// Tampilkan di Serial Monitor
Serial.print("Suhu: ");
Serial.print(suhu);
Serial.print("Β°C | Kelembaban: ");
Serial.print(kelembaban);
Serial.println("%");
// Kirim data suhu ke Firebase
String path_suhu = "/devices/esp32_001/sensor/temperature";
if (Firebase.setFloat(firebaseData, path_suhu, suhu)) {
Serial.println("Suhu terkirim: " + String(suhu));
} else {
Serial.println("Gagal kirim suhu: " + firebaseData.errorReason());
}
// Kirim data kelembaban ke Firebase
String path_hum = "/devices/esp32_001/sensor/humidity";
if (Firebase.setFloat(firebaseData, path_hum, kelembaban)) {
Serial.println("Kelembaban terkirim: " + String(kelembaban));
} else {
Serial.println("Gagal kirim kelembaban: " + firebaseData.errorReason());
}
// Kirim timestamp
String path_time = "/devices/esp32_001/sensor/timestamp";
if (Firebase.setInt(firebaseData, path_time, millis())) {
Serial.println("Timestamp terkirim");
}
// Update status device
String path_status = "/devices/esp32_001/info/status";
Firebase.setString(firebaseData, path_status, "online");
Serial.println("---");
}
}
Hindari mengirim data terlalu sering ke Firebase (misal setiap 1 detik) karena bisa menghabiskan kuota free tier dengan cepat. Interval 10-30 detik sudah cukup untuk monitoring suhu pada umumnya.
5. ESP32 + Firebase: Baca Data Kontrol (LED ON/OFF)
Selain mengirim data sensor, ESP32 juga bisa membaca data dari Firebase untuk mengontrol perangkat. Misalnya, kita bisa mengontrol LED atau relay dari dashboard web melalui Firebase.
Konsep: Stream Listener untuk Kontrol Real-time
Firebase mendukung fitur streaming, yaitu ESP32 akan menerima pembaruan data secara otomatis setiap kali nilai di path tertentu berubah. Ini jauh lebih efisien daripada terus-menerus melakukan polling.
ββββββββββββ Ubah nilai ββββββββββββββββ Stream/Listener ββββββββββββ β Browser β βββββββββββββββββββ β Firebase β ββββββββββββββββββββββ β ESP32 β βDashboard β relay1 = true β Realtime DB β Path berubah! β LED ON β β β β β β β β β β βββββββββββββββββββ β β βββββββββββββββββββββ β β β β Status terupdate β β Kirim status baru β β ββββββββββββ ββββββββββββββββ ββββββββββββ
Kode: Kontrol LED & Relay via Firebase Stream
/*
* Kontrol LED & Relay via Firebase Realtime Database
* ESP32 - Stream Listener untuk perubahan data real-time
* IoTHub - Tutorial Firebase IoT
*/
#include <WiFi.h>
#include <Firebase_ESP32.h>
// ===== KONFIGURASI WiFi =====
#define WIFI_SSID "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"
// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"
// ===== PIN OUTPUT =====
#define LED_PIN 2 // LED bawaan ESP32
#define RELAY1_PIN 16 // Relay module channel 1
#define RELAY2_PIN 17 // Relay module channel 2
// ===== INISIALISASI =====
FirebaseData firebaseData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;
// Path path di Firebase
const char* pathControl = "/devices/esp32_001/control";
void streamCallback(StreamData data) {
// Dipanggil setiap kali data berubah di path yang di-listen
Serial.println("=== DATA BERUBAH ===");
Serial.print("Path: ");
Serial.println(data.dataPath());
Serial.print("Tipe data: ");
Serial.println(data.dataType());
Serial.print("Nilai baru: ");
Serial.println(data.stringData());
// Cek path yang berubah dan jalankan aksi
String path = data.dataPath();
String value = data.stringData();
if (path == "/led") {
// Kontrol LED bawaan ESP32
if (value == "true") {
digitalWrite(LED_PIN, HIGH);
Serial.println("LED ON");
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("LED OFF");
}
}
else if (path == "/relay1") {
// Kontrol Relay Channel 1
if (value == "true") {
digitalWrite(RELAY1_PIN, HIGH);
Serial.println("Relay 1 ON");
} else {
digitalWrite(RELAY1_PIN, LOW);
Serial.println("Relay 1 OFF");
}
}
else if (path == "/relay2") {
// Kontrol Relay Channel 2
if (value == "true") {
digitalWrite(RELAY2_PIN, HIGH);
Serial.println("Relay 2 ON");
} else {
digitalWrite(RELAY2_PIN, LOW);
Serial.println("Relay 2 OFF");
}
}
}
void streamTimeoutCallback(bool timeout) {
if (timeout) {
Stream timeoutStream;
Serial.println("Stream timeout, reconnect...");
// Mulai ulang stream listener
if (!Firebase.readStream(firebaseData)) {
Serial.println("Gagal mulai ulang stream: " + firebaseData.errorReason());
}
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("=== Firebase IoT: Kontrol LED & Relay ===");
// Setup pin output
pinMode(LED_PIN, OUTPUT);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
// Pastikan semua relay OFF saat awal
digitalWrite(LED_PIN, LOW);
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
// Koneksi WiFi
Serial.print("Menghubungkan WiFi");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("WiFi terhubung! IP: ");
Serial.println(WiFi.localIP());
// Konfigurasi Firebase
firebaseConfig.database_url = FIREBASE_HOST;
firebaseConfig.api_key = FIREBASE_AUTH;
Firebase.begin(&firebaseConfig, &firebaseAuth);
Firebase.reconnectWiFi(true);
// Inisialisasi nilai awal di Firebase (jika belum ada)
if (!Firebase.pathExist(firebaseData, "/devices/esp32_001/control")) {
Serial.println("Membuat node kontrol awal...");
FirebaseJson json;
json.set("led", false);
json.set("relay1", false);
json.set("relay2", false);
Firebase.set(firebaseData, "/devices/esp32_001/control", json);
}
// Mulai stream listener untuk path kontrol
if (!Firebase.beginStream(firebaseData, pathControl)) {
Serial.println("Gagal mulai stream: " + firebaseData.errorReason());
return;
}
// Set callback untuk perubahan data
Firebase.setStreamCallback(firebaseData, streamCallback, streamTimeoutCallback);
Serial.println("Stream listener aktif! Menunggu perubahan data...");
}
void loop() {
// Pastikan koneksi WiFi tetap aktif
if (WiFi.status() != WL_CONNECTED) {
Serial.println("WiFi terputus! Menghubungkan ulang...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println("WiFi terhubung kembali!");
}
// Stream listener bekerja di background, tidak perlu polling
delay(1000);
}
Gunakan path spesifik saat menggunakan beginStream(). Jangan gunakan path root (/) karena Firebase akan mengalirkan seluruh data database yang akan membebani ESP32.
6. Firebase Security Rules untuk IoT
Security Rules adalah komponen krusial yang sering diabaikan dalam proyek IoT. Tanpa rules yang tepat, siapa pun bisa membaca data sensor atau mengontrol perangkat kamu dari internet!
Mengapa Security Rules Penting untuk IoT?
- Mencegah akses tidak sah β Seseorang bisa membaca suhu di rumah kamu
- Mencegah kontrol ilegal β Seseorang bisa mematikan/menghidupkan perangkat kamu
- Mencegah penyalahgunaan kuota β Akun kamu bisa kehabisan kuota free tier
- Melindungi data historis β Data sensor berharga tidak boleh dihapus sembarangan
Contoh Security Rules untuk IoT
{
"rules": {
"devices": {
// Setiap device hanya bisa diakses dengan device ID yang benar
"$device_id": {
// Info device: baca semua, tulis hanya owner
"info": {
".read": "auth != null",
".write": "auth != null && root.child('users').child(auth.uid).child('devices').child($device_id).exists()"
},
// Data sensor: baca semua yang terautentikasi, tulis hanya device sendiri
"sensor": {
".read": "auth != null",
".write": "auth != null && root.child('devices').child($device_id).child('info/api_key').val() === data.parent().child('info/api_key').val()"
},
// Data kontrol: baca semua, tulis semua (untuk dashboard web)
"control": {
".read": "auth != null",
".write": "auth != null"
}
}
},
// Pengaturan threshold: baca semua, tulis hanya admin
"settings": {
".read": "auth != null",
".write": "auth != null && root.child('users').child(auth.uid).child('role').val() === 'admin'"
},
// Log aksi: baca semua, tulis hanya device
"logs": {
".read": "auth != null",
".write": false,
"$log_id": {
".validate": "newData.hasChildren(['timestamp', 'device', 'action'])"
}
},
// Aturan default: tolak semua yang tidak didefinisikan
"$other": {
".read": false,
".write": false
}
}
}
Menjalankan Security Rules
- Di Firebase Console, buka Realtime Database
- Klik tab "Rules"
- Tempelkan JSON rules di atas (sesuaikan dengan kebutuhanmu)
- Klik "Publish"
Mode "test mode" memungkinkan siapa pun membaca dan menulis data tanpa autentikasi. Mode ini hanya untuk pengembangan awal. SELALU update ke production rules sebelum menggunakan di proyek nyata!
7. Firebase vs MQTT vs HTTP: Perbandingan
Ada beberapa protokol komunikasi yang bisa digunakan untuk IoT cloud. Berikut perbandingan lengkap Firebase Realtime Database, MQTT, dan HTTP REST API.
Firebase Realtime DB MQTT Broker HTTP REST API
ββββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
β β β β β β
β ESP32 ββHTTPSβββ β β ESP32 ββTCPβββ β β ESP32 ββHTTPSβββ β
β Firebase Server β β MQTT Broker β β REST API Server β
β β β β β β β β β
β Real-time sync β β Pub/Sub message β β Request/Responseβ
β via WebSocket β β via Topics β β β
β β β β β β
ββββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ
Alat: Web Dashboard Alat: Node-RED Alat: Grafana
Firebase Console Grafana Grafana
| Aspek | Firebase RTDB | MQTT | HTTP REST |
|---|---|---|---|
| Protokol dasar | WebSocket / HTTPS | TCP (port 1883/8883) | HTTP/HTTPS |
| Kontrol Real-time | β Otomatis (stream) | β Pub/Sub instant | β Harus polling |
| Bandwidth | Sedang (JSON) | π’ Sangat rendah (binary) | π΄ Tinggi (HTTP headers) |
| Daya baterai | Sedang | π’ Sangat hemat | π΄ Boros |
| Mudah untuk pemula | π’ Sangat mudah | Mudah | Mudah |
| Dashboard built-in | β Firebase Console | β Perlu tool tambahan | β Perlu buat sendiri |
| Autentikasi | β Built-in (token/API key) | Username/password TLS | Token/JWT manual |
| Query data | β οΈ Terbatas | β Tidak ada (hanya topic) | β Lengkap (GET param) |
| Free tier | 1 GB storage, 10 GB/mo | Broker publik gratis | Tergantung provider |
| Skalabilitas | Google infrastructure | Self-hosted atau cloud | Tergantung arsitektur |
| Kapan pakai? | Dashboard monitoring, CRUD mudah | Banyak device, hemat daya | Integrasi dengan API eksternal |
Firebase adalah pilihan terbaik ketika kamu membutuhkan dashboard monitoring real-time yang cepat dibangun, kombinasi kirim + kontrol data dalam satu platform, dan tidak ingin mengelola broker/server sendiri. Untuk skala ribuan device, pertimbangkan MQTT atau kombinasi keduanya.
8. Proyek: Sistem Monitoring Suhu + Kontrol Relay via Firebase
Mari kita satukan semua yang sudah dipelajari ke dalam satu proyek lengkap! Proyek ini menggabungkan pengiriman data sensor (suhu + kelembaban) dan kontrol relay (untuk menghidupkan/mematikan perangkat) melalui Firebase Realtime Database.
Komponen yang Dibutuhkan
| Komponen | Jumlah | Fungsi |
|---|---|---|
| ESP32 DevKit v1 | 1 | Mikrokontroler utama |
| Sensor DHT11/DHT22 | 1 | Mengukur suhu dan kelembaban |
| Relay Module 2 Channel 5V | 1 | Mengontrol perangkat AC (lampu, kipas) |
| LED merah + hijau | 2 | Indikator status sistem |
| Resistor 220Ξ© | 2 | Pembatas arus untuk LED |
| Resistor 10kΞ© | 1 | Pull-up untuk DHT11 |
| Breadboard + jumper wire | β | Prototyping |
Diagram Wiring
βββββββββββββββββββββββββββββββββββ
β ESP32 DevKit v1 β
β β
DHT11 ββββββββββ€ GPIO 4 (D4) β
β β
LED Hijau ββββββ€ GPIO 2 (D2) β LED Bawaan β
LED Merah ββββββ€ GPIO 15 (D15) β
β β
Relay CH1 ββββββ€ GPIO 16 (D16) β Kipas Angin β
Relay CH2 ββββββ€ GPIO 17 (D17) β Lampu β
β β
Relay COM ββββββ€ 5V β
DHT11 VCC ββββββ€ 3.3V β
β β
βββββββββββββββββββββββββββββββββββ
DHT11 Pinout:
βββββββββ
β DHT11 β VCC βββ 3.3V (ESP32)
β β DATA βββ GPIO 4 + Resistor 10kΞ© ke 3.3V
β 1 2 3 β NC
β β GND βββ GND (ESP32)
βββββββββ
Kode Lengkap: Proyek Monitoring + Kontrol
/*
* Proyek Lengkap: Monitoring Suhu + Kontrol Relay via Firebase
* ESP32 + DHT11 + Relay 2 Channel
* IoTHub - Tutorial Firebase IoT
*
* Fitur:
* 1. Mengirim data suhu & kelembaban ke Firebase setiap 15 detik
* 2. Monitoring status LED (online/offline) di Firebase
* 3. Kontrol relay real-time via Firebase stream listener
* 4. Alert otomatis jika suhu melebihi threshold
*/
#include <WiFi.h>
#include <Firebase_ESP32.h>
#include <DHT.h>
#include <time.h>
// ===== KONFIGURASI WiFi =====
#define WIFI_SSID "NamaWiFiKamu"
#define WIFI_PASSWORD "PasswordWiFiKamu"
// ===== KONFIGURASI Firebase =====
#define FIREBASE_HOST "iot-monitoring-project-default-rtdb.firebaseio.com"
#define FIREBASE_AUTH "AIzaSyBxxxxxxxxxxxxxxxxxxxxxxx"
// ===== PIN KONFIGURASI =====
#define DHT_PIN 4
#define DHT_TYPE DHT11
#define LED_GREEN 2 // LED indikator online
#define LED_RED 15 // LED indikator error
#define RELAY1_PIN 16 // Relay CH1 - Kipas Angin
#define RELAY2_PIN 17 // Relay CH2 - Lampu
// ===== THRESHOLD =====
#define TEMP_HIGH 35.0 // Suhu tinggi (Β°C) - trigger alert
#define TEMP_LOW 18.0 // Suhu rendah (Β°C) - trigger alert
// ===== INISIALISASI =====
DHT dht(DHT_PIN, DHT_TYPE);
FirebaseData firebaseData;
FirebaseData streamData;
FirebaseConfig firebaseConfig;
FirebaseAuth firebaseAuth;
// Device ID unik
const String DEVICE_ID = "esp32_001";
// Timing
unsigned long prevSendTime = 0;
const long sendInterval = 15000; // 15 detik
// ===== FUNGSI CALLBACK STREAM =====
void onControlChange(StreamData data) {
String path = data.dataPath();
String value = data.stringData();
Serial.printf("[KONTROL] %s = %s\n", path.c_str(), value.c_str());
if (path == "/relay1") {
bool state = (value == "true");
digitalWrite(RELAY1_PIN, state ? HIGH : LOW);
Serial.printf(" β Relay 1 (Kipas): %s\n", state ? "ON" : "OFF");
}
else if (path == "/relay2") {
bool state = (value == "true");
digitalWrite(RELAY2_PIN, state ? HIGH : LOW);
Serial.printf(" β Relay 2 (Lampu): %s\n", state ? "ON" : "OFF");
}
}
void onStreamTimeout(bool timeout) {
if (timeout) {
Serial.println("[STREAM] Timeout! Reconnecting...");
Firebase.readStream(streamData);
}
}
// ===== FUNGSI KIRIM ALERT =====
void sendAlert(String type, String message) {
String path = "/alerts/" + String(millis());
FirebaseJson alertJson;
alertJson.set("device", DEVICE_ID);
alertJson.set("type", type);
alertJson.set("message", message);
alertJson.set("timestamp", millis());
alertJson.set("read", false);
if (Firebase.setJSON(streamData, path, alertJson)) {
Serial.println("[ALERT] Terkirim: " + message);
}
}
// ===== FUNGSI KIRIM DATA SENSOR =====
void sendSensorData(float suhu, float kelembaban) {
String basePath = "/devices/" + DEVICE_ID + "/sensor/";
// Kirim data terkini
Firebase.setFloat(streamData, basePath + "temperature", suhu);
Firebase.setFloat(streamData, basePath + "humidity", kelembaban);
Firebase.setInt(streamData, basePath + "timestamp", millis());
// Simpan history (opsional, untuk grafik)
String historyPath = basePath + "history/" + String(millis()) + "/";
FirebaseJson histJson;
histJson.set("temp", suhu);
histJson.set("hum", kelembaban);
Firebase.setJSON(streamData, historyPath, histJson);
// Cek threshold dan kirim alert
if (suhu > TEMP_HIGH) {
sendAlert("high_temp", "Suhu " + String(suhu) + "Β°C melebihi batas " + String(TEMP_HIGH) + "Β°C");
}
else if (suhu < TEMP_LOW) {
sendAlert("low_temp", "Suhu " + String(suhu) + "Β°C di bawah batas " + String(TEMP_LOW) + "Β°C");
}
}
// ===== SETUP =====
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("========================================");
Serial.println(" Firebase IoT - Monitoring + Kontrol");
Serial.println(" IoTHub Tutorial");
Serial.println("========================================");
// Setup pin
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
// Default: semua OFF
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, LOW);
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
// Mulai sensor
dht.begin();
Serial.println("[INIT] Sensor DHT11 aktif");
// Koneksi WiFi
Serial.print("[WIFI] Menghubungkan");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
int retries = 0;
while (WiFi.status() != WL_CONNECTED && retries < 30) {
Serial.print(".");
delay(500);
retries++;
}
if (WiFi.status() != WL_CONNECTED) {
Serial.println("\n[FATAL] WiFi gagal! Restart...");
ESP.restart();
}
Serial.println();
Serial.printf("[WIFI] Terhubung! IP: %s\n", WiFi.localIP().toString().c_str());
digitalWrite(LED_GREEN, HIGH); // LED hijau ON = WiFi OK
// Setup NTP time
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
// Konfigurasi Firebase
firebaseConfig.database_url = FIREBASE_HOST;
firebaseConfig.api_key = FIREBASE_AUTH;
Firebase.begin(&firebaseConfig, &firebaseAuth);
Firebase.reconnectWiFi(true);
streamData.setResponseSize(4096);
// Update status online
String infoPath = "/devices/" + DEVICE_ID + "/info/";
FirebaseJson infoJson;
infoJson.set("name", "Monitoring Ruangan");
infoJson.set("location", "Lantai 1");
infoJson.set("status", "online");
infoJson.set("ip", WiFi.localIP().toString());
Firebase.setJSON(streamData, infoPath, infoJson);
// Inisialisasi node kontrol jika belum ada
if (!Firebase.pathExist(streamData, "/devices/" + DEVICE_ID + "/control")) {
FirebaseJson ctrlJson;
ctrlJson.set("relay1", false);
ctrlJson.set("relay2", false);
Firebase.setJSON(streamData, "/devices/" + DEVICE_ID + "/control", ctrlJson);
}
// Mulai stream listener untuk kontrol
String controlPath = "/devices/" + DEVICE_ID + "/control";
if (!Firebase.beginStream(streamData, controlPath)) {
Serial.println("[STREAM] Gagal mulai: " + streamData.errorReason());
} else {
Firebase.setStreamCallback(streamData, onControlChange, onStreamTimeout);
Serial.println("[STREAM] Listener kontrol aktif");
}
Serial.println("[SYSTEM] Siap! Memulai siklus monitoring...");
Serial.println("========================================");
}
// ===== LOOP =====
void loop() {
unsigned long now = millis();
// Cek WiFi
if (WiFi.status() != WL_CONNECTED) {
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, HIGH);
Serial.println("[WIFI] Terputus! Menghubungkan ulang...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
delay(5000);
return;
}
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_RED, LOW);
// Kirim data sensor sesuai interval
if (now - prevSendTime >= sendInterval) {
prevSendTime = now;
float suhu = dht.readTemperature();
float kelembaban = dht.readHumidity();
if (isnan(suhu) || isnan(kelembaban)) {
Serial.println("[SENSOR] Gagal baca DHT11!");
Firebase.setString(streamData, "/devices/" + DEVICE_ID + "/info/status", "sensor_error");
return;
}
// Kirim ke Firebase
sendSensorData(suhu, kelembaban);
// Cek status relay dari Firebase
FirebaseJson relayStatus;
String relayPath = "/devices/" + DEVICE_ID + "/control";
if (Firebase.getJSON(streamData, relayPath)) {
FirebaseJson &json = streamData.jsonObject();
FirebaseJsonData jsonData;
if (json.get(jsonData, "relay1")) {
Serial.printf(" Relay1: %s\n", jsonData.stringValue);
}
if (json.get(jsonData, "relay2")) {
Serial.printf(" Relay2: %s\n", jsonData.stringValue);
}
}
Serial.printf("[DATA] Suhu: %.1fΒ°C | Kelembaban: %.1f%%\n", suhu, kelembaban);
Serial.println("---");
}
delay(100);
}
Proyek ini bisa dikembangkan lebih lanjut dengan menambahkan: (1) Dashboard web menggunakan Chart.js untuk grafik data sensor, (2) Notifikasi push ke smartphone via Firebase Cloud Messaging, (3) Logika otomatis menggunakan Firebase Cloud Functions, atau (4) Multiple ESP32 yang terhubung ke project yang sama.
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Firebase untuk IoT: