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.

Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Mamdani for Arduino

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.

Fuzzy logic mamdani input dan output

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

Tokopedia.com

  • 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
  1. M1 = ∫ ((100-x)/100)x dx ==================> limd a1 and limup 100
  2. M2 = ∫ 0.555556x dx ==================> limd 0 and limup a1
  3. M3 = ∫ ((x-20)/107.5)x dx ==================> limd 20 and limup b1a
  4. M4 = ∫ ((235-x)/107.5)x dx ==================> limd b1b and limup 235
  5. M5 = ∫ 0 dx ==================> limd b1a and limup b1b
  6. M6 = ∫ ((x-155)/100)x dx ==================> limd 155 and limup c1
  7. 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.

Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Bahasa C Mamdani
Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Bahasa C Mamdani

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

Tutorial Fuzzy Logic Mamdani for Arduino
Tutorial Fuzzy Logic Mamdani for Arduino
Arduino Fuzzy Logic Mamdani Jarak dan PWM Motor DC

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,

- -

Learn microcontroller with anakkendali.com