#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int ledGreen = 3;
const int ledYellow = 5;
const int ledRed = 6;
const int buzzer = 9;
const int potPin = A0;
void setup() {
pinMode(ledGreen, OUTPUT);
pinMode(ledYellow, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(buzzer, OUTPUT);
lcd.init();
lcd.print("Deteksi Alkohol");
delay(500);
lcd.clear();
}
void loop() {
int potValue = analogRead(potPin); // Read potentiometer
float bac = map(potValue, 0, 1023, 0, 100) / 100.0;
// Fuzzy Tsukamoto
float tsukamotoOutput = fuzzyTsukamoto(bac);
// Fuzzy Sugeno
float sugenoOutput = fuzzySugeno(bac);
// Control Output
if (tsukamotoOutput <= 0.33) {
activateLow();
} else if (tsukamotoOutput > 0.33 && tsukamotoOutput <= 0.66) {
activateMedium();
} else {
activateHigh();
}
// Display Output
lcd.setCursor(0, 0);
lcd.print("BAC: ");
lcd.print(bac * 100, 1);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("D: ");
lcd.print(tsukamotoOutput * 100, 1);
lcd.print("D: ");
lcd.print(sugenoOutput * 100, 1);
delay(500);
}
float fuzzyTsukamoto(float bac) {
// Membership functions with updated ranges
float low = (bac <= 0.15) ? (1 - bac / 0.15) : 0; // Range: 0-15
float medium = (bac > 0.15 && bac <= 0.40) ? (1 - abs(bac - 0.275) / 0.125) : 0; // Range: 16-40
float high = (bac > 0.40) ? ((bac - 0.40) / 0.60) : 0; // Range: 41-100
// Rule evaluation and weighted average (defuzzification)
float zLow = 0.1; // Low output
float zMedium = 0.5; // Medium output
float zHigh = 1.0; // High output
// Sum of weighted outputs
float numerator = (low * zLow) + (medium * zMedium) + (high * zHigh);
float denominator = low + medium + high;
// Defuzzification: return weighted average
return (denominator == 0) ? 0 : numerator / denominator;
}
float fuzzySugeno(float bac) {
// Membership functions with updated ranges
float low = (bac <= 0.15) ? (1 - bac / 0.15) : 0; // Range: 0-15
float medium = (bac > 0.15 && bac <= 0.40) ? (1 - abs(bac - 0.275) / 0.125) : 0; // Range: 16-40
float high = (bac > 0.40) ? ((bac - 0.40) / 0.60) : 0; // Range: 41-100
// Sugeno linear functions for output (y = ax + b)
float y1 = 0.1 * bac + 0.2; // Output for low
float y2 = 0.5 * bac + 0.3; // Output for medium
float y3 = 1.0 * bac + 0.4; // Output for high
// Sum of weights
float w1 = low;
float w2 = medium;
float w3 = high;
// Sum of weighted outputs (defuzzification)
float numerator = (w1 * y1) + (w2 * y2) + (w3 * y3);
float denominator = w1 + w2 + w3;
// Defuzzification: return weighted average
return (denominator == 0) ? 0 : numerator / denominator;
}
void activateLow() {
digitalWrite(ledGreen, HIGH);
digitalWrite(ledYellow, LOW);
digitalWrite(ledRed, LOW);
tone(buzzer, 100, 200);
}
void activateMedium() {
digitalWrite(ledGreen, LOW);
digitalWrite(ledYellow, HIGH);
digitalWrite(ledRed, LOW);
tone(buzzer, 200, 300);
}
void activateHigh() {
digitalWrite(ledGreen, LOW);
digitalWrite(ledYellow, LOW);
digitalWrite(ledRed, HIGH);
tone(buzzer, 400, 200);
}