#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
// --- Konfigurasi Pin ---
#define DHTPIN 7 // Pin Data DHT22 terhubung ke Digital 2
#define DHTTYPE DHT22 // Menentukan tipe sensor yaitu DHT22
#define PELTIER_PIN 8 // Pin Relay 1 (Peltier) terhubung ke Digital 3
#define LAMP_PIN 9 // Pin Relay 2 (Lampu) terhubung ke Digital 4
// --- Inisialisasi Alamat I2C LCD ---
// Biasanya alamat LCD I2C adalah 0x27 atau 0x3F. Ukuran LCD 20 kolom x 4 baris.
LiquidCrystal_I2C lcd(0x27, 20, 4);
// --- Inisialisasi Sensor DHT ---
DHT dht(DHTPIN, DHTTYPE);
// --- Konfigurasi Parameter Suhu ---
const float SUHU_MIN = 10.0; // Batas bawah suhu ideal (°C)
const float SUHU_MAX = 15.0; // Batas atas suhu ideal (°C)
void setup() {
// Mengatur pin relay sebagai OUTPUT
pinMode(PELTIER_PIN, OUTPUT);
pinMode(LAMP_PIN, OUTPUT);
// Kondisi awal: Matikan semua aktuator saat pertama kali menyala
// Catatan: Jika menggunakan modul relay Active-LOW, ubah HIGH menjadi LOW
digitalWrite(PELTIER_PIN, LOW);
digitalWrite(LAMP_PIN, LOW);
// Inisialisasi Sensor DHT22
dht.begin();
// Inisialisasi LCD Display
lcd.init();
lcd.backlight();
// Tampilan Selamat Datang (Booting)
lcd.setCursor(0, 0);
lcd.print("====================");
lcd.setCursor(0, 1);
lcd.print(" PENGKONDISI SUHU ");
lcd.setCursor(0, 2);
lcd.print(" PENYIMPANAN TOMAT ");
lcd.setCursor(0, 3);
lcd.print("====================");
delay(3000); // Tampilkan selama 3 detik
lcd.clear();
}
void loop() {
// Membaca data suhu dalam satuan Celcius
float suhu = dht.readTemperature();
// Membaca data kelembaban udara (%)
float kelembaban = dht.readHumidity();
// --- 1. Logika Proteksi / Pengaman (Fail-Safe) ---
// Memeriksa apakah sensor DHT22 gagal merespons atau rusak
if (isnan(suhu) || isnan(kelembaban)) {
// Demi keamanan komoditas, matikan semua sistem pemanas/pendingin
digitalWrite(PELTIER_PIN, LOW);
digitalWrite(LAMP_PIN, LOW);
// Tampilkan pesan error di LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" ![ERROR]! ");
lcd.setCursor(0, 1);
lcd.print(" SENSOR DHT22 LEPAS ");
lcd.setCursor(0, 2);
lcd.print(" ATAU RUSAK! ");
lcd.setCursor(0, 3);
lcd.print("SISTEM DIMATIKAN... ");
delay(2000); // Tunggu 2 detik sebelum mencoba membaca ulang
return; // Kembali ke awal loop()
}
// --- 2. Logika Utama Kontrol Suhu (Thresholding) ---
String statusPeltier = "OFF";
String statusLampu = "OFF";
if (suhu > SUHU_MAX) {
// Kondisi A: Terlalu Panas (> 15°C) -> Nyalakan Pendingin
digitalWrite(PELTIER_PIN, HIGH);
digitalWrite(LAMP_PIN, LOW);
statusPeltier = "ON ";
statusLampu = "OFF";
}
else if (suhu < SUHU_MIN) {
// Kondisi B: Terlalu Dingin (< 10°C) -> Nyalakan Pemanas
digitalWrite(PELTIER_PIN, LOW);
digitalWrite(LAMP_PIN, HIGH);
statusPeltier = "OFF";
statusLampu = "ON ";
}
else {
// Kondisi C: Suhu Ideal (10°C - 15°C) -> Semua Dimatikan (Hemat Energi)
digitalWrite(PELTIER_PIN, LOW);
digitalWrite(LAMP_PIN, LOW);
statusPeltier = "OFF";
statusLampu = "OFF";
}
// --- 3. Menampilkan Informasi ke Layar LCD 20x4 ---
// Baris 1: Informasi Suhu Riil
lcd.setCursor(0, 0);
lcd.print("SUHU RUANG : ");
lcd.print(suhu, 1); // Menampilkan 1 angka di belakang koma
lcd.print((char)223); // Mencetak simbol derajat (°)
lcd.print("C ");
// Baris 2: Informasi Kelembaban Udara
lcd.setCursor(0, 1);
lcd.print("KELEMBABAN : ");
lcd.print(kelembaban, 1);
lcd.print("% ");
// Baris 3: Menampilkan Target Aturan Suhu
lcd.setCursor(0, 2);
lcd.print("TARGET : 10-15");
lcd.print((char)223);
lcd.print("C");
// Baris 4: Menampilkan Status Aktuator Aktif
lcd.setCursor(0, 3);
lcd.print("Peltier:");
lcd.print(statusPeltier);
lcd.print(" Lmp:");
lcd.print(statusLampu);
// --- 4. Jeda Waktu Stabilitas (Anti-Flickering Delay) ---
// Memberikan waktu jeda agar relay tidak cepat aus akibat fluktuasi kecil
delay(1500);
}