#include <Servo.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
Servo waterPump;
const int soilMoisturePin = A0;
const int DHT_PIN = 15;
const int WATER_PUMP_PIN = 9;
DHT dht(DHT_PIN, DHT22);
LiquidCrystal_I2C lcd(0x27, 16, 2);
double ZKering(double a_predikat) {
double kering = 0; // Water pump off
double basah = 100; // Water pump at full speed
double ZKering = kering + a_predikat * (basah - kering);
return ZKering;
}
double LBasah(double a_predikat) {
double kering = 0; // Water pump off
double basah = 100; // Water pump at full speed
double LBasah = a_predikat * (basah - kering) + kering;
return LBasah;
}
void setup() {
Serial.begin(115200);
waterPump.attach(WATER_PUMP_PIN);
lcd.begin(16, 2);
lcd.init();
lcd.backlight();
dht.begin();
}
void loop() {
// Read soil moisture level
int soilMoistureValue = analogRead(soilMoisturePin);
// Map the soil moisture value to a range of 0 to 100
double y = map(soilMoistureValue, 0, 1023, 0, 100);
Serial.println("=========Soil Moisture=========");
Serial.println("Moisture Level: " + String(y, 0));
// Fuzzification
double Soil_Dry;
if (y >= 70) {
Soil_Dry = 0;
Serial.println("μSoil_Dry [Y]: " + String(Soil_Dry, 0));
} else if (30 < y && y < 70) {
Soil_Dry = (70 - y) / (70 - 30);
Serial.println("μSoil_Dry [Y]: " + String(Soil_Dry, 4));
} else if (y <= 30) {
Soil_Dry = 1;
Serial.println("μSoil_Dry [Y]: " + String(Soil_Dry, 0));
}
double Soil_Wet;
if (y <= 30) {
Soil_Wet = 0;
Serial.println("μSoil_Wet [Y]: " + String(Soil_Wet, 0));
} else if (30 < y && y < 70) {
Soil_Wet = (y - 30) / (70 - 30);
Serial.println("μSoil_Wet [Y]: " + String(Soil_Wet, 4));
} else if (y >= 70) {
Soil_Wet = 1;
Serial.println("μSoil_Wet [Y]: " + String(Soil_Wet, 0));
}
// Inferencing
Serial.println("===========Inferencing==========");
// [R1] Kering = Pump off
double a_predikat1 = min(Soil_Dry, Soil_Wet);
Serial.println("a_predikat 1: " + String(a_predikat1, 4));
double Z1 = ZKering(a_predikat1);
Serial.println("z1: " + String(Z1, 0));
// [R2] Basah = Pump at full speed
double a_predikat2 = min(Soil_Wet, Soil_Dry);
Serial.println("a_predikat 2: " + String(a_predikat2, 4));
double Z2 = LBasah(a_predikat2);
Serial.println("z2: " + String(Z2, 0));
// Defuzzification
Serial.println("=========Defuzzification========");
double z = (a_predikat1 * Z1 + a_predikat2 * Z2) / (a_predikat1 + a_predikat2);
Serial.println("Resulting Pump Speed: " + String(z, 3));
// Control the water pump based on the inferred pump speed
int pumpSpeed = int(z);
waterPump.write(pumpSpeed);
// Display the result on LCD
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Soil Moisture:");
lcd.setCursor(0, 1);
lcd.print(y, 0);
lcd.print("%");
delay(1000);
}