/**
Program ini adalah implementasi dari kontroler logika fuzzy
menggunakan Arduino dan beberapa sensor. Tujuannya adalah mengontrol
kecerahan lampu LED berdasarkan dua input, yaitu jarak sensor ultrasonik
dan nilai sensor LDR (Light Dependent Resistor).
Kontroler logika fuzzy digunakan untuk membuat keputusan berdasarkan
aturan-aturan fuzzy yang telah ditentukan.
**/
// eFLL includes
#include <Fuzzy.h> // library logika fuzzy
#include <FuzzyComposition.h> // library komposisi fuzzy
#include <FuzzyInput.h> // library input fuzzy
#include <FuzzyIO.h> // library I/O fuzzy
#include <FuzzyOutput.h> // library output fuzzy
#include <FuzzyRule.h> // library aturan fuzzy
#include <FuzzyRuleAntecedent.h> // library aturan antecedent fuzzy
#include <FuzzyRuleConsequent.h> // library aturan concequent fuzzy
#include <FuzzySet.h> // library himpunan fuzzy
// pins
#define LDR A0 //pin A0 digunakan untuk LDR
#define TRIGGER 4 //pin 4 digunakan untuk TRIGGER Ultrasonik
#define ECHO 5 //pin 5 digunakan untuk ECHO ultrasonik
#define LED 6 //pin 6 digunakan untuk LED
// object library
Fuzzy *fuzzy = new Fuzzy(); // mengganti variabel dari f besar menjadi f kecil, apabila ingin memanggil fuzzy hanya tinggal memanggil dengan fuzzy f kecil
void setup() { //Ini adalah bagian awal dari program Arduino
//yang hanya berjalan sekali saat pertama kali menyala.
// set console and pins
Serial.begin(9600);// Menghubungkan Arduino ke komputer supaya bisa mengirim data dan ditampilkan
//di Serial Monitor (di Arduino IDE).
//Angka 9600 adalah kecepatan komunikasi (baud rate).
pinMode(LDR, INPUT); // Mengatur pin LDR sebagai input
pinMode(TRIGGER, OUTPUT); // Mengatur pin trigger sebagai output
pinMode(ECHO, INPUT); // Mengatur pin echo sebagai input
pinMode(LED, OUTPUT); // Mengatur pin LED sebagai output
// fuzzy sets
// distance (0-400cm in Wokwi)
// **Menentukan himpunan fuzzy untuk sensor jarak**
FuzzySet *kecil = new FuzzySet(0, 0, 0, 120); // Jarak dekat (trapesium)
FuzzySet *tengah = new FuzzySet(60, 120, 120, 180);// Jarak sedang
FuzzySet *besar = new FuzzySet(120, 180, 180, 240);// Jarak jauh
FuzzySet *sangatbesar = new FuzzySet(180, 240, 400, 400);// Jarak sangat jauh
// ldr (0-1023 in wokwi)
// ldr (0-100000 lux=> 1015-8 resistance value in wokwi)
// **Menentukan himpunan fuzzy untuk sensor LDR**
FuzzySet *kurangldr = new FuzzySet(0, 0, 0, 100);// Cahaya redup
FuzzySet *tengahldr = new FuzzySet(60, 200, 500, 700);// Cahaya sedang
FuzzySet *tinggildr = new FuzzySet(400 ,700, 1015, 1015);// Cahaya terang
// kecerahan
// **Menentukan himpunan fuzzy untuk kecerahan LED**
FuzzySet *mati = new FuzzySet(0, 0, 0, 0);// LED mati
FuzzySet *kurangb = new FuzzySet(0, 0, 25, 100);// Kecerahan rendah
FuzzySet *tengahb = new FuzzySet(55, 100, 155, 200);// Kecerahan sedang
FuzzySet *tinggib = new FuzzySet(155, 230, 255, 255);// Kecerahan tinggi
// variables
// variable distance with universe 0-400 as input
// **Mendaftarkan variabel fuzzy untuk jarak**
FuzzyInput *distance = new FuzzyInput(1);
distance->addFuzzySet(kecil);
distance->addFuzzySet(tengah);
distance->addFuzzySet(besar);
fuzzy->addFuzzyInput(distance);
// variable ldr with universe 0-1015 as input
// **Mendaftarkan variabel fuzzy untuk sensor LDR**
FuzzyInput *ldr = new FuzzyInput(2);
ldr->addFuzzySet(kurangldr);
ldr->addFuzzySet(tengahldr);
ldr->addFuzzySet(tinggildr);
fuzzy->addFuzzyInput(ldr);
// variable kecerahan with universe 0-255 as output
// **Mendaftarkan variabel fuzzy untuk output kecerahan LED**
FuzzyOutput *kecerahan = new FuzzyOutput(1);
kecerahan->addFuzzySet(mati);
kecerahan->addFuzzySet(kurangb);
kecerahan->addFuzzySet(tengahb);
kecerahan->addFuzzySet(tinggib);
fuzzy->addFuzzyOutput(kecerahan);
// **Aturan Fuzzy**
// **Jika jarak dekat dan cahaya redup, maka LED terang**
FuzzyRuleAntecedent *ifDistanceKecilAndLdrIsKurang = new FuzzyRuleAntecedent();
ifDistanceKecilAndLdrIsKurang->joinWithAND(kecil, kurangldr); //for Potentiometer tinggildr , for actual ldr => lowldr
FuzzyRuleConsequent *thenKecerahanTinggi = new FuzzyRuleConsequent();
thenKecerahanTinggi->addOutput(tinggib); ////for Potentiometer kurangb , for actual ldr => tinggib
FuzzyRule *fuzzyRule1 = new FuzzyRule(1, ifDistanceKecilAndLdrIsKurang, thenKecerahanTinggi);
fuzzy->addFuzzyRule(fuzzyRule1);
// Rules 2
// **Jika jarak dekat dan cahaya terang, maka LED mati**
FuzzyRuleAntecedent *ifDistanceKecilAndLdrIsTinggi = new FuzzyRuleAntecedent();
ifDistanceKecilAndLdrIsTinggi->joinWithAND(kecil, tinggildr);
FuzzyRuleConsequent *thenKecerahanMati = new FuzzyRuleConsequent();
thenKecerahanMati->addOutput(mati);
FuzzyRule *fuzzyRule2 = new FuzzyRule(2, ifDistanceKecilAndLdrIsTinggi, thenKecerahanMati);
fuzzy->addFuzzyRule(fuzzyRule2);
// Rules 3
// **Jika jarak sedang, maka LED sedang terang**
FuzzyRuleAntecedent *ifDistanceTengah = new FuzzyRuleAntecedent();
ifDistanceTengah->joinSingle(tengah);
FuzzyRuleConsequent *thenKecerahanTengahb = new FuzzyRuleConsequent();
thenKecerahanTengahb->addOutput(tengahb);
FuzzyRule *fuzzyRule3 = new FuzzyRule(3, ifDistanceTengah, thenKecerahanTengahb);
fuzzy->addFuzzyRule(fuzzyRule3);
// Rules 4
// **Jika jarak jauh, maka LED redup**
FuzzyRuleAntecedent *ifDistanceBesar = new FuzzyRuleAntecedent();
ifDistanceBesar->joinSingle(besar);
FuzzyRuleConsequent *thenKecerahanKurang = new FuzzyRuleConsequent();
thenKecerahanKurang->addOutput(kurangb);
FuzzyRule* fuzzyRule4 = new FuzzyRule(4, ifDistanceBesar, thenKecerahanKurang);
fuzzy->addFuzzyRule(fuzzyRule4);
// Rules 5
// **Jika jarak sangat jauh, maka LED mati**
FuzzyRuleAntecedent *ifDistanceSangatBesar = new FuzzyRuleAntecedent();
ifDistanceSangatBesar->joinSingle(sangatbesar);
FuzzyRule* fuzzyRule5 = new FuzzyRule(5, ifDistanceSangatBesar, thenKecerahanMati);
fuzzy->addFuzzyRule(fuzzyRule5);
}
// returns the distance
// **Fungsi untuk membaca jarak dari sensor ultrasonik**
int distance() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;// Hitung waktu pantulan suara
return pulse * 10 / 292;// Konversi ke cm
}
// returns the kecerahan
// **Fungsi untuk membaca nilai sensor cahaya (LDR)**
int kecerahan() {
return analogRead(LDR);
}
/*
// prints in serial monitor
void print(int dist, int lampu, int output) {
Serial.print("distance: ");
Serial.print(dist);
Serial.print(" lampu: ");
Serial.print(lampu);
Serial.print(" => output: ");
Serial.print(output);
Serial.println();
}
*/
// main method
// **Loop utama program**
void loop() {
// untuk mendapatkan jarak and lampu
int dist = distance();// Baca nilai jarak
int lampu = kecerahan(); // Baca nilai sensor LDR
// if the inputs are weird, ignore them Miximum value
// **Validasi data agar tidak melebihi batas**
if (dist < 0 || dist > 400 || lampu > 1023) return;
// fuzzyfication
// **Fuzzyfikasi (memasukkan data ke sistem fuzzy)**
fuzzy->setInput(1, dist); // dist as fuzzy input 1 (distance)
fuzzy->setInput(2, lampu); // lampu as fuzzy input 2 (ldr)
fuzzy->fuzzify();
// defuzzyfication
// **Defuzzyfikasi (mengambil hasil keputusan)**
int output = fuzzy->defuzzify(1); // defuzzify fuzzy output 1 (kecerahan)
// **Mengatur kecerahan LED berdasarkan hasil fuzzy**
analogWrite(LED, output);
// **Menampilkan data ke Serial Monitor**
//void print(int dist, int lampu, int output) {
Serial.print("distance: ");
Serial.print(dist);
Serial.print(" lampu: ");
Serial.print(lampu);
Serial.print(" => output: ");
Serial.print(output);
Serial.println();
delay(100);// Tunggu 100ms sebelum membaca ulang
}