// eFLL includes
#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>
//pins
#define LDR A0
#define TRIGGER 2
#define ECHO 3
#define LED 5
// object library
Fuzzy *fuzzy = new Fuzzy();
int pinPotensio = 4; // Pin Potensiometer
void setup() {
// set console dan pin
Serial.begin(9600);
pinMode(LDR, INPUT);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(LED, OUTPUT);
// fuzzy sets
// jarak (0-400cm di Wokwi)
FuzzySet *kecil = new FuzzySet(0, 0, 0, 120); //trapizoid MF (a,b,c,d)
FuzzySet *sedang = new FuzzySet(60, 120, 120, 180);
FuzzySet *besar = new FuzzySet(120, 180, 180, 240);
FuzzySet *sangatBesar = new FuzzySet(180, 240, 400, 400);
// ldr (Potentiometer) (0-1023 di Wokwi)
FuzzySet *ldrRendah = new FuzzySet(0, 0, 0, 100);
FuzzySet *ldrSedang = new FuzzySet(60, 200, 500, 700);
FuzzySet *ldrTinggi = new FuzzySet(400, 700, 1015, 1015);
// kecerahan
FuzzySet *mati = new FuzzySet(0, 0, 0, 0);
FuzzySet *kecerahanRendah = new FuzzySet(0, 0, 25, 100);
FuzzySet *kecerahanSedang = new FuzzySet(55, 100, 155, 200);
FuzzySet *kecerahanTinggi = new FuzzySet(155, 230, 255, 255);
// variabel
// variabel jarak dengan universe 0-400 sebagai input
FuzzyInput *jarak = new FuzzyInput(1);
jarak->addFuzzySet(kecil);
jarak->addFuzzySet(sedang);
jarak->addFuzzySet(besar);
fuzzy->addFuzzyInput(jarak);
// variabel ldr dengan universe 0-1015 sebagai input
FuzzyInput *ldr = new FuzzyInput(2);
ldr->addFuzzySet(ldrRendah);
ldr->addFuzzySet(ldrSedang);
ldr->addFuzzySet(ldrTinggi);
fuzzy->addFuzzyInput(ldr);
// variabel kecerahan dengan universe 0-255 sebagai output
FuzzyOutput *kecerahan = new FuzzyOutput(1);
kecerahan->addFuzzySet(mati);
kecerahan->addFuzzySet(kecerahanRendah);
kecerahan->addFuzzySet(kecerahanSedang);
kecerahan->addFuzzySet(kecerahanTinggi);
fuzzy->addFuzzyOutput(kecerahan);
// Aturan 1
// jika jarak kecil dan ldr rendah maka kecerahan tinggi
FuzzyRuleAntecedent *jikaJarakKecilDanLdrRendah = new FuzzyRuleAntecedent();
jikaJarakKecilDanLdrRendah->joinWithAND(kecil, ldrRendah);
FuzzyRuleConsequent *makaKecerahanTinggi = new FuzzyRuleConsequent();
makaKecerahanTinggi->addOutput(kecerahanTinggi);
FuzzyRule *aturanFuzzy1 = new FuzzyRule(1, jikaJarakKecilDanLdrRendah, makaKecerahanTinggi);
fuzzy->addFuzzyRule(aturanFuzzy1);
// Aturan 2
// jika jarak kecil dan ldr tinggi maka kecerahan mati
FuzzyRuleAntecedent *jikaJarakKecilDanLdrTinggi = new FuzzyRuleAntecedent();
jikaJarakKecilDanLdrTinggi->joinWithAND(kecil, ldrTinggi);
FuzzyRuleConsequent *makaKecerahanMati = new FuzzyRuleConsequent();
makaKecerahanMati->addOutput(mati);
FuzzyRule *aturanFuzzy2 = new FuzzyRule(2, jikaJarakKecilDanLdrTinggi, makaKecerahanMati);
fuzzy->addFuzzyRule(aturanFuzzy2);
// Aturan 3
// jika jarak sedang maka kecerahan sedang
FuzzyRuleAntecedent *jikaJarakSedang = new FuzzyRuleAntecedent();
jikaJarakSedang->joinSingle(sedang);
FuzzyRuleConsequent *makaKecerahanSedang = new FuzzyRuleConsequent();
makaKecerahanSedang->addOutput(kecerahanSedang);
FuzzyRule *aturanFuzzy3 = new FuzzyRule(3, jikaJarakSedang, makaKecerahanSedang);
fuzzy->addFuzzyRule(aturanFuzzy3);
// Aturan 4
// jika jarak besar maka kecerahan rendah
FuzzyRuleAntecedent *jikaJarakBesar = new FuzzyRuleAntecedent();
jikaJarakBesar->joinSingle(besar);
FuzzyRuleConsequent *makaKecerahanRendah = new FuzzyRuleConsequent();
makaKecerahanRendah->addOutput(kecerahanRendah);
FuzzyRule *aturanFuzzy4 = new FuzzyRule(4, jikaJarakBesar, makaKecerahanRendah);
fuzzy->addFuzzyRule(aturanFuzzy4);
// Aturan 5
// jika jarak sangat besar maka kecerahan mati
FuzzyRuleAntecedent *jikaJarakSangatBesar = new FuzzyRuleAntecedent();
jikaJarakSangatBesar->joinSingle(sangatBesar);
FuzzyRule *aturanFuzzy5 = new FuzzyRule(5, jikaJarakSangatBesar, makaKecerahanMati);
fuzzy->addFuzzyRule(aturanFuzzy5);
}
// mengembalikan nilai jarak
int jarak() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;
return pulse * 10 / 292;
}
// mengembalikan nilai potensiometer
int bacaPotensio() {
return analogRead(pinPotensio);
}
// fungsi utama
void loop() {
// mendapatkan jarak dan nilai potensiometer
int nilaiJarak = jarak();
int nilaiPotensio = bacaPotensio();
// jika input tidak valid, abaikan
if (nilaiJarak < 0 || nilaiJarak > 400 || nilaiPotensio > 1023) return;
// fuzzyfication
fuzzy->setInput(1, nilaiJarak); // jarak sebagai fuzzy input 1
fuzzy->setInput(2, nilaiPotensio); // potensiometer sebagai fuzzy input 2
fuzzy->fuzzify();
// defuzzyfication
int nilaiOutput = fuzzy->defuzzify(1); // output defuzzifikasi
analogWrite(LED, nilaiOutput);
// mencetak nilai jarak, Potensio, dan output ke monitor serial
Serial.print("jarak: ");
Serial.print(nilaiJarak);
Serial.print(" potensio: ");
Serial.print(nilaiPotensio);
Serial.print(" => output: ");
Serial.print(nilaiOutput);
Serial.println();
delay(100);
}