# Help me find out the error of my program

``````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;
}
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… :’(

``````       if (x=(-1)) return 1;
``````

Did you want == here? I suspect that you did.

And here?

``````      if (x=0) return 1;
``````
``````if (x=1) return 1;
``````

Well, there's one.

Hmm, beat me by 13 seconds! (I gave up looking for any more at that point) Edit: There are lots more.[/edit]

Really good to see that you thoroughly tested your routines before committing to putting them into a big program. Keep it up, and carry on setting a good example.

It would also be a good idea to use floating point constants in your expressions that use floating point variables. ("if (x==1.0)" rather than "if (x==1)") Some (most?) of these will probably work the way you expect, but this is one of the ways that C will let you shoot yourself in the foot.

Also, beware that checking for equality of floating point numbers is pretty dangerous. 1.00001 will not be equal to 1.0 (or maybe it will.) You may need to implement an "almostequals" function or macro.

Thanks for help. That problem was fixed but some logic of those equation maybe wrong. I need to correct it.

``````const double NB = -0.25 ;
const double NS = -0.1;
const double ZE = 0;
const double PS = 0.1;
const double PB = 0.25;
const double Vref= 4.40;
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;
double D = 0.5;
// expert rules
double Rules[5][5] =
{
{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.6)) return 1;
if (x>=(-0.8)) return 0;
else return ((-0.8)-x)/(-0.8-(-2.6));
}

double ErrorNegativeSmall(double x)
{
if (x<=(-2.6) || x>=0) return 0;
if (x==(-0.8)) return 1;
if (x<(-0.8)) return(x-(-2.6))/(-0.8-(-2.6));
else return (0-(x))/(0-(-0.8));
}

double ErrorZeroEqual(double x)
{
if (x<=(-0.8) || x>=1) return 0;
if (x==0) return 1;
if (x<0) return(x-(-0.8))/(0-(-0.8));
else return (1-x)/(1-0);
}

double ErrorPositiveSmall(double x)
{
if (x<=0 || x>=4.4) return 0;
if (x==1) return 1;
if (x<1) return(x-0)/(1-0);
else return (4.4-x)/(4.4-1);
}

double ErrorPositiveBig(double x)
{
if (x<=1) return 0;
if (x>=4.4) return 1;
return (x-1)/(4.4-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 LD; //last D
double de;
if (initialize == true)
{
Serial.println("#\$%^&*@#%\$^&*@\$^%&\$*&@*&\$@*\$%*@%\$*&@^%\$*&^%@*&*§_DISCOURSE_HOISTED_CODE_0_§@^%\$*@");
initialize = false;
lastE = 0;
LD = 0.5;
}
else {
Serial.println("error i - 1");
Serial.println(e);
lastE = e;
Serial.println("LD i-1");
Serial.println(LD);
LD = D;
}
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 ;//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("LD");
Serial.println(LD);
D = LD + percent;
LD = D;
Serial.println("percent");
Serial.println(percent);
Serial.println("D");
Serial.println(D);
action = 255 * D ;
Serial.println("action");
Serial.println(action);
analogWrite(OutputPin, action);     //Do the action which generates from the rules
}
``````

After fixing the “==” problem, I modify the program a lot. I think there is one more problem which I cannot debug it. That is :

`````` if (initialize == true)
{
Serial.println("#\$%^&*@#%\$^&*@\$^%&\$*&@*&\$@*\$%*@%\$*&@^%\$*&^%@*&*§_DISCOURSE_HOISTED_CODE_1_§@^%\$*@");
initialize = false;
lastE = 0;
LD = 0.5;
}
else {
Serial.println("error i - 1");
Serial.println(e);
lastE = e;
Serial.println("LD i-1");
Serial.println(LD);
LD = D;
}
``````

My friend told me this method can store the last looping’s data. Actually is first put the initialize box be true, then all the things inside will be run at the first time only and the box will then be false. After the next loop begin, the true statement will never run again.
All things seems to be right at the first loop.

#\$%^&@#%\$^&@\$^%&\$&@&\$@\$%@%\$&@^%\$&^%@&\$&@^%\$*@
actualvout
0.00
error
4.40
lastEEEEEEEEEEE
0.00
Derror
4.40
LD
0.50
percent
0.25
D
0.75
action
191.25

But after the 2nd looping, I can see from the com 4 giving this result:

error i - 1
4.40
LD i-1
0.00
actualvout
0.00
error
4.40
lastEEEEEEEEEEE
4.40
Derror
0.00
LD
0.75
percent
0.25
D
1.00
action
255.00

I found that the “error i - 1” can store the last loop data but the LD cannnot, i.e. 0.

Can anybody find the error which I made? :-[