// penambahan library fuzzy
#include <Fuzzy.h>
#include <FuzzyComposition.h>
#include <FuzzyInput.h>
#include <FuzzyIO.h>
#include <FuzzyOutput.h>
#include <FuzzyRule.h>
#include <FuzzyRuleAntecedent.h>
#include <FuzzyRuleConsequent.h>
#include <FuzzySet.h>
// penambahan Library LCD I2C
#include <LiquidCrystal_I2C.h>
// Alamat I2C untuk LCD (umumnya 0x27)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Inisialisasi pin
int LDR = A1;
int trg = 4;
int ech = 3;
int led = 9;
Fuzzy *fuzzy = new Fuzzy();
void setup()
{
Serial.begin(9600);
pinMode(LDR, INPUT); // pin A1 sebagai input
pinMode(trg, OUTPUT); // pin 4 sebagai output
pinMode(ech, INPUT); // pin 3 sebagai input
pinMode(led, OUTPUT); // pin 9 sebagai output
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Starting...");
// Mengatur fuzzy ,jarak antara 0 - 400cm
FuzzySet *pendek = new FuzzySet(0, 0, 0, 120); //trapizoid MF (a,b,c,d)
FuzzySet *mid = new FuzzySet(60, 120, 120, 180);
FuzzySet *panjang = new FuzzySet(120, 180, 180, 240);
FuzzySet *sangat_panjang = new FuzzySet(180, 240, 400, 400);
// ldr (potensio) ,ADC(0-1023 di wokwi)
// ldr (0-100000 lux=> 1015-8 resistance value in wokwi)
FuzzySet *rendahldr = new FuzzySet(0, 0, 0, 100);
FuzzySet *midldr = new FuzzySet(60, 200, 500, 700);
FuzzySet *tinggildr = new FuzzySet(400 ,700, 1015, 1015);
// kecerahan
FuzzySet *mati = new FuzzySet(0, 0, 0, 0);
FuzzySet *redup = new FuzzySet(0, 0, 25, 100);
FuzzySet *menyala = new FuzzySet(55, 100, 155, 200);
FuzzySet *terang = new FuzzySet(155, 230, 255, 255);
// variable distance with universe 0-400 as input
FuzzyInput *jarak = new FuzzyInput(1);
jarak->addFuzzySet(pendek);
jarak->addFuzzySet(mid);
jarak->addFuzzySet(panjang);
fuzzy->addFuzzyInput(jarak);
// variable ldr with universe 0-1015 as input
FuzzyInput *ldr = new FuzzyInput(2);
ldr->addFuzzySet(rendahldr);
ldr->addFuzzySet(midldr);
ldr->addFuzzySet(tinggildr);
fuzzy->addFuzzyInput(ldr);
// variable brightness with universe 0-255 as output
FuzzyOutput *kecerahan = new FuzzyOutput(1);
kecerahan->addFuzzySet(mati);
kecerahan->addFuzzySet(redup);
kecerahan->addFuzzySet(menyala);
kecerahan->addFuzzySet(terang);
fuzzy->addFuzzyOutput(kecerahan);
// Aturan 1: Jika jarak pendek dan cahaya redup, maka kecerahan terang.
FuzzyRuleAntecedent *ifDistanceSmallAndLdrIsLow = new FuzzyRuleAntecedent();
ifDistanceSmallAndLdrIsLow->joinWithAND(pendek, rendahldr); //untuk Potentiometer tinggildr , yang sebenarnya ldr => rendahldr
FuzzyRuleConsequent *thenBrightnessHigh = new FuzzyRuleConsequent();
thenBrightnessHigh->addOutput(terang); ////for Potentiometer lowb , for actual ldr => highb
FuzzyRule *fuzzyRule1 = new FuzzyRule(1, ifDistanceSmallAndLdrIsLow, thenBrightnessHigh);
fuzzy->addFuzzyRule(fuzzyRule1);
// Aturan 2: Jika jarak small dan cahaya tinggildr, maka kecerahan mati.
FuzzyRuleAntecedent *ifDistanceSmallAndLdrIsHigh = new FuzzyRuleAntecedent();
ifDistanceSmallAndLdrIsHigh->joinWithAND(pendek, tinggildr);
FuzzyRuleConsequent *thenBrightnessOff = new FuzzyRuleConsequent();
thenBrightnessOff->addOutput(mati);
FuzzyRule *fuzzyRule2 = new FuzzyRule(2, ifDistanceSmallAndLdrIsHigh, thenBrightnessOff);
fuzzy->addFuzzyRule(fuzzyRule2);
// Aturan 3: Jika jarak mid, maka kecerahan redup
FuzzyRuleAntecedent *ifDistanceMid = new FuzzyRuleAntecedent();
ifDistanceMid->joinSingle(mid);
FuzzyRuleConsequent *thenBrightnessMidb = new FuzzyRuleConsequent();
thenBrightnessMidb->addOutput(redup);
FuzzyRule *fuzzyRule3 = new FuzzyRule(3, ifDistanceMid, thenBrightnessMidb);
fuzzy->addFuzzyRule(fuzzyRule3);
// Aturan 4: Jika jarak panjang, maka kecerahan menyala
FuzzyRuleAntecedent *ifDistanceBig = new FuzzyRuleAntecedent();
ifDistanceBig->joinSingle(panjang);
FuzzyRuleConsequent *thenBrightnessLow = new FuzzyRuleConsequent();
thenBrightnessLow->addOutput(menyala);
FuzzyRule* fuzzyRule4 = new FuzzyRule(4, ifDistanceBig, thenBrightnessLow);
fuzzy->addFuzzyRule(fuzzyRule4);
// Aturan 5: Jika jarak sangat panjang, maka kecerahan mati.
FuzzyRuleAntecedent *ifDistanceVeryBig = new FuzzyRuleAntecedent();
ifDistanceVeryBig->joinSingle(sangat_panjang);
FuzzyRule* fuzzyRule5 = new FuzzyRule(5, ifDistanceVeryBig, thenBrightnessOff);
fuzzy->addFuzzyRule(fuzzyRule5);
}
//program hc sr 04 untuk memancarkan dan menangkap denyut
int jarak()
{
digitalWrite(trg, LOW);
delayMicroseconds(5);
digitalWrite(trg, HIGH);
delayMicroseconds(10);
digitalWrite(trg, LOW);
// Pemnancara denyut dibagi 2 menghasilkan jarak
long denyut = pulseIn(ech, HIGH) / 2;
return denyut * 10 / 292;
}
// Fungsi membaca analog di pin A1
int kecerahan()
{
return analogRead(LDR);
}
void loop()
{
// get distance and light
int dist = jarak();
int light = kecerahan();
// if the inputs are weird, ignore them Miximum value
if (dist < 0 || dist > 400 || light > 1023) return;
// fuzzyfication
fuzzy->setInput(1, dist); // dist as fuzzy input 1 (distance)
fuzzy->setInput(2, light); // light as fuzzy input 2 (ldr)
fuzzy->fuzzify();
// defuzzyfication
int output = fuzzy->defuzzify(1); // defuzzify fuzzy output 1 (brightness)
analogWrite(led, output);
//void print(int dist, int light, int output) {
Serial.print("distance: ");
Serial.print(dist);
Serial.print(" light: ");
Serial.print(light);
Serial.print(" => output: ");
Serial.print(output);
Serial.println();
delay(100);
}