Dosen Pengampu: Dr. Ir. Fatchul Arifin, M.T
Dosen Pengampu: Dr. Ir. Fatchul Arifin, M.T
Dosen Pengampu: Dr. Ir. Fatchul Arifin, M.T
Disusun Oleh :
Prasetyo 17502241005
//motor kiri
#define IN3 4
#define IN4 7
#define pwm_kiri 5
//motor kiri
//lcd
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
/*
* The circuit:
* LCD RS pin to digital pin 12
* LCD Enable pin to digital pin 11
* LCD D4 pin to digital pin 5
* LCD D5 pin to digital pin 4
* LCD D6 pin to digital pin 3
* LCD D7 pin to digital pin 2
*/
//lcd
//variabel global
int a,b,i,j,speed_left,speed_right,sensorA,sensorB;
float x, y, error, d_error;
float z1=60,z2=80,a1=-145.5556,a2=-80,a3=0;
float a4=80,a5=145.5556; //z = luas dan a = COA out;
float u_error[3],u_d_error[3],u[3][3], errorneg, errorzero, errorpos, d_errorneg,
d_errorzero,d_errorpos;
float nilai_awal,beda_pwm, validasi, pembilang, penyebut;
//variabel global
void setup() {
lcd.begin(20, 4);
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(pwm_kanan, OUTPUT);
pinMode(pwm_kiri, OUTPUT);
pinMode(16, INPUT_PULLUP);
pinMode(17, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
}
void loop() {
nilai_awal = 100;
baca_sensor(); //membaca nilai error dan d_error
fuzzyfikasi();
rule();
defuzzyfikasi();
kendali_motor(speed_left,speed_right);
int tombol_fuzzyfikasi = digitalRead(16);
int tombol_rule = digitalRead(17);
int tombol_defuzzyfikasi = digitalRead(18);
if(tombol_fuzzyfikasi==0 && tombol_rule==1 && tombol_defuzzyfikasi==1) {
display_fuzzyfikasi();
} //menampilkan data proses fuzzyfikasi
if(tombol_fuzzyfikasi==1 && tombol_rule==0 && tombol_defuzzyfikasi==1) {
display_rule();
} //nenampilkan implikasi setiap rule
if(tombol_fuzzyfikasi==1 && tombol_rule==1 && tombol_defuzzyfikasi==0) {
display_defuzzyfikasi();
}//menampilkan output tegas dan nilai kecepatan motor kiri dan kanan
if(tombol_fuzzyfikasi==1 && tombol_rule==1 && tombol_defuzzyfikasi==1) {
lcd.clear();
}//clear tampilan LCD
}
void baca_sensor()
{
sensorA = analogRead(A0);
sensorB = analogRead(A1);
a = map(sensorA, 0, 1023, 0, 255); //maping error
b = map(sensorB, 0, 1023, 0, 255); //maping d_error
if(a>=241) {error=8;}
else if(a>=227) {error=7;}
else if(a>=213) {error=6;}
else if(a>=199) {error=5;}
else if(a>=185) {error=4;}
else if(a>=171) {error=3;}
else if(a>=157) {error=2;}
else if(a>=143) {error=1;}
else if(a>=129) {error=0;}
else if(a>=115) {error=-1;}
else if(a>=101) {error=-2;}
else if(a>=87) {error=-3;}
else if(a>=73) {error=-4;}
else if(a>=59) {error=-5;}
else if(a>=45) {error=-6;}
else if(a>=31) {error=-7;}
else if((a<31)&&(a>=0)) {error=-8;}
if(b>=248) {d_error=16;}
else if(b>=241) {d_error=15;}
else if(b>=234) {d_error=14;}
else if(b>=227) {d_error=13;}
else if(b>=220) {d_error=12;}
else if(b>=213) {d_error=11;}
else if(b>=206) {d_error=10;}
else if(b>=199) {d_error=9;}
else if(b>=192) {d_error=8;}
else if(b>=185) {d_error=7;}
else if(b>=178) {d_error=6;}
else if(b>=171) {d_error=5;}
else if(b>=164) {d_error=4;}
else if(b>=157) {d_error=3;}
else if(b>=150) {d_error=2;}
else if(b>=143) {d_error=1;}
else if(b>=136) {d_error=0;}
else if(b>=129) {d_error=-1;}
else if(b>=122) {d_error=-2;}
else if(b>=115) {d_error=-3;}
else if(b>=108) {d_error=-4;}
else if(b>=101) {d_error=-5;}
else if(b>= 94) {d_error=-6;}
else if(b>= 87) {d_error=-7;}
else if(b>= 80) {d_error=-8;}
else if(b>= 73) {d_error=-9;}
else if(b>= 66) {d_error=-10;}
else if(b>= 59) {d_error=-11;}
else if(b>= 52) {d_error=-12;}
else if(b>= 45) {d_error=-13;}
else if(b>= 38) {d_error=-14;}
else if(b>= 31) {d_error=-15;}
else if((b<31)&&(b>= 0)) {d_error=-16;}
}
void fuzzyfikasi_error()
{
x = error;
//u_error[0] = Negatif 1
//u_error[1] = Zero 1
//u_error[2] = Positif 1
if(x >= 5)
{
u_error[0]=0;
u_error[1]=0;
u_error[2]=1;
}
else if(x >= 0)
{
u_error[0]=0;
u_error[1]=(5-x)/5;
u_error[2]=(x-0)/5;
}
else if(x >= -5)
{
u_error[0]=(0-x)/5;
u_error[1]=(x+5)/5;
u_error[2]=0;
}
else if(x < -5)
{
u_error[0]=1;
u_error[1]=0;
u_error[2]=0;
}
errorneg = u_error[0];
errorzero = u_error[1];
errorpos = u_error[2];
}
void fuzzyfikasi_perubahan_error()
{
y = d_error;
// u_d_error[0]=Negatif 2
// u_d_error[1]=Zero 2,
//u_d_error[2]=Positif 2
if(y >= 8)
{
u_d_error[0]=0;
u_d_error[1]=0;
u_d_error[2]=1;
}
else if(y >= 0)
{
u_d_error[0]=0;
u_d_error[1]=(8-y)/8;
u_d_error[2]=(y-0)/8;
}
else if(y >= -8)
{
u_d_error[0]=(0-y)/8;
u_d_error[1]=(y+8)/8;
u_d_error[2]=0;
}
else if(y < -8)
{
u_d_error[0]=1;
u_d_error[1]=0;
u_d_error[2]=0;
}
d_errorneg = u_d_error[0];
d_errorzero = u_d_error[1];
d_errorpos = u_d_error[2];
}
void fuzzyfikasi()
{
fuzzyfikasi_error();
fuzzyfikasi_perubahan_error();
}
void defuzzyfikasi()
{
//menggunakan metode mamdani dan defuzzyfikasi meggunakan metode centroid of
area
pembilang
=(u[0][0]*a5*z1)+(u[0][1]*a4*z2)+(u[0][2]*a3*z2)+(u[1][0]*a4*z2)+(u[1][1]*a3*z2
)+(u[1][2]*a2*z2)+(u[2][0]*a3*z2)+(u[2][1]*a2*z2)+(u[2][2]*a1*z1);
penyebut
=(u[0][0]*z1)+(u[0][1]*z2)+(u[0][2]*z2)+(u[1][0]*z2)+(u[1][1]*z2)+(u[1][2]*z2)+(u
[2][0]*z2)+(u[2][1]*z2)+(u[2][2]*z1);
validasi=pembilang/penyebut; // perhitungan defuzzyfikasi dengan menggabungkan
seluruh nilai min yang sudah didapatkan
Serial.print("validasi= ");
Serial.println(validasi);
beda_pwm = validasi;
speed_left = nilai_awal-beda_pwm;
speed_right = nilai_awal+beda_pwm;
}
void display_fuzzyfikasi()
{
lcd.setCursor(0, 0);lcd.print("er=");
lcd.setCursor(3, 0);lcd.print(error);
lcd.setCursor(9, 0);lcd.print("d_er=");
lcd.setCursor(14, 0);lcd.print(d_error);
lcd.setCursor(0, 1);lcd.print("neg=");
lcd.setCursor(4, 1);lcd.print(errorneg);
lcd.setCursor(9, 1);lcd.print("neg=");
lcd.setCursor(14, 1);lcd.print(d_errorneg);
lcd.setCursor(0, 2);lcd.print("zer=");
lcd.setCursor(4, 2);lcd.print(errorzero);
lcd.setCursor(9, 2);lcd.print("zer=");
lcd.setCursor(14, 2);lcd.print(d_errorzero);
lcd.setCursor(0, 3);lcd.print("pos=");
lcd.setCursor(4, 3);lcd.print(errorpos);
lcd.setCursor(9, 3);lcd.print("pos=");
lcd.setCursor(14, 3);lcd.print(d_errorpos);
}
void display_rule()
{
lcd.setCursor(0, 0);lcd.print("er=");
lcd.setCursor(3, 0);lcd.print(error);
lcd.setCursor(9, 0);lcd.print("d_er=");
lcd.setCursor(14, 0);lcd.print(d_error);
lcd.setCursor(0, 1);lcd.print("1=");
lcd.setCursor(2, 1);lcd.print(u[0][0]);
lcd.setCursor(7, 1);lcd.print("2=");
lcd.setCursor(9, 1);lcd.print(u[0][1]);
lcd.setCursor(14, 1);lcd.print("3=");
lcd.setCursor(16, 1);lcd.print(u[0][2]);
lcd.setCursor(0, 2);lcd.print("4=");
lcd.setCursor(2, 2);lcd.print(u[1][0]);
lcd.setCursor(7, 2);lcd.print("5=");
lcd.setCursor(9, 2);lcd.print(u[1][1]);
lcd.setCursor(14, 2);lcd.print("6=");
lcd.setCursor(16, 2);lcd.print(u[1][2]);
lcd.setCursor(0, 3);lcd.print("7=");
lcd.setCursor(2, 3);lcd.print(u[2][0]);
lcd.setCursor(7, 3);lcd.print("8=");
lcd.setCursor(9, 3);lcd.print(u[2][1]);
lcd.setCursor(14, 3);lcd.print("9=");
lcd.setCursor(16, 3);lcd.print(u[2][2]);
}
void display_defuzzyfikasi()
{
lcd.setCursor(0, 0);lcd.print("er=");
lcd.setCursor(3, 0);lcd.print(error);
lcd.setCursor(9, 0);lcd.print("d_er=");
lcd.setCursor(14, 0);lcd.print(d_error);
lcd.setCursor(0, 1);lcd.print("Output =");
lcd.setCursor(15, 1);lcd.print(beda_pwm);
lcd.setCursor(0, 2);lcd.print("Speed_Right =");
lcd.setCursor(15, 2);lcd.print(speed_right);
lcd.setCursor(0, 3);lcd.print("Speed_Left =");
lcd.setCursor(15, 3);lcd.print(speed_left);
}
Pembahasan 1. Deklarasi Awal
//motor kanan
#define IN1 2
#define IN2 3
#define pwm_kanan 6
//motor kiri
#define IN3 4
#define IN4 7
#define pwm_kiri 5
//lcd
#include <LiquidCrystal.h>
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
//variabel global
int a,b,i,j,speed_left,speed_right,sensorA,sensorB;
float x, y, error, d_error;
float z1=60,z2=80,a1=-145.5556,a2=-80,a3=0;
float a4=80,a5=145.5556; //z = luas dan a = COA out;
float u_error[3],u_d_error[3],u[3][3], errorneg, errorzero, errorpos, d_errorneg,
d_errorzero,d_errorpos;
float nilai_awal,beda_pwm, validasi, pembilang, penyebut;
//variabel global
Pembahasan 2. Setup
void setup() {
lcd.begin(20, 4);
Serial.begin(9600);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(pwm_kanan, OUTPUT);
pinMode(pwm_kiri, OUTPUT);
pinMode(16, INPUT_PULLUP);
pinMode(17, INPUT_PULLUP);
pinMode(18, INPUT_PULLUP);
}
if(b>=248) {d_error=16;}
else if(b>=241) {d_error=15;}
else if(b>=234) {d_error=14;}
else if(b>=227) {d_error=13;}
else if(b>=220) {d_error=12;}
else if(b>=213) {d_error=11;}
else if(b>=206) {d_error=10;}
else if(b>=199) {d_error=9;}
else if(b>=192) {d_error=8;}
else if(b>=185) {d_error=7;}
else if(b>=178) {d_error=6;}
else if(b>=171) {d_error=5;}
else if(b>=164) {d_error=4;}
else if(b>=157) {d_error=3;}
else if(b>=150) {d_error=2;}
else if(b>=143) {d_error=1;}
else if(b>=136) {d_error=0;}
else if(b>=129) {d_error=-1;}
else if(b>=122) {d_error=-2;}
else if(b>=115) {d_error=-3;}
else if(b>=108) {d_error=-4;}
else if(b>=101) {d_error=-5;}
else if(b>= 94) {d_error=-6;}
else if(b>= 87) {d_error=-7;}
else if(b>= 80) {d_error=-8;}
else if(b>= 73) {d_error=-9;}
else if(b>= 66) {d_error=-10;}
else if(b>= 59) {d_error=-11;}
else if(b>= 52) {d_error=-12;}
else if(b>= 45) {d_error=-13;}
else if(b>= 38) {d_error=-14;}
else if(b>= 31) {d_error=-15;}
else if((b<31)&&(b>= 0)) {d_error=-16;}
}
Yang dimaksud sensor di sini adalah potensio maka dari itu dalam
sub program ini merupakan pemetaan nilai potensio dari 0-1023 dipetakan
ke nilai 0-255 lalu dipetakan kembali secara manual kedalam range -8 s/d
8 untuk error dan -16 s/d 16 untuk d_error.
void display_rule()
{
lcd.setCursor(0, 0);lcd.print("er=");
lcd.setCursor(3, 0);lcd.print(error);
lcd.setCursor(9, 0);lcd.print("d_er=");
lcd.setCursor(14, 0);lcd.print(d_error);
lcd.setCursor(0, 1);lcd.print("1=");
lcd.setCursor(2, 1);lcd.print(u[0][0]);
lcd.setCursor(7, 1);lcd.print("2=");
lcd.setCursor(9, 1);lcd.print(u[0][1]);
lcd.setCursor(14, 1);lcd.print("3=");
lcd.setCursor(16, 1);lcd.print(u[0][2]);
lcd.setCursor(0, 2);lcd.print("4=");
lcd.setCursor(2, 2);lcd.print(u[1][0]);
lcd.setCursor(7, 2);lcd.print("5=");
lcd.setCursor(9, 2);lcd.print(u[1][1]);
lcd.setCursor(14, 2);lcd.print("6=");
lcd.setCursor(16, 2);lcd.print(u[1][2]);
lcd.setCursor(0, 3);lcd.print("7=");
lcd.setCursor(2, 3);lcd.print(u[2][0]);
lcd.setCursor(7, 3);lcd.print("8=");
lcd.setCursor(9, 3);lcd.print(u[2][1]);
lcd.setCursor(14, 3);lcd.print("9=");
lcd.setCursor(16, 3);lcd.print(u[2][2]);
}
void display_defuzzyfikasi()
{
lcd.setCursor(0, 0);lcd.print("er=");
lcd.setCursor(3, 0);lcd.print(error);
lcd.setCursor(9, 0);lcd.print("d_er=");
lcd.setCursor(14, 0);lcd.print(d_error);
lcd.setCursor(0, 1);lcd.print("Output =");
lcd.setCursor(15, 1);lcd.print(beda_pwm);
lcd.setCursor(0, 2);lcd.print("Speed_Right =");
lcd.setCursor(15, 2);lcd.print(speed_right);
lcd.setCursor(0, 3);lcd.print("Speed_Left =");
lcd.setCursor(15, 3);lcd.print(speed_left);
}
C. Data Hasil
Tabel 1. Hasil Percobaan Variable Error
error negatif zero positif
-8 1 0 0
-7 1 0 0
-6 1 0 0
-5 1 0 0
-4 0,8 0,2 0
-3 0,6 0,4 0
-2 0,4 0,6 0
-1 0,2 0,8 0
0 0 1 0
1 0 0,8 0,2
2 0 0,6 0,4
3 0 0,4 0,6
4 0 0,2 0,8
5 0 0 1
6 0 0 1
7 0 0 1
8 0 0 1
Tabel 2. Hasil Percobaan Variable D_Error
d_error negatif zero positif d_error negatif zero positif
-16 1 0 0 0 0 1 0
-15 1 0 0 1 0 0,88 0,12
-14 1 0 0 2 0 0,75 0,25
-13 1 0 0 3 0 0,63 0,37
-12 1 0 0 4 0 0,5 0,5
-11 1 0 0 5 0 0,37 0,63
-10 1 0 0 6 0 0,25 0,75
-9 1 0 0 7 0 0,12 0,88
-8 1 0 0 8 0 0 1
-7 0,88 0,12 0 9 0 0 1
-6 0,75 0,25 0 10 0 0 1
-5 0,63 0,37 0 11 0 0 1
-4 0,5 0,5 0 12 0 0 1
-3 0,37 0,63 0 13 0 0 1
-2 0,25 0,75 0 14 0 0 1
-1 0,12 0,88 0 15 0 0 1
0 0 1 0 16 0 0 1
e) Defuzzyfikasi
Input dari proses defuzzifikasi adalah suatu himpunan
fuzzy yang diperoleh dari komposisi aturan-aturan fuzzy.
Metode defuzzyfikasi yang digunakan adalah metode
centroid atau juga dikenal dengan Center of Area (COA).
Pada metode ini, solusi crisp diperoleh dengan cara
mengambil titik pusat daerah fuzzy. Output yang dihasilkan
akan digunakan sebagai variable penentu perubahan
kecepatan motor.
Seperti yang tertulis di atas tadi, output memiliki 5 buah
linguistik variable, setelah diketahui nilai titik dari grafik
output maka dicari luas daerah dan titik tengah masing-
masing anggota. Untuk menghitung Luas daerah anggota
Negative Small, Zero dan Positive Small digunakan rumus
luas segitiga karena ketiganya berbentuk segitiga.
Keterangan
rule : hasil fungsi implikasi dari kedua input
coa : titik tengah anggota
luas : luas daerah anggota
n : jumlah rule yang dipakai
i : data ke-n
E. Kesimpulan
Dari percobaan yang telah dilakukan dapat disimulkan bahwa,
penggunaan fuzzy logic sebagai unit controller merupakan keputusan yang
baik, dikarenakan jika kita bisa merancang sistem fuzzy yang baik maka
data yang didapatkan akan cenderung presisi. Selain itu dari praktikum ini
dapat kita lihat bahwa:
1. Hasil antara perhitungan dan percobaan relatif cocok
2. Penggunaan metode yang baik sehingga mendapatkan hasil yang
relatif presisi
3. Mudah untuk dipahami
4. Dapat dibayangkan variable yang digunakan dengan melihat
program yang ada