#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>
// Penambahan Library DS18B20
#include <OneWire.h>
#include <DallasTemperature.h>
// Alamat I2C untuk LCD (umumnya 0x27)
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Pin untuk sensor suhu DS18B20
#define ONE_WIRE_BUS 2 // Pin data DS18B20
// Inisialisasi pin
int trg = 4;
int ech = 3;
int led = 9;
int aktuator = 7; // Pin untuk aktuator tambahan
// Setup OneWire dan DallasTemperature
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
Fuzzy *fuzzy = new Fuzzy();
void setup()
{
Serial.begin(9600);
pinMode(trg, OUTPUT); // Pin trigger untuk sensor ultrasonik
pinMode(ech, INPUT); // Pin echo untuk sensor ultrasonik
pinMode(led, OUTPUT); // Pin untuk LED
pinMode(aktuator, OUTPUT); // Pin untuk aktuator tambahan
// Inisialisasi LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 1);
lcd.print("Eric Agus Kurniawan ");
lcd.setCursor(0, 2);
lcd.print("2241170097");
delay(1000);
lcd.clear();
lcd.print("Memulai...");
delay(500);
// Inisialisasi sensor suhu
sensors.begin();
// Mengatur fuzzy untuk jarak antara 0 - 400 cm
FuzzySet *pendek = new FuzzySet(0, 0, 0, 120);
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);
// Termometer (suhu dalam derajat Celsius)
FuzzySet *rendahSuhu = new FuzzySet(0, 0, 0, 25);
FuzzySet *sedangSuhu = new FuzzySet(25, 30, 30, 35);
FuzzySet *tinggiSuhu = new FuzzySet(30, 50, 50, 50);
// Kecerahan LED
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);
// Variabel jarak dengan universe 0-400 cm sebagai input
FuzzyInput *jarakInput = new FuzzyInput(1);
jarakInput->addFuzzySet(pendek);
jarakInput->addFuzzySet(mid);
jarakInput->addFuzzySet(panjang);
jarakInput->addFuzzySet(sangat_panjang);
fuzzy->addFuzzyInput(jarakInput);
// Variabel suhu dengan universe 0-50 derajat Celsius sebagai input
FuzzyInput *suhuInput = new FuzzyInput(2);
suhuInput->addFuzzySet(rendahSuhu);
suhuInput->addFuzzySet(sedangSuhu);
suhuInput->addFuzzySet(tinggiSuhu);
fuzzy->addFuzzyInput(suhuInput);
// Variabel kecerahan LED dengan universe 0-255 sebagai output
FuzzyOutput *kecerahan = new FuzzyOutput(1);
kecerahan->addFuzzySet(mati);
kecerahan->addFuzzySet(redup);
kecerahan->addFuzzySet(menyala);
kecerahan->addFuzzySet(terang);
fuzzy->addFuzzyOutput(kecerahan);
// Aturan Fuzzy
// Aturan 1: Jika jarak pendek dan suhu rendah, maka kecerahan LED terang
FuzzyRuleAntecedent *jikaJarakPendekDanSuhuRendah = new FuzzyRuleAntecedent();
jikaJarakPendekDanSuhuRendah->joinWithAND(pendek, rendahSuhu);
FuzzyRuleConsequent *makaKecerahanTerang = new FuzzyRuleConsequent();
makaKecerahanTerang->addOutput(terang);
FuzzyRule *aturanFuzzy1 = new FuzzyRule(1, jikaJarakPendekDanSuhuRendah, makaKecerahanTerang);
fuzzy->addFuzzyRule(aturanFuzzy1);
// Aturan 2: Jika jarak mid dan suhu sedang, maka kecerahan LED redup
FuzzyRuleAntecedent *jikaJarakMidDanSuhuSedang = new FuzzyRuleAntecedent();
jikaJarakMidDanSuhuSedang->joinWithAND(mid, sedangSuhu);
FuzzyRuleConsequent *makaKecerahanRedup = new FuzzyRuleConsequent();
makaKecerahanRedup->addOutput(redup);
FuzzyRule *aturanFuzzy2 = new FuzzyRule(2, jikaJarakMidDanSuhuSedang, makaKecerahanRedup);
fuzzy->addFuzzyRule(aturanFuzzy2);
// Aturan 3: Jika jarak 70-80 cm dan suhu 30 derajat, maka aktuator menyala
FuzzySet *jarak70_80 = new FuzzySet(70, 75, 75, 80);
FuzzySet *suhu30 = new FuzzySet(29, 30, 30, 31);
FuzzyRuleAntecedent *jikaJarak70_80DanSuhu30 = new FuzzyRuleAntecedent();
jikaJarak70_80DanSuhu30->joinWithAND(jarak70_80, suhu30);
FuzzyRuleConsequent *makaAktuatorMenyala = new FuzzyRuleConsequent();
makaAktuatorMenyala->addOutput(terang);
FuzzyRule *aturanFuzzy3 = new FuzzyRule(3, jikaJarak70_80DanSuhu30, makaAktuatorMenyala);
fuzzy->addFuzzyRule(aturanFuzzy3);
// Aturan 4: Jika jarak panjang, maka kecerahan LED menyala
FuzzyRuleAntecedent *jikaJarakPanjang = new FuzzyRuleAntecedent();
jikaJarakPanjang->joinSingle(panjang);
FuzzyRuleConsequent *makaKecerahanMenyala = new FuzzyRuleConsequent();
makaKecerahanMenyala->addOutput(menyala);
FuzzyRule *aturanFuzzy4 = new FuzzyRule(4, jikaJarakPanjang, makaKecerahanMenyala);
fuzzy->addFuzzyRule(aturanFuzzy4);
// Aturan 5: Jika jarak sangat panjang, maka kecerahan LED mati
FuzzyRuleAntecedent *jikaJarakSangatPanjang = new FuzzyRuleAntecedent();
jikaJarakSangatPanjang->joinSingle(sangat_panjang);
FuzzyRuleConsequent *makaKecerahanMati = new FuzzyRuleConsequent();
makaKecerahanMati->addOutput(mati);
FuzzyRule *aturanFuzzy5 = new FuzzyRule(5, jikaJarakSangatPanjang, makaKecerahanMati);
fuzzy->addFuzzyRule(aturanFuzzy5);
}
int bacaJarak()
{
digitalWrite(trg, LOW);
delayMicroseconds(5);
digitalWrite(trg, HIGH);
delayMicroseconds(10);
digitalWrite(trg, LOW);
long denyut = pulseIn(ech, HIGH, 30000); // Timeout 30ms
if (denyut == 0) return 400; // Jika tidak ada objek, anggap jarak maksimal
return denyut * 0.0343 / 2; // Menghitung jarak dalam cm
}
float bacaSuhu()
{
sensors.requestTemperatures(); // Mengambil pembacaan suhu
float suhu = sensors.getTempCByIndex(0); // Mengambil suhu dalam derajat Celsius
return suhu;
}
void loop()
{
// Membaca nilai jarak dan suhu
int jarak = bacaJarak();
float suhu = bacaSuhu();
// Jika input tidak sesuai, abaikan
if (jarak < 0 || jarak > 400 || suhu > 50 || suhu < -55) return; // Batas suhu DS18B20
// Fuzzyfication
fuzzy->setInput(1, jarak); // Jarak sebagai input fuzzy 1
fuzzy->setInput(2, suhu); // Suhu sebagai input fuzzy 2
fuzzy->fuzzify();
// Defuzzyfication
int output = fuzzy->defuzzify(1); // Keluaran fuzzy untuk kecerahan
analogWrite(led, output); // Mengontrol kecerahan LED
// Menyalakan atau mematikan aktuator berdasarkan aturan
bool statusAktuator = false;
if (jarak >= 70 && jarak <= 80 && suhu >= 27 && suhu <= 33)
{
digitalWrite(aktuator, HIGH); // Aktuator menyala
statusAktuator = true;
}
else
{
digitalWrite(aktuator, LOW); // Aktuator mati
}
// Debugging output ke serial monitor
Serial.print("Jarak: ");
Serial.print(jarak);
Serial.print(" cm, Suhu: ");
Serial.print(suhu);
Serial.print(" C, Kecerahan LED: ");
Serial.print(output);
Serial.print(", Aktuator: ");
Serial.println(statusAktuator ? "Menyala" : "Mati");
// Menampilkan data ke LCD 4x20
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Jarak:");
lcd.print(jarak);
lcd.print(" cm");
lcd.setCursor(0, 1);
lcd.print("Suhu:");
lcd.print(suhu, 1);
lcd.print(" C");
lcd.setCursor(0, 2);
lcd.print("Kecerahan LED:");
lcd.print(output);
lcd.setCursor(0, 3);
lcd.print("Aktuator:");
lcd.print(statusAktuator ? "On" : "Off");
delay(500);
}