Tutorial Fuzzy Logic Mamdani for Arduino — {link}
Fuzzy mamdani Arduino is a decision making program based on fuzzy logic or fuzzy logic controller, Arduino as a microcontroller that processes fuzzy logic programs. In this article, we will discuss thoroughly about making design of fuzzy logic mamdani with Arduino and its application.
Fuzzy logic is a branch of mathematics for fuzzy or cryptic decision
In contrast to crisp logic where the value is clear or bright, fuzzy applies cryptic methods to determine a decision.
Examples of fuzzy logic in life
- Riding a motorcycle
- Kicking the ball
- Determine someone’s beauty
- and many other human behavior and judgments
Examples of fuzzy logic in systems or robots
- Fuzzy fire fighting robot
- Robot Balancing with Fuzzy
- Fuzzy air heater system
- Fuzzy washing machine
- and many other systems by implementing fuzzy logic as a controller
Tutorial Arduino Fuzzy Mamdani With One Input and Two Outputs
Fuzzy in this article is the application of the mamdani method with Arduino, DC motor and proximity sensor.
The case is simple, namely to make a controller to determine the speed of a DC motor based on the distance read by the ultrasonic sensor.
Arduino Circuit Schematic, Ultrasonic Sensor and DC Motor
Here is a schematic using proteus 8
Fuzzyfication Design with Matlab or Labview Software (Optionally can use Corel or anything for drawing)
The following is a picture of the fuzzy mamdani set for Arduino distance input and PWM output that I have created using the fuzzy simulation and control labview functions.
Next we will create a program to calculate defuzzification or fuzzy mamdani sets with Arduino for input and output.
Based on the picture above, I have designed for distance input fuzzification like this
- membership function of near = 1 when input distance is less than 10
- membership function of near = (100 — x) / (100–10) when the input distance is more than 10 or less than 100
- membership function of near = 0 when input distance is more than 100
- membership function of a bit far = 1 when input distance = 150
- membership function of a bit far = (x — 50) / (150–50) when input distance is more than 50 or less than 150
- membership function of a bit far = (150 — x) / (250–150) when input distance is more than 150 or less than 250
- membership function of a bit far = 0 when input distance is less than 50 or more than 250
- membership function of far = 1 when input distance is more than 290
- membership function of far = (x-200) / (290–200) when input distance is more than 10 or less than 100
- membership function of far = 0 when input distance is less than 200
For the fuzzy pwm output, please think for yourself. if there is something wrong with the explanation above, please comment.
By knowing and understanding the table above, we will easily create a fuzzy set program in C or Arduino
Mamdani Defuzzification Code with C or Arduino Language
float fudeket[4] = {0, 0, 10, 100};
float fulumayan[3] = {50, 150, 250};
float fujauh[4] = {200, 290, 300, 300};
float fylambat[3] = {0, 0, 100};
float fysedang[3] = {20, 127.5, 235};
float fycepat[3] = {155, 255, 255};
float inputf, outputf;
float FiN(){
if (inputf < fudeket[2]){return 1;}
else if (inputf >= fudeket[2] && inputf <= fudeket[3]){return (fudeket[3] - inputf)/(fudeket[3]-fudeket[2]);}
else if (inputf > fudeket[3]){return 0;}
}
float FiZ(){
if (inputf < fulumayan[0]){return 0;}
else if (inputf >= fulumayan[0] && inputf <= fulumayan[1]){return (inputf - fulumayan[0])/(fulumayan[1]-fulumayan[0]);}
else if (inputf >= fulumayan[1] && inputf <= fulumayan[2]){return (fulumayan[2] - inputf)/(fulumayan[2]-fulumayan[1]);}
else if (inputf > fulumayan[2]){return 0;}
}
float FiP(){
if (inputf < fujauh[0]){return 0;}
else if (inputf >= fujauh[0] && inputf <= fujauh[1]){return (inputf - fujauh[0])/(fujauh[1]-fujauh[0]);}
else if (inputf > fujauh[2]){return 1;}
}
float FoN(){
if (outputf < fylambat[1]){return 1;}
else if (outputf >= fylambat[1] && outputf <= fylambat[2]){return (fylambat[2] - outputf)/(fylambat[2]-fylambat[1]);}
else if (outputf > fylambat[2]){return 0;}
}
float FoZ(){
if (outputf < fysedang[0]){return 0;}
else if (outputf >= fysedang[0] && outputf <= fysedang[1]){return (outputf - fysedang[0])/(fysedang[1]-fysedang[0]);}
else if (outputf >= fysedang[1] && outputf <= fysedang[2]){return (fysedang[2] - outputf)/(fysedang[2]-fysedang[1]);}
else if (outputf > fysedang[2]){return 0;}
}
float FoP(){
if (outputf < fycepat[0]){return 0;}
else if (outputf >= fycepat[0] && outputf <= fycepat[1]){return (outputf - fycepat[0])/(fycepat[1]-fycepat[0]);}
else if (outputf > fycepat[1]){return 1;}
}
int main(){
printf ("Masukan Input Jarak 0 - 300 :");
scanf ("%f", &inputf);
printf ("Masukan Input PWM 0 - 255 :");
scanf ("%f", &outputf);
printf ("Keanggotaan Jarak Deket : %f\n", FiN());
printf ("Keanggotaan Jarak Lumayan : %f\n", FiZ());
printf ("Keanggotaan Jarak Jauh : %f\n", FiP());
printf ("Keanggotaan PWM Lambat : %f\n", FoN());
printf ("Keanggotaan PWM Sedang : %f\n", FoZ());
printf ("Keanggotaan PWM Cepat : %f\n", FoP());
}
Please run the program above then check the results whether it is appropriate or not, if it is not suitable, please say so I will fix it.
Then we will apply the implication function based on the rules that we will create.
First, let’s create a fuzzy mamdani rule for Arduino, a proximity sensor as input and PWM as an output.
Fuzzy Mamdani rules with Arduino or C language
- If the distance is near Then PWM is slow
- If the distance is a bit far Then PWM is medium
- If the distance is far Then PWM is fast
Then the implication function for each rule is like this in the fuzzy Arduino mamdani or C language program
Look again at the fuzzy set output mamdani Arduino above.
- Slow fuzzy membership formula = (100 — x) / (100–0)
- Medium fuzzy membership formula a = (x — 20) / (127.5–20)
- Medium fuzzy membership formula b = (235 — x) / (235–127.5)
- Fast fuzzy membership formula (x — 155) / (255–255)
By reversing the formula, the results of the program are obtained as below. (To learn how to count, please contact me for private telegram lessons: @anakkontrol)
void implikasi (){
//sesuai dengan rule
// if deket then lambat
a1 = 100 - (FiN() * (fylambat[2] - fylambat[1]));
// if lumayan then sedang
b1a = 20 + (FiZ() * (fysedang[1] - fysedang[0]));
b1b = 235 - (FiZ() * (fysedang[2] - fysedang[1]));
// if jauh then cepat
c1 = 155 + (FiP() * (fycepat[1] - fycepat[0]));
}
The complete program for calculating the fuzzy mamdani implications based on the above rules can be seen below.
#include<stdio.h>
#include<math.h>
float A, B;
int sel_;
float a1, b1a, b1b, c1;
float fudeket[4] = {0, 0, 10, 100};
float fulumayan[3] = {50, 150, 250};
float fujauh[4] = {200, 290, 300, 300};
float fylambat[3] = {0, 0, 100};
float fysedang[3] = {20, 127.5, 235};
float fycepat[3] = {155, 255, 255};
float inputf, outputf;
float FiN(){
if (inputf < fudeket[2]){return 1;}
else if (inputf >= fudeket[2] && inputf <= fudeket[3]){return (fudeket[3] - inputf)/(fudeket[3]-fudeket[2]);}
else if (inputf > fudeket[3]){return 0;}
}
float FiZ(){
if (inputf < fulumayan[0]){return 0;}
else if (inputf >= fulumayan[0] && inputf <= fulumayan[1]){return (inputf - fulumayan[0])/(fulumayan[1]-fulumayan[0]);}
else if (inputf >= fulumayan[1] && inputf <= fulumayan[2]){return (fulumayan[2] - inputf)/(fulumayan[2]-fulumayan[1]);}
else if (inputf > fulumayan[2]){return 0;}
}
float FiP(){
if (inputf < fujauh[0]){return 0;}
else if (inputf >= fujauh[0] && inputf <= fujauh[1]){return (inputf - fujauh[0])/(fujauh[1]-fujauh[0]);}
else if (inputf > fujauh[1]){return 1;}
}
float FoN(){
if (outputf < fylambat[1]){return 1;}
else if (outputf >= fylambat[1] && outputf <= fylambat[2]){return (fylambat[2] - outputf)/(fylambat[2]-fylambat[1]);}
else if (outputf > fylambat[2]){return 0;}
}
float FoZ(){
if (outputf < fysedang[0]){return 0;}
else if (outputf >= fysedang[0] && outputf <= fysedang[1]){return (outputf - fysedang[0])/(fysedang[1]-fysedang[0]);}
else if (outputf >= fysedang[1] && outputf <= fysedang[2]){return (fysedang[2] - outputf)/(fysedang[2]-fysedang[1]);}
else if (outputf > fysedang[2]){return 0;}
}
float FoP(){
if (outputf < fycepat[0]){return 0;}
else if (outputf >= fycepat[0] && outputf <= fycepat[1]){return (outputf - fycepat[0])/(fycepat[1]-fycepat[0]);}
else if (outputf > fycepat[1]){return 1;}
}
void implikasi (){
//sesuai dengan rule
// if deket then lambat
a1 = 100 - (FiN() * (fylambat[2] - fylambat[1]));
// if lumayan then sedang
b1a = 20 + (FiZ() * (fysedang[1] - fysedang[0]));
b1b = 235 - (FiZ() * (fysedang[2] - fysedang[1]));
// if jauh then cepat
c1 = 155 + (FiP() * (fycepat[1] - fycepat[0]));
}
float f(float x){
if (B > 0 && sel_ == 0){
return ((x-A)/B)*x;
}
else if (B > 0 && sel_ == 1){
return ((A-x)/B)*x;
}
else {
return A*x;
}
}
/*Function definition to perform integration by Simpson's 1/3rd Rule */
float simpsons(float f(float x), float a,float b,float n){
float h,integral,x,sum=0;
int i;
h=fabs(b-a)/n;
for(i=1;i<n;i++){
x=a+i*h;
if(i%2==0){
sum=sum+2*f(x);
}
else{
sum=sum+4*f(x);
}
}
integral=(h/3)*(f(a)+f(b)+sum);
return integral;
}
float fx(float limd, float limu, float a, float b, int sel){
int n,i=2;
float h,x,integral,eps=0.1,integral_new;
A = a;
B = b;
sel_ = sel;
integral_new=simpsons(f,limd,limu,i);
do{
integral=integral_new;
i=i+2;
integral_new=simpsons(f,limd,limu,i);
}while(fabs(integral_new-integral)>=eps);
/*Print the answer */
return integral_new;
}
main(){
printf ("Masukan Input Jarak 0 - 300 :");
scanf ("%f", &inputf);
printf ("Keanggotaan Jarak Deket : %f\n", FiN());
printf ("Keanggotaan Jarak Lumayan : %f\n", FiZ());
printf ("Keanggotaan Jarak Jauh : %f\n", FiP());
implikasi();
printf("a1 : %f\n", a1);
printf("b1a : %f\n", b1a);
printf("b1b : %f\n", b1b);
printf("c1 : %f\n", c1);
}
Please try it on your C language compiler and notice the implication results are in accordance with manual calculations or not.
Next we will compose all fuzzy mamdani Arduino output.
Composition of fuzzy logic output mamdani method using arduino or c language
We assume first to make it easy, for example the input we input for distance is 50, then the following data will be generated:
- Close Membership: 0.555556
- Fair Distance Membership: 0.000000
- Remote Membership: 0.000000
- A1: 44.444443
- b1a: 20.000000
- b1b: 235.000000
- c1: 155.000000
(100-pwm) / 100–0 for a1 <= pwm <= 100
if simplified then the result is like this
100 — pwm / 100
We try to validate by counting back pwm = 44.444443 then 100–44.444443 / 100 = 0.55556
The overall composition is as follows
- (100-pwm)/100–0 for a1 <= pwm <= 100
- 0.555556 for pwm < a1
- (pwm-20)/127.5–20 for 20 <= pwm <= b1a
- (235-pwm)/235–1275 for b1b <= pwm <= 235
- 0 for b1a < pwm > b1b
- (pwm-155)/255–155 for 155 <= pwm <= c1
- 0 for pwm > c1
Difficult to understand, huh? hehe, it’s hard, I’ve counted it many times, sometimes it’s wrong, so you have to be careful, and if you understand and find me wrong in writing formulas or explanations, you can comment right away.
Next we will calculate the area and this has entered the defuzzyfication stage.
Defuzzification of the Mamdani Method with Arduino or C Language
Calculating the area is very easy, because there are only triangles and squares or squares, so the formula for triangles is AxT / 2 or 1/2 AT. Meanwhile, the formula for the area of a square is length x width.
According to the sample, where the fuzzy distance input is 50 and data like the one above is found, we calculate it as follows.
- A1 = ((100 — a1) *0.55556) / 2 = 15.432222
- A2 = (a1–0) * 0.55556 = 24.69155
- A3 = ((b1a — 20)*0) / 2 = 0
- A4 = ((235 — b1b)*0) / 2 = 0
- A5 = (b1b — b1a)*0 = 0
- A6 = (c1–155)*0 / 2 = 0
- A7 = (255 — c1)* 0 = 0
We will try it directly with the program, whether the results are the same or there is a calculation error.
#include<stdio.h>
#include<math.h>
float A, B;
int sel_;
float a1, b1a, b1b, c1;
float A1, A2, A3, A4, A5, A6, A7;
float fudeket[4] = {0, 0, 10, 100};
float fulumayan[3] = {50, 150, 250};
float fujauh[4] = {200, 290, 300, 300};
float fylambat[3] = {0, 0, 100};
float fysedang[3] = {20, 127.5, 235};
float fycepat[3] = {155, 255, 255};
float inputf, outputf;
float FiN(){
if (inputf < fudeket[2]){return 1;}
else if (inputf >= fudeket[2] && inputf <= fudeket[3]){return (fudeket[3] - inputf)/(fudeket[3]-fudeket[2]);}
else if (inputf > fudeket[3]){return 0;}
}
float FiZ(){
if (inputf < fulumayan[0]){return 0;}
else if (inputf >= fulumayan[0] && inputf <= fulumayan[1]){return (inputf - fulumayan[0])/(fulumayan[1]-fulumayan[0]);}
else if (inputf >= fulumayan[1] && inputf <= fulumayan[2]){return (fulumayan[2] - inputf)/(fulumayan[2]-fulumayan[1]);}
else if (inputf > fulumayan[2]){return 0;}
}
float FiP(){
if (inputf < fujauh[0]){return 0;}
else if (inputf >= fujauh[0] && inputf <= fujauh[1]){return (inputf - fujauh[0])/(fujauh[1]-fujauh[0]);}
else if (inputf > fujauh[1]){return 1;}
}
float FoN(){
if (outputf < fylambat[1]){return 1;}
else if (outputf >= fylambat[1] && outputf <= fylambat[2]){return (fylambat[2] - outputf)/(fylambat[2]-fylambat[1]);}
else if (outputf > fylambat[2]){return 0;}
}
float FoZ(){
if (outputf < fysedang[0]){return 0;}
else if (outputf >= fysedang[0] && outputf <= fysedang[1]){return (outputf - fysedang[0])/(fysedang[1]-fysedang[0]);}
else if (outputf >= fysedang[1] && outputf <= fysedang[2]){return (fysedang[2] - outputf)/(fysedang[2]-fysedang[1]);}
else if (outputf > fysedang[2]){return 0;}
}
float FoP(){
if (outputf < fycepat[0]){return 0;}
else if (outputf >= fycepat[0] && outputf <= fycepat[1]){return (outputf - fycepat[0])/(fycepat[1]-fycepat[0]);}
else if (outputf > fycepat[1]){return 1;}
}
void implikasi (){
//sesuai dengan rule
// if deket then lambat
a1 = 100 - (FiN() * (fylambat[2] - fylambat[1]));
// if lumayan then sedang
b1a = 20 + (FiZ() * (fysedang[1] - fysedang[0]));
b1b = 235 - (FiZ() * (fysedang[2] - fysedang[1]));
// if jauh then cepat
c1 = 155 + (FiP() * (fycepat[1] - fycepat[0]));
}
void luas_deffuzzy(){
implikasi ();
A1 = ((fylambat[2] - a1) * FiN()) / 2; //= 15.432222
A2 = (a1 - fylambat[0]) * FiN(); // = 24.69155
A3 = ((b1a - fysedang[0])* FiZ()) / 2; // = 0
A4 = ((fysedang[2] - b1b)* FiZ()) / 2; // = 0
A5 = (b1b - b1a)*FiZ(); // = 0
A6 = ((c1 - fycepat[0]) * FiP()) / 2; // = 0
A7 = (fycepat[2] - c1)* FiP(); // = 0
}
float f(float x){
if (B > 0 && sel_ == 0){
return ((x-A)/B)*x;
}
else if (B > 0 && sel_ == 1){
return ((A-x)/B)*x;
}
else {
return A*x;
}
}
/*Function definition to perform integration by Simpson's 1/3rd Rule */
float simpsons(float f(float x), float a,float b,float n){
float h,integral,x,sum=0;
int i;
h=fabs(b-a)/n;
for(i=1;i<n;i++){
x=a+i*h;
if(i%2==0){
sum=sum+2*f(x);
}
else{
sum=sum+4*f(x);
}
}
integral=(h/3)*(f(a)+f(b)+sum);
return integral;
}
float fx(float limd, float limu, float a, float b, int sel){
int n,i=2;
float h,x,integral,eps=0.1,integral_new;
A = a;
B = b;
sel_ = sel;
integral_new=simpsons(f,limd,limu,i);
do{
integral=integral_new;
i=i+2;
integral_new=simpsons(f,limd,limu,i);
}while(fabs(integral_new-integral)>=eps);
/*Print the answer */
return integral_new;
}
main(){
printf ("Masukan Input Jarak 0 - 300 :");
scanf ("%f", &inputf);
printf ("Keanggotaan Jarak Deket : %f\n", FiN());
printf ("Keanggotaan Jarak Lumayan : %f\n", FiZ());
printf ("Keanggotaan Jarak Jauh : %f\n", FiP());
luas_deffuzzy();
printf("a1 : %f\n", a1);
printf("b1a : %f\n", b1a);
printf("b1b : %f\n", b1b);
printf("c1 : %f\n", c1);
printf("A1 :%f\n", A1);
printf("A2 :%f\n", A2);
printf("A3 :%f\n", A3);
printf("A4 :%f\n", A4);
printf("A5 :%f\n", A5);
printf("A6 :%f\n", A6);
printf("A7 :%f\n", A7);
}
Next, we will calculate the defuzzification moment for Mamdani Arduino or the C language.
In this calculation, we will need a little basic integral knowledge, if you forget the integral math material, please study again in high school mathematics material.
From the composition data that we calculated above, then we multiply it by x, because the integral is to the x-axis.
- A1 = ((100 — a1) *0.55556) / 2 = 15.432222
- A2 = (a1–0) * 0.55556 = 24.69155
- A3 = ((b1a — 20)*0) / 2 = 0
- A4 = ((235 — b1b)*0) / 2 = 0
- A5 = (b1b — b1a)*0 = 0
- A6 = (c1–155)*0 / 2 = 0
- A7 = (255 — c1)* 0 = 0
- M1 = ∫ ((100-x)/100)x dx ==================> limd a1 and limup 100
- M2 = ∫ 0.555556x dx ==================> limd 0 and limup a1
- M3 = ∫ ((x-20)/107.5)x dx ==================> limd 20 and limup b1a
- M4 = ∫ ((235-x)/107.5)x dx ==================> limd b1b and limup 235
- M5 = ∫ 0 dx ==================> limd b1a and limup b1b
- M6 = ∫ ((x-155)/100)x dx ==================> limd 155 and limup c1
- M7 = ∫ 0 dx ==================> limd c1 and limup 255
From the data above, we just believe that for M3 — M7 the result is definitely 0 hehe.
for the M1 please calculate it manually, and the results of my calculations are
- M1 = 971.64929
- M2 = 548.69865
To calculate the fuzzy, it is very easy, just calculate the center of the defuzzyfication area.
SUM M1 / SUM A1
(M1+M2+M3+M4+M5+M6+M7) / (A1+A2+A3+A4+A5+A6+A7)
The result of distance input = 50, then the fuzzy output is = 37,891
Here is a fuzzy mamdani final program with arduino or C language
Mamdani Fuzzy Logic C Language Code
#include<stdio.h>
#include<math.h>
float A, B;
int sel_;
float a1, b1a, b1b, c1;
float A1, A2, A3, A4, A5, A6, A7;
float M1, M2, M3, M4, M5, M6, M7;
float fudeket[4] = {0, 0, 10, 100};
float fulumayan[3] = {50, 150, 250};
float fujauh[4] = {200, 290, 300, 300};
float fylambat[3] = {0, 0, 100};
float fysedang[3] = {20, 127.5, 235};
float fycepat[3] = {155, 255, 255};
float inputf, outputf;
float FiN(){
if (inputf < fudeket[2]){return 1;}
else if (inputf >= fudeket[2] && inputf <= fudeket[3]){return (fudeket[3] - inputf)/(fudeket[3]-fudeket[2]);}
else if (inputf > fudeket[3]){return 0;}
}
float FiZ(){
if (inputf < fulumayan[0]){return 0;}
else if (inputf >= fulumayan[0] && inputf <= fulumayan[1]){return (inputf - fulumayan[0])/(fulumayan[1]-fulumayan[0]);}
else if (inputf >= fulumayan[1] && inputf <= fulumayan[2]){return (fulumayan[2] - inputf)/(fulumayan[2]-fulumayan[1]);}
else if (inputf > fulumayan[2]){return 0;}
}
float FiP(){
if (inputf < fujauh[0]){return 0;}
else if (inputf >= fujauh[0] && inputf <= fujauh[1]){return (inputf - fujauh[0])/(fujauh[1]-fujauh[0]);}
else if (inputf > fujauh[1]){return 1;}
}
float FoN(){
if (outputf < fylambat[1]){return 1;}
else if (outputf >= fylambat[1] && outputf <= fylambat[2]){return (fylambat[2] - outputf)/(fylambat[2]-fylambat[1]);}
else if (outputf > fylambat[2]){return 0;}
}
float FoZ(){
if (outputf < fysedang[0]){return 0;}
else if (outputf >= fysedang[0] && outputf <= fysedang[1]){return (outputf - fysedang[0])/(fysedang[1]-fysedang[0]);}
else if (outputf >= fysedang[1] && outputf <= fysedang[2]){return (fysedang[2] - outputf)/(fysedang[2]-fysedang[1]);}
else if (outputf > fysedang[2]){return 0;}
}
float FoP(){
if (outputf < fycepat[0]){return 0;}
else if (outputf >= fycepat[0] && outputf <= fycepat[1]){return (outputf - fycepat[0])/(fycepat[1]-fycepat[0]);}
else if (outputf > fycepat[1]){return 1;}
}
void implikasi (){
//sesuai dengan rule
// if deket then lambat
a1 = 100 - (FiN() * (fylambat[2] - fylambat[1]));
// if lumayan then sedang
b1a = 20 + (FiZ() * (fysedang[1] - fysedang[0]));
b1b = 235 - (FiZ() * (fysedang[2] - fysedang[1]));
// if jauh then cepat
c1 = 155 + (FiP() * (fycepat[1] - fycepat[0]));
}
void luas_deffuzzy(){
implikasi ();
A1 = ((fylambat[2] - a1) * FiN()) / 2; //= 15.432222
A2 = (a1 - fylambat[0]) * FiN(); // = 24.69155
A3 = ((b1a - fysedang[0])* FiZ()) / 2; // = 0
A4 = ((fysedang[2] - b1b)* FiZ()) / 2; // = 0
A5 = (b1b - b1a)*FiZ(); // = 0
A6 = ((c1 - fycepat[0]) * FiP()) / 2; // = 0
A7 = (fycepat[2] - c1)* FiP(); // = 0
}
float f(float x){
if (B > 0 && sel_ == 0){
return ((x-A)/B)*x;
}
else if (B > 0 && sel_ == 1){
return ((A-x)/B)*x;
}
else {
return A*x;
}
}
/*Function definition to perform integration by Simpson's 1/3rd Rule */
float simpsons(float f(float x), float a,float b,float n){
float h,integral,x,sum=0;
int i;
h=fabs(b-a)/n;
for(i=1;i<n;i++){
x=a+i*h;
if(i%2==0){
sum=sum+2*f(x);
}
else{
sum=sum+4*f(x);
}
}
integral=(h/3)*(f(a)+f(b)+sum);
return integral;
}
float fx(float limd, float limu, float a, float b, int sel){
int n,i=2;
float h,x,integral,eps=0.1,integral_new;
A = a;
B = b;
sel_ = sel;
integral_new=simpsons(f,limd,limu,i);
do{
integral=integral_new;
i=i+2;
integral_new=simpsons(f,limd,limu,i);
}while(fabs(integral_new-integral)>=eps);
/*Print the answer */
return integral_new;
}
/*
(fylambat[2]-pwm)/fylambat[2]-fylambat[0] untuk a1 <= pwm <= 100
FiN() untuk pwm < a1
(pwm-20)/127.5-20 untuk 20 <= pwm <= b1a
(235-pwm)/235-1275 untuk b1b <= pwm <= 235
0 untuk b1a < pwm > b1b
(pwm-155)/255-155 untuk 155 <= pwm <= c1
0 untuk pwm > c1
*/
void moment(){
luas_deffuzzy();
//M1 = ∫ ((100-x)/100)x dx ==================> limd a1 dan limup 100
M1 = fx(a1, fylambat[2], fylambat[2], (fylambat[2]-fylambat[0]), 1);
//M2 = ∫ 0.555556x dx ==================> limd 0 dan limup a1
M2 = fx(fylambat[0], a1, FiN(), 0, 0);
//M3 = ∫ ((x-20)/107.5)x dx ==================> limd 20 dan limup b1a
M3 = fx(fysedang[0], b1a, fysedang[0], (fysedang[1] - fysedang[0]), 0);
//M4 = ∫ ((235-x)/107.5)x dx ==================> limd b1b dan limup 235
M4 = fx (b1b, fysedang[2], fysedang[2], (fysedang[2]-fysedang[1]), 1);
//M5 = ∫ 0 dx ==================> limd b1a dan limup b1b
M5 = fx (b1a, b1b, FiZ(), 0, 0);
//M6 = ∫ ((x-155)/100)x dx ==================> limd 155 dan limup c1
M6 = fx(fycepat[0], c1, fycepat[0], (fycepat[2]-fycepat[0]), 0);
//M7 = ∫ 0 dx ==================> limd c1 dan limup 255
M7 = fx(c1, fycepat[2], FiP(), 0, 0);
}
float deffuzzyfikasi(){
return (M1+M2+M3+M4+M5+M6+M7)/(A1+A2+A3+A4+A5+A6+A7);
}
main(){
printf ("Masukan Input Jarak 0 - 300 :");
scanf ("%f", &inputf);
printf ("Keanggotaan Jarak Deket : %f\n", FiN());
printf ("Keanggotaan Jarak Lumayan : %f\n", FiZ());
printf ("Keanggotaan Jarak Jauh : %f\n", FiP());
moment();
printf("a1 : %f\n", a1);
printf("b1a : %f\n", b1a);
printf("b1b : %f\n", b1b);
printf("c1 : %f\n", c1);
printf("A1 :%f\n", A1);
printf("A2 :%f\n", A2);
printf("A3 :%f\n", A3);
printf("A4 :%f\n", A4);
printf("A5 :%f\n", A5);
printf("A6 :%f\n", A6);
printf("A7 :%f\n", A7);
printf("M1 : %f\n", M1);
printf("M2 : %f\n", M2);
printf("M3 : %f\n", M3);
printf("M4 : %f\n", M4);
printf("M5 : %f\n", M5);
printf("M6 : %f\n", M6);
printf("M7 : %f\n", M7);
printf("OutDefuzzyfikasi : %f", deffuzzyfikasi());
}
Finally, friends of the Arduino Fuzzy Mamdani method tutorial, how do you feel?
I was also tired and dizzy for half a day calculating the fuzzy for one input and one output.
What if two inputs are one output or so? leave it to admin anakkontrol.com hehe. later the admin will help.
Following are the results of testing with Labview and Fuzzy Mamdani C language above.
Code Arduino Fuzzy Logic Mamdani
#include<math.h>
float A, B;
int sel_;
float a1, b1a, b1b, c1;
float L1, L2, L3, L4, L5, L6, L7;
float M1, M2, M3, M4, M5, M6, M7;
float fudeket[4] = {0, 0, 10, 100};
float fulumayan[3] = {50, 150, 250};
float fujauh[4] = {200, 290, 300, 300};
float fylambat[3] = {0, 0, 100};
float fysedang[3] = {20, 127.5, 235};
float fycepat[3] = {155, 255, 255};
float inputf, outputf;
float FiN() {
if (inputf < fudeket[2]) {
return 1;
}
else if (inputf >= fudeket[2] && inputf <= fudeket[3]) {
return (fudeket[3] - inputf) / (fudeket[3] - fudeket[2]);
}
else if (inputf > fudeket[3]) {
return 0;
}
}
float FiZ() {
if (inputf < fulumayan[0]) {
return 0;
}
else if (inputf >= fulumayan[0] && inputf <= fulumayan[1]) {
return (inputf - fulumayan[0]) / (fulumayan[1] - fulumayan[0]);
}
else if (inputf >= fulumayan[1] && inputf <= fulumayan[2]) {
return (fulumayan[2] - inputf) / (fulumayan[2] - fulumayan[1]);
}
else if (inputf > fulumayan[2]) {
return 0;
}
}
float FiP() {
if (inputf < fujauh[0]) {
return 0;
}
else if (inputf >= fujauh[0] && inputf <= fujauh[1]) {
return (inputf - fujauh[0]) / (fujauh[1] - fujauh[0]);
}
else if (inputf > fujauh[1]) {
return 1;
}
}
float FoN() {
if (outputf < fylambat[1]) {
return 1;
}
else if (outputf >= fylambat[1] && outputf <= fylambat[2]) {
return (fylambat[2] - outputf) / (fylambat[2] - fylambat[1]);
}
else if (outputf > fylambat[2]) {
return 0;
}
}
float FoZ() {
if (outputf < fysedang[0]) {
return 0;
}
else if (outputf >= fysedang[0] && outputf <= fysedang[1]) {
return (outputf - fysedang[0]) / (fysedang[1] - fysedang[0]);
}
else if (outputf >= fysedang[1] && outputf <= fysedang[2]) {
return (fysedang[2] - outputf) / (fysedang[2] - fysedang[1]);
}
else if (outputf > fysedang[2]) {
return 0;
}
}
float FoP() {
if (outputf < fycepat[0]) {
return 0;
}
else if (outputf >= fycepat[0] && outputf <= fycepat[1]) {
return (outputf - fycepat[0]) / (fycepat[1] - fycepat[0]);
}
else if (outputf > fycepat[1]) {
return 1;
}
}
void implikasi () {
//sesuai dengan rule
// if deket then lambat
a1 = 100 - (FiN() * (fylambat[2] - fylambat[1]));
// if lumayan then sedang
b1a = 20 + (FiZ() * (fysedang[1] - fysedang[0]));
b1b = 235 - (FiZ() * (fysedang[2] - fysedang[1]));
// if jauh then cepat
c1 = 155 + (FiP() * (fycepat[1] - fycepat[0]));
}
void luas_deffuzzy() {
implikasi ();
L1 = ((fylambat[2] - a1) * FiN()) / 2; //= 15.432222
L2 = (a1 - fylambat[0]) * FiN(); // = 24.69155
L3 = ((b1a - fysedang[0]) * FiZ()) / 2; // = 0
L4 = ((fysedang[2] - b1b) * FiZ()) / 2; // = 0
L5 = (b1b - b1a) * FiZ(); // = 0
L6 = ((c1 - fycepat[0]) * FiP()) / 2; // = 0
L7 = (fycepat[2] - c1) * FiP(); // = 0
}
float f(float x) {
if (B > 0 && sel_ == 0) {
return ((x - A) / B) * x;
}
else if (B > 0 && sel_ == 1) {
return ((A - x) / B) * x;
}
else {
return A * x;
}
}
/*Function definition to perform integration by Simpson's 1/3rd Rule */
float simpsons(float f(float x), float a, float b, float n) {
float h, integral, x, sum = 0;
int i;
h = fabs(b - a) / n;
for (i = 1; i < n; i++) {
x = a + i * h;
if (i % 2 == 0) {
sum = sum + 2 * f(x);
}
else {
sum = sum + 4 * f(x);
}
}
integral = (h / 3) * (f(a) + f(b) + sum);
return integral;
}
float fx(float limd, float limu, float a, float b, int sel) {
int n, i = 2;
float h, x, integral, eps = 0.1, integral_new;
A = a;
B = b;
sel_ = sel;
integral_new = simpsons(f, limd, limu, i);
do {
integral = integral_new;
i = i + 2;
integral_new = simpsons(f, limd, limu, i);
} while (fabs(integral_new - integral) >= eps);
/*Print the answer */
return integral_new;
}
/*
(fylambat[2]-pwm)/fylambat[2]-fylambat[0] untuk a1 <= pwm <= 100
FiN() untuk pwm < a1
(pwm-20)/127.5-20 untuk 20 <= pwm <= b1a
(235-pwm)/235-1275 untuk b1b <= pwm <= 235
0 untuk b1a < pwm > b1b
(pwm-155)/255-155 untuk 155 <= pwm <= c1
0 untuk pwm > c1
*/
void moment() {
luas_deffuzzy();
//M1 = ∫ ((100-x)/100)x dx ==================> limd a1 dan limup 100
M1 = fx(a1, fylambat[2], fylambat[2], (fylambat[2] - fylambat[0]), 1);
//M2 = ∫ 0.555556x dx ==================> limd 0 dan limup a1
M2 = fx(fylambat[0], a1, FiN(), 0, 0);
//M3 = ∫ ((x-20)/107.5)x dx ==================> limd 20 dan limup b1a
M3 = fx(fysedang[0], b1a, fysedang[0], (fysedang[1] - fysedang[0]), 0);
//M4 = ∫ ((235-x)/107.5)x dx ==================> limd b1b dan limup 235
M4 = fx (b1b, fysedang[2], fysedang[2], (fysedang[2] - fysedang[1]), 1);
//M5 = ∫ 0 dx ==================> limd b1a dan limup b1b
M5 = fx (b1a, b1b, FiZ(), 0, 0);
//M6 = ∫ ((x-155)/100)x dx ==================> limd 155 dan limup c1
M6 = fx(fycepat[0], c1, fycepat[0], (fycepat[2] - fycepat[0]), 0);
//M7 = ∫ 0 dx ==================> limd c1 dan limup 255
M7 = fx(c1, fycepat[2], FiP(), 0, 0);
}
float deffuzzyfikasi() {
moment();
return (M1 + M2 + M3 + M4 + M5 + M6 + M7) / (L1 + L2 + L3 + L4 + L5 + L6 + L7);
}
void setup() {
Serial.begin(9600);
Serial.println("---Program Fuzzy anakkendali.co---");
Serial.println ("Masukan Input Jarak 0 - 300 :");
}
void loop() {
if (Serial.available()) {
int a = Serial.parseInt();
if (a >= 0) {
inputf = a;
Serial.print("Input jarak :");
Serial.print(inputf);
Serial.println(" CM");
Serial.print("Output Deffuzyfikasi Mamdani :");
Serial.println(deffuzzyfikasi());
}
}
}
The following are the results that appear on the Arduino serial monitor
Keyword
- fuzzy arduino,
- arduino fuzzy,
- Arduino fuzzy logic,
- Arduino fuzzy logic explanation,
- Arduino fuzzy logic tutorial,
- fuzzy logic c language,
- fuzzy logic c language,
- fuzzy logic mamdani arduino,
- fuzzy mamdani arduino,
- arduino fuzzy mamdani,
- -