/*
============================================================
TUGAS: Simulasi IoT ESP32 - Pertanian Presisi Berbasis Digital
Komponen:
- Sensor DHT22 (suhu udara) -> pin GPIO 15
- Potensiometer (soil moisture) -> pin analog GPIO 34
- Relay Pompa Air -> pin GPIO 26
Logika:
- Jika soil_moisture_percent < 40% -> Relay ON (pompa nyala)
- Jika soil_moisture_percent >= 40% -> Relay OFF (pompa mati)
Output:
- JSON payload ke Serial Monitor setiap 2 detik
============================================================
*/
#include <DHT.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// ---------- Konfigurasi Pin ----------
#define DHTPIN 15
#define DHTTYPE DHT22
#define SOIL_PIN 34
#define RELAY_PIN 26
// LCD I2C menggunakan pin default I2C ESP32: SDA = GPIO 21, SCL = GPIO 22
// ---------- Konfigurasi LCD ----------
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ---------- Konfigurasi Logika ----------
const float SOIL_MOISTURE_THRESHOLD = 40.0;
const unsigned long INTERVAL_MS = 2000;
const float ANNUAL_RAINFALL_MM = 1200.0;
DHT dht(DHTPIN, DHTTYPE);
unsigned long lastSendTime = 0;
void setup() {
Serial.begin(115200);
dht.begin();
pinMode(RELAY_PIN, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Precision Farm");
lcd.setCursor(0, 1);
lcd.print("Initializing...");
Serial.println("=== Sistem IoT Pertanian Presisi - ESP32 ===");
Serial.println("Inisialisasi sensor DHT22 & Potensiometer...");
delay(2000);
lcd.clear();
}
void loop() {
unsigned long currentTime = millis();
if (currentTime - lastSendTime >= INTERVAL_MS) {
lastSendTime = currentTime;
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature) || isnan(humidity)) {
Serial.println("{\"error\": \"Gagal membaca sensor DHT22\"}");
return;
}
int rawSoil = analogRead(SOIL_PIN);
float soilMoisturePercent = map(rawSoil, 0, 4095, 0, 100);
soilMoisturePercent = constrain(soilMoisturePercent, 0, 100);
String statusPompa;
if (soilMoisturePercent < SOIL_MOISTURE_THRESHOLD) {
digitalWrite(RELAY_PIN, HIGH);
statusPompa = "ON";
} else {
digitalWrite(RELAY_PIN, LOW);
statusPompa = "OFF";
}
StaticJsonDocument<256> doc;
doc["avg_temperature_c"] = round(temperature * 10) / 10.0;
doc["annual_rainfall_mm"] = ANNUAL_RAINFALL_MM;
doc["soil_moisture_percent"] = round(soilMoisturePercent * 10) / 10.0;
doc["status_pompa"] = statusPompa;
serializeJson(doc, Serial);
Serial.println();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("T:");
lcd.print(temperature, 1);
lcd.print("C H:");
lcd.print(humidity, 0);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("Soil:");
lcd.print(soilMoisturePercent, 0);
lcd.print("% ");
lcd.print(statusPompa);
}
}