/*
* KODE UNTUK SESI 6: MEMBERI WAJAH
* Tujuan: Menampilkan data sensor kelembapan pada layar I2C (LCD atau OLED).
*
* Deskripsi:
* Kode ini mengambil data dari sensor dan menampilkannya di layar,
* membuat Sang Penjaga lebih mandiri tanpa perlu terhubung ke komputer.
*
* PENTING:
* 1. Instal Library: Buka Library Manager di Arduino IDE (Sketch > Include Library > Manage Libraries)
* - Untuk LCD: Instal "LiquidCrystal I2C" by Frank de Brabander.
* - Untuk OLED: Instal "U8g2" by oliver.
* 2. Pilih Salah Satu: Kode di bawah ini berisi bagian untuk LCD dan OLED.
* HAPUS atau BERI TANDA KOMENTAR (//) pada bagian yang tidak Anda gunakan.
*
* Rangkaian (Sama untuk LCD & OLED I2C):
* - VCC layar -> VIN atau 5V pada ESP32
* - GND layar -> GND pada ESP32
* - SDA layar -> GPIO 21 pada ESP32
* - SCL layar -> GPIO 22 pada ESP32
* - Sensor Kelembapan tetap terhubung seperti di Sesi 5.
*/
#include <Wire.h> // Library wajib untuk komunikasi I2C
// --- BAGIAN UNTUK LCD 16x2 I2C ---
// Hapus komentar di bawah ini jika Anda menggunakan LCD
// #include <LiquidCrystal_I2C.h>
// // Alamat I2C umum adalah 0x27 atau 0x3F. Coba ganti jika layar tidak terdeteksi.
// LiquidCrystal_I2C lcd(0x27, 16, 2); // (alamat, kolom, baris)
// --- BAGIAN UNTUK OLED SSD1306 I2C ---
// Menggunakan library U8g2 yang lebih modern dan fleksibel
#include <U8g2lib.h>
// Constructor ini menggunakan hardware I2C ESP32.
// U8G2_R0 = No rotation
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Pin sensor kelembapan
const int soilPin = 34;
// Variabel untuk kalibrasi (UBAH NILAI INI SESUAI PENGUKURAN ANDA)
// Ukur nilai sensor saat di udara (kering) dan di dalam air (basah)
const int nilaiUdara = 4095; // Nilai saat sensor kering
const int nilaiAir = 1800; // Nilai saat sensor basah tercelup air
void setup() {
Serial.begin(115200);
Wire.begin(); // Inisialisasi I2C
// --- INISIALISASI UNTUK LCD ---
// Hapus komentar di bawah ini jika Anda menggunakan LCD
// lcd.init();
// lcd.backlight();
// lcd.setCursor(0, 0);
// lcd.print("Penjaga Siap!");
// delay(2000);
// --- INISIALISASI UNTUK OLED ---
// Hapus komentar di bawah ini jika Anda menggunakan OLED
if (!u8g2.begin()) {
Serial.println(F("Gagal menemukan OLED"));
while (true); // Loop selamanya jika gagal
}
u8g2.clearBuffer(); // Hapus buffer internal
u8g2.setFont(u8g2_font_ncenB10_tr); // Pilih font
u8g2.drawStr(18, 36, "Penjaga Siap!"); // Tulis string (posisi x, y, teks)
u8g2.sendBuffer(); // Kirim buffer ke layar
delay(2000);
}
void loop() {
int nilaiRasa = analogRead(soilPin);
// Memetakan nilai sensor ke rentang persentase 0-100%
// map(value, fromLow, fromHigh, toLow, toHigh)
int persentaseLembap = map(nilaiRasa, nilaiUdara, nilaiAir, 0, 100);
// Memastikan nilai persentase tidak di luar 0-100
if (persentaseLembap > 100) {
persentaseLembap = 100;
}
if (persentaseLembap < 0) {
persentaseLembap = 0;
}
// --- TAMPILKAN KE LCD ---
// Hapus komentar di bawah ini jika Anda menggunakan LCD
// lcd.clear();
// lcd.setCursor(0, 0); // Kolom 0, Baris 0
// lcd.print("Lembap: ");
// lcd.print(persentaseLembap);
// lcd.print("%");
// lcd.setCursor(0, 1); // Kolom 0, Baris 1
// if (persentaseLembap < 30) {
// lcd.print("Status: KERING");
// } else {
// lcd.print("Status: AMAN");
// }
// --- TAMPILKAN KE OLED ---
// Hapus komentar di bawah ini jika Anda menggunakan OLED
u8g2.clearBuffer(); // Selalu mulai dengan membersihkan buffer
// Menampilkan persentase kelembapan dengan font besar
u8g2.setFont(u8g2_font_logisoso18_tr); // Pilih font yang lebih besar
u8g2.setCursor(0, 22); // Atur posisi kursor
u8g2.print("Lembap: ");
u8g2.print(persentaseLembap);
u8g2.print("%");
// Menampilkan status dengan font yang lebih kecil
u8g2.setFont(u8g2_font_ncenB08_tr); // Pilih font yang lebih kecil
u8g2.setCursor(0, 45); // Atur posisi kursor di bawah baris pertama
if (persentaseLembap < 30) {
u8g2.print("Status: TANAH KERING");
} else if (persentaseLembap > 85) {
u8g2.print("Status: TERLALU BASAH");
} else {
u8g2.print("Status: KONDISI AMAN");
}
u8g2.sendBuffer(); // Perintah wajib untuk menampilkan ke layar
delay(1000);
}