Pengkodean & Debugging Sistem

Menulis dan menguji kode Smart Agriculture System secara bertahap dengan teknik debugging sistematis.

90 Menit
Modul 5 & 6: PjBL Utama — Smart Agriculture System
Pertemuan 14

TPTujuan Pembelajaran

  1. Peserta didik dapat menulis kode program Smart Agriculture System secara bertahap
  2. Peserta didik dapat menggunakan Serial Monitor untuk debugging sistem terintegrasi
  3. Peserta didik dapat mengidentifikasi dan memperbaiki bug pada sistem multi-sensor
  4. Peserta didik dapat menerapkan pola non-blocking timer dalam program utuh

Strategi Coding Bertahap

Kalian sudah memiliki arsitektur di pertemuan sebelumnya. Sekarang saatnya menulis kode! Aturan nomor satu dalam pemrograman proyek besar adalah: Jangan menulis semua kode sekaligus lalu berharap langsung jalan!

Kita akan menggunakan pendekatan modular: tulis sedikit, uji (test), perbaiki, lalu tambahkan fitur lain.

Kode Utama Sistem (Skeleton)

Berikut adalah kerangka kode (skeleton) dan fungsi kunci untuk Smart Agriculture System kita. Perhatikan bagaimana kita memecah program besar menjadi fungsi-fungsi kecil seperti bacaSemua(), kontrolAktuator(), dan updateLCD().

Smart_Agriculture.ino
cpp
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// ── Konfigurasi Pin ──
#define DHT_PIN     2
#define SOIL_PIN    A0
#define LDR_PIN     A1
#define PIR_PIN     3
#define POMPA_PIN   7
#define BUZZER_PIN  8
#define LED_R       9
#define LED_G       10
#define LED_B       11

DHT dht(DHT_PIN, DHT11);
LiquidCrystal_I2C lcd(0x27, 16, 2);

// ── Batas Ambang (Thresholds) ──
const float SUHU_MAX       = 35.0;
const int   TANAH_KERING   = 30;   // %
const int   CAHAYA_REDUP   = 400;

// ── Variabel Non-blocking Timers (millis) ──
unsigned long prevSensor = 0, prevLCD = 0;
const long INTERVAL_SENSOR = 2000, INTERVAL_LCD = 1000;

// ── Status Sistem ──
float suhu = 0, kelembaban = 0;
int tanahPct = 0, cahaya = 0;
bool pompaNyala = false;

void setup() {
  Serial.begin(9600);
  dht.begin();
  lcd.init(); 
  lcd.backlight();
  
  pinMode(POMPA_PIN, OUTPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(LED_R, OUTPUT); pinMode(LED_G, OUTPUT); pinMode(LED_B, OUTPUT);
  
  Serial.println("=== Smart Agriculture System v1.0 ===");
}

void bacaSemua() {
  suhu       = dht.readTemperature();
  kelembaban = dht.readHumidity();
  // Konversi nilai ADC analog tanah menjadi persen (0-100%)
  // Sesuaikan nilai 850 (kering) dan 350 (basah) dengan hasil kalibrasi kalian
  tanahPct   = constrain(map(analogRead(SOIL_PIN), 850, 350, 0, 100), 0, 100);
  cahaya     = analogRead(LDR_PIN);
}

void kontrolAktuator() {
  // 1. Auto watering: Nyalakan pompa jika tanah kering
  pompaNyala = (tanahPct < TANAH_KERING);
  digitalWrite(POMPA_PIN, pompaNyala);
  
  // 2. Status LED Visual
  bool ada_masalah = (suhu > SUHU_MAX) || (tanahPct < TANAH_KERING);
  analogWrite(LED_R, ada_masalah ? 255 : 0);
  analogWrite(LED_G, ada_masalah ? 0 : 255);
  analogWrite(LED_B, 0); // Biru dimatikan sementara
  
  // 3. Alarm Suhu Panas
  if (suhu > SUHU_MAX) { 
    tone(BUZZER_PIN, 1000, 500); 
  } else {
    noTone(BUZZER_PIN);
  }
}

void updateLCD() {
  lcd.clear();
  lcd.setCursor(0,0); 
  lcd.print("T:"); lcd.print(suhu,1); lcd.print("C H:"); lcd.print(kelembaban,0); lcd.print("%");
  
  lcd.setCursor(0,1); 
  lcd.print("Tanah:"); lcd.print(tanahPct); lcd.print("% P:"); lcd.print(pompaNyala ? "ON" : "OFF");
}

void loop() {
  unsigned long now = millis();
  
  // Interval pembacaan sensor dan aksi aktuator
  if (now - prevSensor >= INTERVAL_SENSOR) {
    prevSensor = now;
    bacaSemua();
    kontrolAktuator();
    
    // Debugging via Serial
    Serial.print("T:"); Serial.print(suhu); 
    Serial.print("C | Tanah:"); Serial.print(tanahPct); Serial.println("%");
  }
  
  // Interval update LCD terpisah
  if (now - prevLCD >= INTERVAL_LCD) {
    prevLCD = now;
    updateLCD();
  }
}

Debugging Sistematis

"Kode saya sudah di-upload, tapi layarnya kosong dan pompanya menyala terus!" — Selamat datang di dunia debugging!

Gunakan Serial Monitor sebagai mata Anda ke dalam otak Arduino. Pastikan sensor terbaca dengan benar sebelum menyalahkan pompa.

Serial Monitor Output
=== Smart Agriculture System v1.0 === T:nanC | Tanah:0% T:nanC | Tanah:0% T:31.5C | Tanah:85% T:31.5C | Tanah:85%

Troubleshooting

Masalah:Suhu terbaca 'nan' (Not a Number)

Solusi:Kabel data DHT11 terlepas, atau pin yang dideklarasikan di kode salah.


Masalah:Kelembaban tanah mentok di 0% atau 100% terus

Solusi:Sensor tidak tertancap sempurna ke tanah, kabel terbalik, atau nilai batas di fungsi map() perlu dikalibrasi ulang (bukan 850-350).


Masalah:LCD nyala tapi muncul kotak-kotak hitam

Solusi:Putar potensiometer di belakang modul I2C LCD dengan obeng kecil sampai tulisan terlihat.

Unit Testing (Pengujian Komponen)

Jika kalian menemukan error kompleks, mundurlah selangkah. Uji satu per satu (Unit Testing).

  • Test 1: Buat script baru yang HANYA membaca DHT11. Berhasil? Lanjut.
  • Test 2: Buat script baru yang HANYA menyalakan pompa air 5 detik lalu mati 5 detik. Pompa jalan? Relay bunyi 'klik'? Berarti hardware aman.

Integrasi & Latihan

Dalam fungsi kontrolAktuator(), pompa air akan menyala berdasarkan kondisi logika apa?

Tantangan

Aktivitas Tim: Integrasi Sensor

  1. Rakitlah minimal DHT11, Soil Moisture, dan sebuah LED (sebagai pengganti pompa sementara) di breadboard.
  2. Salin kode skeleton ke Arduino IDE.
  3. Sesuaikan nomor PIN sesuai dengan rakitan tim kalian.
  4. Upload dan pantau Serial Monitor. Berikan tantangan ke sensor (pegang DHT agar suhu naik, cabut sensor tanah dari pot). Apakah LED menyala sesuai skenario?
Kesimpulan Pertemuan 14
  • Penulisan program yang baik dipecah menjadi fungsi-fungsi spesifik (modular).
  • Gunakan struktur `millis()` untuk menjalankan banyak tugas bersamaan tanpa saling menunggu (non-blocking).
  • Selalu gunakan fungsi `Serial.print()` untuk melacak bug dan memantau status variabel.
  • Lakukan unit testing (menguji hardware satu per satu) sebelum menggabungkan semua komponen.

RRefleksi Coding

Luangkan 2–3 menit untuk menjawab pertanyaan di bawah secara jujur.

Kejutan & Penemuan

Apa yang paling mengejutkan atau menarik hari ini?

Error (bug) apa yang paling berkesan dan berhasil kamu pecahkan hari ini?

Masih Membingungkan

Apa yang masih membingungkan atau ingin kamu pahami lebih dalam?

Apakah kamu sudah sepenuhnya paham perbedaan program menggunakan delay() vs millis()?

Rencana Selanjutnya

Apa yang ingin kamu coba atau pelajari minggu depan?

Apa rencana perbaikan hardware/kode untuk pertemuan berikutnya?

Refleksi tidak dinilai — ini adalah ruang jujurmu untuk berpikir.