Pendahuluan & Tujuan Pembelajaran
Bagian ini memberikan gambaran umum tentang modul praktik IoT Penyiram Tanaman Otomatis. Anda dapat melihat sasaran pembelajaran serta metadata kelas untuk menyesuaikan penyampaian materi kepada siswa. Tujuannya adalah untuk memahami esensi proyek sebelum memulai perakitan fisik.
âąī¸ Informasi Praktik
- Topik: Sistem Kontrol Otomatis
- Tingkat: SMP / SMA / SMK
- Estimasi Waktu: 2 - 3 Jam Pelajaran
đ¯ Kompetensi Siswa
- Memahami konsep dasar Internet of Things (IoT).
- Merangkai mikrokontroler (Wemos D1 Mini) dengan sensor dan aktuator.
- Menghubungkan hardware ke Cloud (Blynk) dan API (WhatsApp).
- Melakukan kalibrasi sensor analog sederhana.
Persiapan Alat & Bahan
Gunakan daftar periksa interaktif ini untuk memastikan setiap kelompok siswa telah memiliki komponen yang lengkap sebelum merakit. Klik pada setiap kartu untuk menandai item tersebut sebagai "Tersedia". Ini membantu pengorganisasian kelas yang lebih baik.
Wemos D1 Mini
Mikrokontroler ESP8266 + Kabel Micro USB
Sensor Kelembaban
Soil Moisture Sensor (Analog)
Pompa Air Mini
Water Pump 5V DC + Selang kecil
Modul Relay
1-Channel (5V) untuk kontrol arus pompa
LCD 16x2
Lengkap dengan modul I2C terpasang
Kabel Jumper
Male-to-Female dan Female-to-Female
Bahan Simulasi
1 Gelas air tawar & 1 Gelas kosong/tanah kering
Tahap 1: Perakitan (Wiring)
Ikuti langkah perakitan interaktif ini. Guru membimbing siswa merangkai komponen dengan hati-hati. Mengisolasi setiap tahap perakitan meminimalkan risiko korsleting atau kesalahan pin. Klik pada masing-masing komponen untuk melihat detail koneksi pin ke Wemos D1 Mini.
â ī¸ Peringatan Keselamatan: Pastikan Wemos BELUM terhubung ke komputer atau listrik saat merangkai.
Koneksi: Sensor Kelembaban
- Pin Sensor VCC â Wemos 3.3V / 5V
- Pin Sensor GND â Wemos GND
- Pin Sensor A0 (Analog) â Wemos A0
Koneksi: Modul Relay & Pompa
- Relay VCC/DC+ â Wemos 5V (VU/Vin)
- Relay GND/DC- â Wemos GND
- Relay IN/Data â Wemos D7
COM relay, ujung lainnya ke NO (Normally Open). Sisa kabel ke sumber listrik.
Koneksi: LCD 16x2 (I2C)
- Pin LCD VCC â Wemos 5V (VU/Vin)
- Pin LCD GND â Wemos GND
- Pin LCD SDA â Wemos D2
- Pin LCD SCL â Wemos D1
Tahap 2 & 3: Cloud & Kode
Di bagian ini, pelajari struktur platform yang digunakan (Arduino IDE, Blynk Cloud, dan Fonnte WhatsApp API). Di bawah ini Anda dapat menyalin program Arduino secara lengkap. Arahkan siswa untuk mengubah nilai kredensial saja pada baris teratas kode.
âī¸ Pengaturan Blynk IoT
| Virtual Pin | Tipe Data | Fungsi / Widget |
|---|---|---|
| V0 | Integer (0-100) | Kelembaban (%) - Gauge |
| V1 | String | Status Sistem - Value Display |
| V2 | Integer (0-1) | Mode Auto/Manual - Switch |
| V3 | Integer (0-1) | Tombol Pompa - Switch |
âī¸ Panduan Library & Board
Sebelum mengunggah kode, pastikan di Arduino IDE sudah terinstal:
- Library Blynk (oleh Volodymyr Shymanskyy)
- Library LiquidCrystal I2C (oleh Frank de Brabander)
Pastikan juga Board yang terpilih di menu Tools adalah:
LOLIN(WEMOS) D1 R2 & mini
/*
Proyek : IoT Pengukur Kelembaban Tanah & Penyiram Otomatis
Board : Wemos D1 Mini (ESP8266)
Integrasi : Blynk IoT & WhatsApp API Fonnte
*/
// --- BLYNK CREDENTIALS (HARUS DI PALING ATAS) ---
#define BLYNK_TEMPLATE_ID "TMPL6xTjYZOFa" // Ganti dengan Template ID Blynk
#define BLYNK_TEMPLATE_NAME "Smart Farming" // Ganti dengan Template Name Blynk
#define BLYNK_AUTH_TOKEN "fzPEGMjL7ZE2kWebrpYC-oqhTThRqdzT"; // Ganti dengan token Blynk
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <LiquidCrystal_I2C.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
// --- KONFIGURASI WIFI ---
char ssid[] = "NAMA_WIFI_ANDA"; // Ganti dengan nama WiFi Anda
char pass[] = "PASSWORD_WIFI_ANDA"; // Ganti dengan password WiFi Anda
// --- KONFIGURASI FONNTE WA ---
String fonnteToken = "xxxxxxxxxx"; // Ganti dengan Token API WA
String targetWA = "08xxxxxxxxxxxxxx"; // Ganti dengan no WA Tujuan
// --- KONFIGURASI PIN & HARDWARE ---
#define SENSOR_PIN A0
#define RELAY_PIN D7 // Pin D7 terhubung ke Relay Pompa
// Jika relay Anda aktif LOW (nyala saat diberi logika LOW), ubah nilai di bawah ini:
// PUMP_ON = LOW, PUMP_OFF = HIGH
#define PUMP_ON LOW
#define PUMP_OFF HIGH
LiquidCrystal_I2C lcd(0x27, 16, 2); // Alamat I2C biasanya 0x27 atau 0x3F
BlynkTimer timer;
// --- VARIABEL GLOBAL ---
int moisturePercent = 0;
bool isAutoMode = true; // Default mode Auto
bool isPumpOn = false;
bool waSent = false; // Mencegah spam WA (Hanya dikirim sekali saat mulai kering)
// Batas kelembaban (Sesuai permintaan: Kering < 25%, Basah >= 80%)
const int DRY_THRESHOLD = 25;
const int WET_THRESHOLD = 80;
void setup() {
Serial.begin(115200);
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, PUMP_OFF); // Pastikan pompa mati saat awal
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Memulai Sistem..");
// Inisialisasi Blynk & WiFi
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Terhubung!");
delay(1000);
// Set interval pembacaan sensor setiap 2 detik
timer.setInterval(2000L, processSensor);
// Set default state Blynk
Blynk.virtualWrite(V2, 0); // Set ke Mode Auto
Blynk.virtualWrite(V3, 0); // Matikan tombol manual
}
void loop() {
Blynk.run();
timer.run();
}
// --- FUNGSI PEMBACAAN SENSOR & LOGIKA AUTO ---
void processSensor() {
int sensorValue = analogRead(SENSOR_PIN);
// Berdasarkan pengujian, nilai analog basah maksimal sensor ada di kisaran 750.
moisturePercent = map(sensorValue, 1023, 750, 0, 100);
// Batasi nilai persentase agar tidak tembus 0-100
if (moisturePercent > 100) moisturePercent = 100;
if (moisturePercent < 0) moisturePercent = 0;
Serial.print("Kelembaban: ");
Serial.print(moisturePercent);
Serial.println("%");
// Update ke Blynk dan LCD
Blynk.virtualWrite(V0, moisturePercent);
updateLCD();
// Logika Mode Otomatis
if (isAutoMode) {
if (moisturePercent < DRY_THRESHOLD && !isPumpOn) {
// Tanah Kering -> Nyalakan Pompa
turnPump(true);
Blynk.virtualWrite(V1, "Kering - Menyiram");
// Kirim WA hanya sekali saat baru terdeteksi kering
if (!waSent) {
sendWA("Peringatan: Tanah kering (" + String(moisturePercent) + "%). Pompa air sedang menyiram tanaman.");
waSent = true;
}
}
else if (moisturePercent >= WET_THRESHOLD && isPumpOn) {
// Tanah Basah Cukup -> Matikan Pompa
turnPump(false);
Blynk.virtualWrite(V1, "Tanah Basah - OK");
// Reset flag WA agar bisa mengirim lagi jika nanti kering
waSent = false;
sendWA("Info: Kelembaban tanah sudah cukup (" + String(moisturePercent) + "%). Pompa dimatikan.");
}
else if (!isPumpOn) {
Blynk.virtualWrite(V1, "Normal");
waSent = false; // Reset jika status normal tapi belum basah maksimal
}
}
}
// --- FUNGSI KONTROL POMPA ---
void turnPump(bool state) {
isPumpOn = state;
if (state) {
digitalWrite(RELAY_PIN, PUMP_ON);
Blynk.virtualWrite(V3, 1); // Update tombol di Blynk
Serial.println("Pompa MENYALA");
} else {
digitalWrite(RELAY_PIN, PUMP_OFF);
Blynk.virtualWrite(V3, 0); // Update tombol di Blynk
Serial.println("Pompa MATI");
}
}
// --- FUNGSI UPDATE TAMPILAN LCD ---
void updateLCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Lembab: ");
lcd.print(moisturePercent);
lcd.print("%");
lcd.setCursor(0, 1);
if (isPumpOn) {
lcd.print("Pompa:NYALA");
} else {
lcd.print("Pompa:MATI ");
}
if (isAutoMode) {
lcd.print("(OTO)");
} else {
lcd.print("(MAN)");
}
}
// --- BLYNK VIRTUAL WRITE (MENERIMA INPUT DARI APLIKASI) ---
// Mode Switch (V2)
BLYNK_WRITE(V2) {
int mode = param.asInt();
if (mode == 1) {
isAutoMode = false; // Mode Manual
Blynk.virtualWrite(V1, "Mode: MANUAL");
} else {
isAutoMode = true; // Mode Auto
waSent = false; // Reset flag WA saat kembali ke auto
}
updateLCD();
}
// Manual Pump Control Switch (V3)
BLYNK_WRITE(V3) {
int pumpControl = param.asInt();
if (!isAutoMode) {
if (pumpControl == 1) {
turnPump(true);
Blynk.virtualWrite(V1, "Manual: Menyiram");
} else {
turnPump(false);
Blynk.virtualWrite(V1, "Manual: Siaga");
}
updateLCD();
} else {
// Jika masih mode Auto tapi user mencoba tekan tombol pompa,
// kembalikan tombol ke state aslinya (ditolak)
Blynk.virtualWrite(V3, isPumpOn ? 1 : 0);
}
}
// --- FUNGSI KIRIM WHATSAPP VIA FONNTE ---
void sendWA(String message) {
if (WiFi.status() == WL_CONNECTED) {
WiFiClientSecure client;
client.setInsecure(); // Abaikan SSL untuk ESP8266 agar tidak berat
HTTPClient http;
Serial.println("Mengirim WA...");
// Ganti spasi dengan %20 untuk format URL (URL Encoding sederhana)
message.replace(" ", "%20");
http.begin(client, "https://api.fonnte.com/send");
http.addHeader("Authorization", fonnteToken);
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String postData = "target=" + targetWA + "&message=" + message;
int httpResponseCode = http.POST(postData);
if (httpResponseCode > 0) {
Serial.print("WA Terkirim. Kode: ");
Serial.println(httpResponseCode);
} else {
Serial.print("Gagal kirim WA. Kesalahan: ");
Serial.println(httpResponseCode);
}
http.end();
} else {
Serial.println("WiFi terputus, gagal kirim WA.");
}
}
Tahap 4: Simulasi Logika Sistem
Visualisasikan bagaimana algoritma sistem bereaksi terhadap perubahan data kelembaban tanah. Gunakan tombol di bawah grafik untuk mensimulasikan kondisi "2 Gelas" di kelas. Grafik memetakan kelembaban secara real-time, menunjukkan batas pemicu (threshold) 25% (kering/pompa ON) dan 80% (basah/pompa OFF).
Display LCD 16x2
Status Komponen
âšī¸ Konsep Kunci yang Diajarkan:
Logika pemrograman menggunakan Histeresis. Pompa menyala di titik kritis bawah (< 25%), namun tidak langsung mati di 26%. Pompa akan terus menyala hingga mencapai batas optimal kenyang air (>= 80%). Ini mencegah pompa terus-menerus menyala-mati (cycling) dengan cepat yang dapat merusak komponen fisik.
đĄ Pemecahan Masalah (Troubleshooting)
Solusi cepat untuk kendala umum yang sering dihadapi siswa selama praktik di dalam kelas. Klik pada setiap gejala masalah untuk melihat solusi teknis dan penjelasan logisnya.
Solusi Kontras: Putar potensiometer kecil berwarna biru di belakang modul I2C LCD menggunakan obeng plus kecil secara perlahan hingga tulisan terlihat jelas.
Solusi Alamat I2C: Jika backlight nyala tapi tidak ada teks setelah kontras diputar, kemungkinan alamat I2C di kode program salah. Ubah `LiquidCrystal_I2C lcd(0x27, 16, 2);` menjadi `0x3F`.
Penyebab: Banyak modul relay di pasaran menggunakan sistem "Active Low" (menyala saat dikirim sinyal 0 / LOW).
Solusi Kode: Minta siswa membuka kode program dan memodifikasi definisi konstanta logika. Ubah baris `#define PUMP_ON LOW` menjadi `HIGH`, dan sebaliknya untuk `PUMP_OFF`.
Penyebab: Sensor fisik memerlukan kalibrasi. Resistansi air tiap daerah berbeda, batas analog tidak persis 0 atau 1023.
Solusi Kalibrasi: Minta siswa melihat nilai analog mentah di "Serial Monitor". Jika saat direndam mentok di angka 750, ubah rumus map di kode: `map(sensorValue, 1023, 750, 0, 100);`. Nilai 750 adalah batas basah maksimal yang terbaca secara fisik.