#include <Wire.h> // I2C communication
#include <RTClib.h> // RTC library for DS1307
#include <DHT.h> // DHT sensor library
#include <Fuzzy.h> // Fuzzy logic library
#define DHTPIN 8 // DHT sensor pin
#define DHTTYPE DHT22 // Change to DHT11 if needed
DHT dht(DHTPIN, DHTTYPE); // Instance for DHT sensor
RTC_DS1307 rtc; // Instance for RTC
Fuzzy *fuzzy = new Fuzzy(); // Instance for Fuzzy logic
// Pump pins
#define POMPA1 6 // Pin for Pump 1 (controlled by fuzzy logic)
#define POMPA2 7 // Pin for Pump 2 (controlled by time logic)
// Timing variables
unsigned long previousMillisPump1 = 0;
unsigned long previousMillisPump2 = 0;
unsigned long intervalPump1 = 0; // Will be set by fuzzy logic
unsigned long intervalPump2 = 10000; // Pump 2 runs for 10 seconds
bool isPump1On = false;
bool isPump2On = false;
// Function to set up fuzzy logic rules
void setupFuzzyLogic() {
FuzzyInput *humidityInput = new FuzzyInput(1);
FuzzySet *lowHumidity = new FuzzySet(20, 40, 40, 60); // Low humidity range
FuzzySet *mediumHumidity = new FuzzySet(50, 70, 70, 90); // Medium humidity range
FuzzySet *highHumidity = new FuzzySet(80, 100, 100, 101); // High humidity range
humidityInput->addFuzzySet(lowHumidity);
humidityInput->addFuzzySet(mediumHumidity);
humidityInput->addFuzzySet(highHumidity);
fuzzy->addFuzzyInput(humidityInput);
FuzzyOutput *wateringOutput = new FuzzyOutput(1);
FuzzySet *shortWatering = new FuzzySet(0, 5, 5, 10);
FuzzySet *mediumWatering = new FuzzySet(10, 15, 15, 20);
FuzzySet *longWatering = new FuzzySet(20, 30, 30, 40);
wateringOutput->addFuzzySet(shortWatering);
wateringOutput->addFuzzySet(mediumWatering);
wateringOutput->addFuzzySet(longWatering);
fuzzy->addFuzzyOutput(wateringOutput);
FuzzyRuleConsequent *shortWateringConsequent = new FuzzyRuleConsequent();
shortWateringConsequent->addOutput(shortWatering);
FuzzyRuleConsequent *mediumWateringConsequent = new FuzzyRuleConsequent();
mediumWateringConsequent->addOutput(mediumWatering);
FuzzyRuleConsequent *longWateringConsequent = new FuzzyRuleConsequent();
longWateringConsequent->addOutput(longWatering);
FuzzyRuleAntecedent *lowHumidityAntecedent = new FuzzyRuleAntecedent();
lowHumidityAntecedent->joinSingle(lowHumidity);
FuzzyRule *fuzzyRule01 = new FuzzyRule(1, lowHumidityAntecedent, longWateringConsequent);
fuzzy->addFuzzyRule(fuzzyRule01);
FuzzyRuleAntecedent *mediumHumidityAntecedent = new FuzzyRuleAntecedent();
mediumHumidityAntecedent->joinSingle(mediumHumidity);
FuzzyRule *fuzzyRule02 = new FuzzyRule(2, mediumHumidityAntecedent, mediumWateringConsequent);
fuzzy->addFuzzyRule(fuzzyRule02);
FuzzyRuleAntecedent *highHumidityAntecedent = new FuzzyRuleAntecedent();
highHumidityAntecedent->joinSingle(highHumidity);
FuzzyRule *fuzzyRule03 = new FuzzyRule(3, highHumidityAntecedent, shortWateringConsequent);
fuzzy->addFuzzyRule(fuzzyRule03);
}
void setup() {
Serial.begin(9600);
dht.begin(); // Initialize the DHT sensor
Wire.begin(); // Start I2C communication
rtc.begin(); // Initialize RTC
pinMode(POMPA1, OUTPUT);
pinMode(POMPA2, OUTPUT);
if (!rtc.isrunning()) {
Serial.println("RTC is not running. Setting to compile-time.");
rtc.adjust(DateTime(__DATE__, __TIME__)); // Set the RTC time if not running
}
setupFuzzyLogic(); // Set up fuzzy logic rules
}
void loop() {
unsigned long currentMillis = millis();
// Read humidity from DHT sensor
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
Serial.print("humidity: ");
Serial.println(humidity);
Serial.print("temperature: ");
Serial.println(temperature);
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Failed to read from DHT sensor.");
return; // Exit the loop if the reading fails
}
// Fuzzy logic for Pump 1
fuzzy->setInput(1, humidity); // Set fuzzy logic input for humidity
fuzzy->fuzzify(); // Run fuzzy logic
float wateringTime = fuzzy->defuzzify(1); // Get the watering duration
Serial.print("Waktu penyiraman: ");
Serial.print(intervalPump1);
Serial.println(" detik.");
DateTime now = rtc.now();
intervalPump1 = wateringTime * 1000; // Set the interval in milliseconds
if ((now.hour() == 9 && now.minute() == 0) || (now.hour() == 15 && now.minute() == 0)) {
if (!isPump1On) {
digitalWrite(POMPA1, LOW); // Aktifkan Pompa 1
previousMillisPump1 = currentMillis; // Setel ulang timer
isPump1On = true; // Tandai Pompa 1 sebagai ON
}
}
// Matikan pompa setelah interval fuzzy logic berakhir
if (isPump1On && (currentMillis - previousMillisPump1) >= intervalPump1) {
digitalWrite(POMPA1, HIGH); // Matikan Pompa 1
isPump1On = false; // Tandai Pompa 1 sebagai OFF
}
// Time-based logic for Pump 2
if (now.hour() == 6 && now.minute() == 0 && !isPump2On) {
digitalWrite(POMPA2, HIGH); // Activate Pump 2 at 6:00 AM
previousMillisPump2 = currentMillis; // Reset the timer
isPump2On = true; // Mark Pump 2 as ON
}
if ((currentMillis - previousMillisPump2) >= intervalPump2 && isPump2On) {
digitalWrite(POMPA2, LOW); // Deactivate Pump 2
isPump2On = false; // Mark Pump 2 as OFF
}
delay(2000); // Delay before the next loop iteration
}