const double NB = 0.25 ;
const double NS = 0.4;
const double ZE = 0.5;
const double PS = 0.6;
const double PB = 0.75;
const byte ROWS = 5; //five rows
const byte COLS = 5; //five columns
const double Vref= 4.4;
const double Ratio = 0.216608; // The ratio of the voltage divider
const int analogPin = 0; // pin that the sensor is attached to
const int OutputPin = 9; //output pin
boolean initialize = true;
double e = 0;
// expert rules
double Rules[ROWS][COLS] =
{
{NB,NB,NB,NS,ZE},
{NB,NB,NS,ZE,PS},
{NB,NS,ZE,PS,PB},
{NS,ZE,PS,PB,PB},
{ZE,PS,PB,PB,PB},
};
// fuzzy operators
double AND(double u1, double u2)
{
return min(u1, u2);
}
double OR(double u1, double u2)
{
return max(u1, u2);
}
// Membership functions for error
double ErrorNegativeBig(double x)
{ if (x<=(-2)) return 1;
if (x>=(-1)) return 0;
else return ((-1)-x)/(-1-(-2));
}
double ErrorNegativeSmall(double x)
{
if (x<=(-2) || x>=0) return 0;
if (x=(-1)) return 1;
if (x<(-1)) return(x-(-2))/(-1-(-2));
else return (0-x)/(0-(-1));
}
double ErrorZeroEqual(double x)
{
if (x<=(-1) || x>=1) return 0;
if (x=0) return 1;
if (x<0) return(x-(-1))/(0-(-1));
else return (1-x)/(1-0);
}
double ErrorPositiveSmall(double x)
{
if (x<=0 || x>=2) return 0;
if (x=1) return 1;
if (x<1) return(x-0)/(1-0);
else return (2-x)/(2-1);
}
double ErrorPositiveBig(double x)
{
if (x<=1) return 0;
if (x>=2) return 1;
return (x-1)/(2-1);
}
// Membership functions for Difference in Error(Derror)
double DerrorNegativeBig(double x)
{ if (x<=(-7)) return 1;
if (x>=(-3.5)) return 0;
return ((-3.5)-x)/(-3.5-(-7));
}
double DerrorNegativeSmall(double x)
{
if (x<=-7 || x>=0) return 0;
if (x=(-3.5)) return 1;
if (x<(-3.5)) return(x-(-7))/(-3.5-(-7));
else return (0-x)/(0-(-3.5));
}
double DerrorZeroEqual(double x)
{
if (x<=(-3.5) || x>=3.5) return 0;
if (x=0) return 1;
if (x<0) return(x-(-3.5))/(0-(-3.5));
else return (3.5-x)/(3.5-0);
}
double DerrorPositiveSmall(double x)
{
if (x<=0 || x>=7) return 0;
if (x = 3.5) return 1;
if (x<3.5) return (x-0)/(3.5-0);
else return (7-x)/(7-3.5);
}
double DerrorPositiveBig(double x)
{
if (x<=3.5) return 0;
if (x>=7) return 1;
return (x-3.5)/(7-3.5);
}
void setup() {
TCCR1B = TCCR1B & 0b11111000 | 0x01; // set the pwm output pin 9 frequency as 31.45kHz
pinMode(OutputPin, OUTPUT); // sets the digital pin9 as output
Serial.begin(9600);
}
void loop() {
int i;
int j;
double Error[5];
double Derror[5];
double actualvout;
double sumu;
double percent;
double action;
double tmpu;
double lastE;
double de;
if (initialize == true)
{
Serial.println("#$%^&*@#%$^&*@$^%&$*&@*&$@*$%*@%$*&@^%$*&^%@*&*§_DISCOURSE_HOISTED_CODE_0_§@^%$*@");
initialize = false;
lastE = 0;
} else {
Serial.println("error i - 1");
Serial.println(e);
lastE = e;
}
double vout = analogRead(analogPin);// read the value of the potentiometer
actualvout = (vout/1023) * 5 / Ratio; // Multiply the ratio which the output voltage after passing through the voltage divider e = Vref-actualvout;
Serial.println("actualvout");
Serial.println(actualvout);
e = Vref- actualvout;
Serial.println("error");
Serial.println(e);
Serial.println("lastEEEEEEEEEEE");
Serial.println(lastE);
de = e - lastE;
Serial.println("Derror");
Serial.println(de);
e = -0.477;// for testing
de=2.7;//for testing
// fuzzification
Error[0]=ErrorNegativeBig(e);
Error[1]=ErrorNegativeSmall(e);
Error[2]=ErrorZeroEqual(e);
Error[3]=ErrorPositiveSmall(e);
Error[4]=ErrorPositiveBig(e);
for (int i=0; i<5; i++) {
Serial.print("Error");
Serial.println(i);
Serial.println(Error[i]);
}
Derror[0]=DerrorNegativeBig(de);
Derror[1]=DerrorNegativeSmall(de);
Derror[2]=DerrorZeroEqual(de);
Derror[3]=DerrorPositiveSmall(de);
Derror[4]=DerrorPositiveBig(de);
for (int i=0; i<5; i++) {
Serial.print("DError");
Serial.println(i);
Serial.println(Derror[i]);
}
// fuzzy inference
sumu=0; percent=0;
for (i=0; i<5; i++){
for(j=0; j<5; j++)
{
tmpu = AND(Error[i],Derror[j]); //temporary Degree of membership of
Serial.println("tmpu");
Serial.println(tmpu);
percent = percent + Rules[j][i]*tmpu;
Serial.println("percent");
Serial.println(percent);
sumu = sumu + tmpu;
Serial.println("sumu");
Serial.println(sumu);
}
}
//defuzzification
percent = percent / sumu;
Serial.println("percent");
Serial.println(percent);
action = 255 * percent ;
Serial.println("action");
Serial.println(action);
analogWrite(OutputPin, action); //Do the action which generates from the rules
}
The problem I faced is that when I put decimal into my function, it gives return 1.
For example, e = -0.477, then for the function:
double ErrorPositiveSmall(double x)
{
if (x<=(-2) || x>=0) return 0;
if (x=(-1)) return 1;
if (x<(-1)) return(x-(-2))/(-1-(-2));
else return (0-x)/(0-(-1));
}
My expected returned number is(0-(-0.477))/(0-(-1) =0.477,
but When I use Serial.print(“Error”);
Serial.println(i);
Serial.println(Error*);*
to check, I found that all the returned decimal value seems to become 1 or 0…
Can anybody know what is the fault?.. Many thanks… :’(