#include <Arduino.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Inisialisasi LCD (alamat I2C default: 0x27)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin untuk potensiometer
const int potAlkoholPin = A0;
const int slideAlarmPin = A1;
// Pin untuk LED
const int ledGreenPin = 9;
const int ledYellowPin = 10;
const int ledRedPin = 11;
// Fungsi membaca nilai potensiometer
float readPotentiometer(int pin, float minVal, float maxVal) {
int value = analogRead(pin);
return map(value, 0, 1023, minVal, maxVal);
}
// Fungsi keanggotaan untuk kadar alkohol
float membershipLow(float x) {
if (x <= 15) return 1.0;
if (x > 15 && x < 40) return (40 - x) / 25.0;
return 0.0;
}
float membershipMedium(float x) {
if (x > 15 && x < 40) return (x - 15) / 25.0;
if (x >= 40 && x <= 100) return (100 - x) / 60.0;
return 0.0;
}
float membershipHigh(float x) {
if (x >= 40) return (x - 40) / 60.0;
return 0.0;
}
// Fungsi keanggotaan untuk intensitas alarm
float membershipSoft(float x) {
if (x <= 100) return 1.0;
if (x > 100 && x < 200) return (200 - x) / 100.0;
return 0.0;
}
float membershipMediumAlarm(float x) {
if (x > 100 && x < 200) return (x - 100) / 100.0;
if (x >= 200 && x <= 300) return (300 - x) / 100.0;
return 0.0;
}
float membershipLoud(float x) {
if (x >= 200) return (x - 200) / 100.0;
return 0.0;
}
// Fungsi defuzzifikasi
float defuzzify(float alkohol, float alarm) {
// Derajat keanggotaan kadar alkohol
float lowAlkohol = membershipLow(alkohol);
float medAlkohol = membershipMedium(alkohol);
float highAlkohol = membershipHigh(alkohol);
// Derajat keanggotaan intensitas alarm
float softAlarm = membershipSoft(alarm);
float medAlarm = membershipMediumAlarm(alarm);
float loudAlarm = membershipLoud(alarm);
// Aturan fuzzy
float R1 = min(lowAlkohol, softAlarm);
float R2 = min(lowAlkohol, medAlarm);
float R3 = min(lowAlkohol, loudAlarm);
float R4 = min(medAlkohol, softAlarm);
float R5 = min(medAlkohol, medAlarm);
float R6 = min(medAlkohol, loudAlarm);
float R7 = min(highAlkohol, softAlarm);
float R8 = min(highAlkohol, medAlarm);
float R9 = min(highAlkohol, loudAlarm);
// Output z untuk setiap aturan
float z1 = 532, z2 = 700, z3 = 700; // Hijau, Kuning, Merah
float z4 = 568, z5 = 700, z6 = 700;
float z7 = 700, z8 = 700, z9 = 700;
// Hitungan defuzzifikasi
float numerator = (R1 * z1) + (R2 * z2) + (R3 * z3) +
(R4 * z4) + (R5 * z5) + (R6 * z6) +
(R7 * z7) + (R8 * z8) + (R9 * z9);
float denominator = R1 + R2 + R3 + R4 + R5 + R6 + R7 + R8 + R9;
if (denominator == 0) return 0;
return numerator / denominator - 0.01;
}
// Fungsi menyalakan LED berdasarkan nilai crisp
String setLED(float crispValue) {
if (crispValue <= 550) {
digitalWrite(ledGreenPin, HIGH);
digitalWrite(ledYellowPin, LOW);
digitalWrite(ledRedPin, LOW);
return "Hijau";
} else if (crispValue > 550 && crispValue <= 650) {
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledYellowPin, HIGH);
digitalWrite(ledRedPin, LOW);
return "Kuning";
} else {
digitalWrite(ledGreenPin, LOW);
digitalWrite(ledYellowPin, LOW);
digitalWrite(ledRedPin, HIGH);
return "Merah";
}
}
void setup() {
pinMode(ledGreenPin, OUTPUT);
pinMode(ledYellowPin, OUTPUT);
pinMode(ledRedPin, OUTPUT);
lcd.init();
lcd.backlight();
Serial.begin(9600);
}
void loop() {
float kadarAlkohol = readPotentiometer(potAlkoholPin, 0, 100);
float intensitasAlarm = readPotentiometer(slideAlarmPin, 0, 300);
float crispOutput = defuzzify(kadarAlkohol, intensitasAlarm);
String ledStatus = setLED(crispOutput);
Serial.print("Alkohol: ");
Serial.print(kadarAlkohol);
Serial.print(" | Alarm: ");
Serial.print(intensitasAlarm);
Serial.print(" | Defuzzy: ");
Serial.print(crispOutput);
Serial.print(" | LED: ");
Serial.println(ledStatus);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("A: ");
lcd.print(kadarAlkohol);
lcd.print("M: ");
lcd.print(intensitasAlarm);
lcd.setCursor(0, 1);
lcd.print("D: ");
lcd.print(crispOutput);
lcd.print(" ");
lcd.print(ledStatus);
delay(500);
}