Fuzzy logic

I am building a RC tank/bot using the sparkfun motor shield and I need a little help with the control. I plan on using pulseIN to capture the PWM signal from an RC receiver (I will be using two channels) which will return a value of roughly 800 to 1200 and 1000 will be center. If the value is between 800 and 1000, the bot will move backwards and the speed will depend on the magnitude from 1000. If it is between 1000 and 1200, the robot will go forward with the speed depending on the magnitude. So 1100 would be slow forward 1200 would be max speed forward. 800 would be max speed in reverse and 900 would be slow in reverse. However, I want the speed to be proportional.

The motor shield requires two pieces of information for each motor, direction (digital) and speed (analog). So "1" will set the direction to forward and analog value of 0 would be 0 speed, 255 will be full speed. "0" would be reverse with 0 being no speed, 255 also being full speed.

My question is, how do I convert the PWM in signal to be compatible with the motor shield?

I believe it would be something along the lines of..

if (pulseIn-1000) > 0 //subtract 1000 from pulseIn to make "0" center instead of 1000 being center
Direction = 1 // Sets direction to forward

if (pulseIn-1000) < 0
Direction = 0

Now, since I shifted pulseIn to have 0 being center instead of 1000...

// |800-1055|= 255
// 1200-1055 = 255

speed = pulseIn - 1055 //returns a value between the absolute value of 800-1055 and 1200-1055

Or could I get away with something like this...

pulseIn = map(pulseIn, 800, 1200, -255, 255) // maps pulseIn from 800, 1200 to -255 and 255 so 0 should be center..hopefully

if (pulseIn) > 0
Direction = 1 // Sets direction to forward

if (pulseIn) < 0
Direction = 0

speed = abs(pulseIn) // speed is equal to the absolute value of pulseIn, inverting the -255 to 255

I read an article on SOR about fuzzy logic. This is my first time trying to implement this so I tried to come up with as many ideas as possible. If anyone would mind looking over my sudo code or even pitch in, it would be greatly appreciated.

Nothing fuzzy about it.

Do your calculation and if the number is positive the direction pin is LOW and output the speed. If it is negative, then set the direction pin HIGH and output minus the speed . (speed vs. -speed)

Don't try to make things more complex than they need to be. You need to know whether to set the direction pin High or Low and still send a positive value to the PWM pin.

Something like this -

Speed = pulsein - 1055;
if (Speed > 0) {   // this 0 could be 5 or 10 to give some deadband
     DigitalWrite(DirPin,LOW);
     Analogwrite(SpdPin,Speed); 
   }
   else if (Speed < 0) {   // this 0 could be -5 or -10 to give some deadband
      DigitalWrite(DirPin,HIGH);
      Analogwrite(SpdPin,-Speed);
   }
   else {
   AnalogWrite(SpdPin,0);
  }

To reverse the operation, just swap the HIGH and LOW after DirPin.
[DISCLAIMER] Code may not be correct as writen, but the logic I am trying to explain is...

Ah, I see. My next question is, the difference between 800 and 1000 is 200. If I subtract 1055 from pulseIn, I will be able to reach 255, but if pulseIn is centered at 1000 and I subtract 1055, I will be left with speed being equal to 55. I know a little deadband is desirable but 55 is a little much. How would I go about both having 0 as center and still being able to reach 255?

I think I would need a scaling factor. 200/255 = 0.78 so I would just multiply "speed" by 0.78 and only subtract 1000 instead of 1055. That would allow me to keep 0 as center while being able to reach the full range of analogWrite, which is 255.

Or am I just making something simple too complicated? :cold_sweat:

Or am I just making something simple too complicated?

You'll know whether you need to be concerned, or not, after you "Just Do It!".

I do not have the motor shield yet, so I am unable to test the code. I should have it by the end of this week though. I also just remembered the other half of the problem I am facing. Differential steering. I want one pulseIn stream to give me forward/backwards and speed while the second pulseIn allows the bot to steer differentially and proportionally. I am typing this on my phone at work, I'll have to write the sudo code later today. I think I would just subtract pulseIn2 from speed. PulseIn2 would need a positive and negative speed output for the subtraction to work.

I do not have the motor shield yet, so I am unable to test the code.

Not so.
You could abstract the motor control into something visual, like serial prints.

It would be helpful if you read what the pulseIn() function measures, and use that measurement in your project description, instead of the name of the function used to obtain that measurement. I'm sure that time is easier to type than pulseIn(), too.

I finally got time to work on it. I have to stress, the purpose of this bot is NOT to simply get it to just drive around. I want to test different programming styles and techniques such as pulseIn() vs interrupts, map() vs shifting a value and dividing the endpoints to get the same effect, using arrays to set acceleration profiles, and basically just learn how to program better.

Essentially, I use pulseIn to capture the pulses of two PWM RC receiver channels (elevator and aileron) I map them from 982,1982 to -255,255. The elevator channel adds/subtracts to both left and right motors, while the aileron subtracts from one side and adds to the other. The aileron value can be + or - so it can cancel out the hard coded +- sign. It is explained in the comments of my code.
I use analogWrite and abs() to strip the negative sign away from the control pulse for speed control. On the directional control side, if the control pulse is in the negative, IE less than 0, the motor goes in reverse, if it is greater than 0, it will go forward. I tried to map 982,1982 to 0,1 but it didn't quite work out too well for direction control. I also tried to shift the pulse with subtraction and divide it by 255 to get the same effect as map() but higher precision but I got some funky numbers. (Yes, I know PWM out only does integers but in the case I need 0.00 precision, I think that will work better)

This is the rough rough code, but it works. For some reason, when I reach the higher 80%ish limits on my RC radio, I get some weird results. Say if I put the elevator stick forward to make the robot drive forward, it will work fine until it hits 80% then it simply stops for a second and then keeps going. It doesn't happen all the time though, it seems to be random. I also wouldn't mind programing a function to calibrate the sticks min/max values. Eventually I intend to switch from pulseIn() to using interrupts for more precision. But I will start with baby steps..

/*
  Arduino RC robot
  Uses ardumoto shield and a standard rc receiver for control
  
*/



int speed_right = 3;  //PWM control for motor outputs 1 and 2 is on digital pin 3
int speed_left = 11;  //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_right = 12;  //direction control for motor outputs 1 and 2 is on digital pin 12
int dir_left = 13;  //direction control for motor outputs 3 and 4 is on digital pin 13

int ele = 6;      //RC rx elevator ch connected 
int ail = 5;      //RC rx aileron ch connected 
//int rud = 7;    //RC rx rudder ch connected

int ele_max = 1985;  //max of elevator channel
//int ele_cent = 1488; //center of elevator channel 
int ele_min = 982;   //min of elevator channel

int ail_max = 1985; //max of aileron channel
//int ail_cent = 1488; //center of aileron channel
int ail_min = 982; //min of aileron channel

/*
int rud_max =   //max of rudder channel
int rud_cent =  //center of rudder channel
int rud_min =   //min of rudder channel
*/

// int fwd and int bkw may be unnecessary!
//int fwd = HIGH;  //forward is HIGH for digitalWrites() 
//int bkw = LOW;   //backward is LOW for digitalWrites()

int wait = 1000;  //delay interval in milliseconds

unsigned long prevtime = 0; //placeholder for the last time it was updated with millis()

void setup()
{
  pinMode(speed_left, OUTPUT);  //Set control pins to be outputs
  pinMode(speed_right, OUTPUT);
  pinMode(dir_right, OUTPUT);
  pinMode(dir_left, OUTPUT);
  
  pinMode(ele, INPUT);
  pinMode(ail, INPUT);
  //pinMode(rud, INPUT);
  
  Serial.begin(9600);
  
  analogWrite(speed_left, 0);  //set both motors to run at 0 speed so robot does not move
  analogWrite(speed_right, 0);
  
}

void loop()
{
  unsigned long time = millis();  //sets up the time 
  
  //                    This section gathers and converts inputs               // 
  unsigned long ele_pulse = pulseIn(ele, HIGH, 25000);   //Reads the pulses channel of RC RX
  unsigned long ail_pulse = pulseIn(ail, HIGH, 25000);  

  int ele_speed = map(ele_pulse, ele_min, ele_max, -255, 255);  //maps max and mins of the pulse
  int ail_speed = map(ail_pulse, ail_min, ail_max, -255, 255);  // -255 to 255 for analogWrite()
  
  //int ele_dir = map(ele_pulse, ele_min, ele_max, 0,1);  //maps max and mins of pulse
  //int ail_dir = map(ail_pulse, ail_min, ail_max, 0,1);  // 0 and 1 for backward and forward
  
 
  int speedL = ele_speed - ail_speed; //mixes elevator and aileron channels. Aileron has + and - values at the same time
  int speedR = ele_speed + ail_speed; //one side needs the opposite value added... 255+(-255) = 0 and 255 - (+255) = 0
 
  if(speedL<0){
    digitalWrite(dir_left, LOW);   // sets up the direction depending on magnitude of "speedL/R" 
  }
  if(speedL>0){
    digitalWrite(dir_left, HIGH);
  }
  if(speedR<0){
    digitalWrite(dir_right, LOW);
  }
  if(speedR>0){
    digitalWrite(dir_right, HIGH);
  }

  
  analogWrite(speed_left, abs(speedL));  // speed is the absolute value
  analogWrite(speed_right, abs(speedR)); //   removes negative sign
  
  
  
  // DEBUG AREA 
  
  if(time - prevtime > wait){
  //Serial.print("elespeed = "); Serial.print(ele_speed); Serial.print("  eledir = "); Serial.print(ele_dir);Serial.print("  elepulse = "); Serial.println(ele_pulse);
  //Serial.println("             ");
  
  Serial.print("speedL = "); Serial.print(speedL);
  Serial.print("  speedR = "); Serial.println(speedR);
  //Serial.println(" ");
  
  
 // Serial.print("ailspeed = "); Serial.print(ail_speed); Serial.print("  aildir = "); Serial.print(ail_dir);Serial.print("  ailpulse = "); Serial.println(ail_pulse);
 // Serial.println("======================================================");
  
  prevtime = time;
  } 
 
}

This is also my first program!

whiteglint143:
Say if I put the elevator stick forward to make the robot drive forward, it will work fine until it hits 80% then it simply stops for a second and then keeps going.

This sounds a bit like number overflow, although the inconsistency in the behaviour is a little puzzling. I haven't looked at your code, but if you're dealing with time and have an overflow anywhere in your calculation, that might be sensitive to when you carry out the calculation and therefor appear inconsistent.

The time portion is only for the serial monitor part. Other than that, pulseIn's largest value is 1985ish and I am using an unsigned long to store that value. I think I know what the problem is though. When I measured the pulses, I used pulseIn() and the largest value I was getting was about 1985 but it did drift a little by about +-10. I hard coded that value of 1985 as the max. When I call upon the following code....

int ele_speed = map(ele_pulse, ele_min, ele_max, -255, 255);  //maps max and mins of the pulse
  int ail_speed = map(ail_pulse, ail_min, ail_max, -255, 255);  // -255 to 255 for analogWrite()

.... it is possible that I am getting a value greater than 1985 (ele_max) and that is why it happens randomly. I remember reading pulseIn is measured empirically which may explain why the value jumps.

so essentially, what I think is happening is this..(sudo code)
ele_pulse = pulseIn(ele,high,25000);
int ele_speed = map(ele_pulse, 982, 1985, -255, 255); //982 and 1985 are the extremes of the values I measured
ele_speed freaks out if ele_pulse is greater than 1985 or less than 982. Although they are what I measured, I noticed every time I run the sketch in the serial monitor, it seems to change +-50

I will write a function that automatically adjust the max/min values and see if that helps.
I think the code would look something like...

if(max_pulse < current_pulse){
max_pulse = current_pulse;
}

and for the minimum side...

if(min_pulse > current_pulse){
min_pulse = current pulse;
}

Alright, I rewrote the code from the ground up. Compared to my old code, this is 416 bytes smaller and works MUCH better. I allowed for movement thresholds, trims for the pulse and avoided the use of the map() function by using subtraction and multiplication. Since I figure a lot of beginners (like me!) are around here, I over commented the code so it is crystal clear. It is my pet peeve when people comment everything but the black voodoo blocks. I also plan on adding max/min calibration for the pulses soon.

/*
  Arduino RC robot v1.1
  Uses ardumoto shield and a standard rc receiver for control
  
*/


int speed_right = 3;   // PWM control for motor outputs 1 and 2 is on digital pin 3
int speed_left = 11;   // PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_right = 12;    // direction control for motor outputs 1 and 2 is on digital pin 12
int dir_left = 13;     // direction control for motor outputs 3 and 4 is on digital pin 13

int ele = 5;           // RC rx elevator ch connected 
int ail = 6;           // RC rx aileron ch connected

int ele_max = 1985;    // max of elevator channel
int ele_min = 982;     // min of elevator channel

int ail_max = 1985;    // max of aileron channel
int ail_min = 982;     // min of aileron channel

int ele_trim = 0;      // pulseIn() varies a little, use this to center it
int ail_trim = 0;

int end_point = 10;    // sets the threshold for motors/direction to move

int pulse_cent = 1488; // center of both rc channels

// int wait = 1000;    // delay interval in milliseconds for debug area

// unsigned long prevtime = 0; // placeholder for the last time it was updated with millis() for debug area
 
void setup()
{
  pinMode(speed_left, OUTPUT);   // set control pins to be outputs
  pinMode(speed_right, OUTPUT); 
  pinMode(dir_right, OUTPUT);
  pinMode(dir_left, OUTPUT);
  
  pinMode(ele, INPUT);          // set control pins to be inputs
  pinMode(ail, INPUT);
  
  analogWrite(speed_left, 0);   // set both motors to run at 0 speed so robot does not move
  analogWrite(speed_right, 0);
 
 // Serial.begin(9600);         // for debug
  
}


void loop()
{
  
 long ele_pulse = pulseIn(ele, HIGH, 25000);   // Reads the pulses channel of RC RX
 long ail_pulse = pulseIn(ail, HIGH, 25000);   
  
  ele_pulse = ele_pulse - pulse_cent + ele_trim;     // centers the pulse from ~982, 1488, 1985 to roughly -500, 0, 500
  ail_pulse = ail_pulse - pulse_cent + ail_trim;
  
  
  
  float ele_speed = ele_pulse * 0.5169;  // analogWrite max is 255, divide 255 by pulse max  to rescale it to -255, 0 , 255
  float ail_speed = ail_pulse * 0.5169;  //   255/500 = 0.5169, use that as a scaling factor. 
  //float x_speed = 255/x_pulse returns weird values, must use multiplcation (??) 
  
  float speedL = ele_speed - ail_speed; // mixes elevator and aileron channels. Aileron has + and - values at the same time for differential control
  float speedR = ele_speed + ail_speed;
  
  speedL = constrain(speedL, -254, 254); // keeps speedL/R from exceeding +-254
  speedR = constrain(speedR, -254, 254);
  
  
  
  if(speedL<=-end_point){         // sets up the direction depending on magnitude of speedL
    digitalWrite(dir_left, LOW);  // if speedL is greater than end_point, direction is reverse
  }
  if(speedL>=end_point){
    digitalWrite(dir_left, HIGH);  // if speedL is lower than negative end_point, direction is reverse
  }
  if(speedL<end_point && speedL>-end_point){  // if speedL is inbetween 10 and -10...
     speedL = 0;                              // ...sets speedL to zero, this keeps motors from stalling when controller is centered
  }
 
 
  if(speedR<=-end_point){          // sets up the direction depending on magnitude of speedR
    digitalWrite(dir_right, LOW);  // if speedR is greater than end_point, direction is reverse
  }
  if(speedR>=end_point){
    digitalWrite(dir_right, HIGH); // if speedR is lower than negative end_point, direction is reverse
  }
  if(speedR<end_point && speedR>-end_point){  // if speedR is inbetween 10 and -10...
    speedR = 0;                               // ...sets speedR to zero, this keeps motors from stalling when controller is centered
  }
 
  analogWrite(speed_left, abs(speedL));  // actual speed is the absolute value of speedL/R
  analogWrite(speed_right, abs(speedR)); // abs() removes negative sign
  
  
  // DEBUG AREA 
 /*
  unsigned long time = millis();  //sets up the time 
  
  if(time - prevtime > wait){
    Serial.print(" int x = "); Serial.print(x); Serial.print(" int y = "); Serial.println(y);
    Serial.println("");
    Serial.print("ele_pulse = ");Serial.print( ele_pulse); Serial.print(" ail_pulse = "); Serial.println( ail_pulse);
    Serial.println("");
    Serial.print("ele_speed = ");Serial.print( ele_speed); Serial.print(" ail_speed = "); Serial.println( ail_speed);
    Serial.println("");
    Serial.print("speedL = ");Serial.print( speedL); Serial.print(" speedR = "); Serial.println( speedR);
    Serial.println("------------------------------------");
    
  prevtime = time;
  } 
 */
}

I am also working on a simple fuzzy controller, which is using distances as its input and revoultion of step motor as its output.
but unfortunately every time when i am watching my input and output on my serial monitor it is just printing revolution time =0 even when I am providing certain positive inputs.
kindly someone help me.
I am attaching my code.

// eFFL includes
#include <Fuzzy.h>
#include <FuzzyComposition.h>
#include <FuzzyInput.h>
#include <FuzzyIO.h>
#include <FuzzyOutput.h>
#include <FuzzyRule.h>
#include <FuzzyRuleAntecedent.h>
#include <FuzzyRuleConsequent.h>
#include <FuzzySet.h>

// pins

#define TRIGGER 9
#define ECHO 10
int initialdepth() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;

return(pulse * 10 / 292);
}
const int stepPin = 5;
const int dirPin = 2;
byte b;
long i=0;
long temp=0;
// object library
Fuzzy *fuzzy = new Fuzzy();

void setup() {
// set console and pins
Serial.begin(9600);
pinMode(stepPin,OUTPUT);
pinMode(dirPin,OUTPUT);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
temp= initialdepth();
Serial.print("Enter the Depth at which You want to go=:)");
Serial.setTimeout(10);
while(Serial.available()==0)
{}
i= Serial.parseInt();
Serial.print("Distance: "); Serial.println(i);
Serial.print("Initial Depth is: "); Serial.println(temp);

// fuzzy sets
// error1
FuzzySet *NL = new FuzzySet(-10 ,-10, -10, -7);
FuzzySet *NM = new FuzzySet(-10, -7, -7, 3.5);
FuzzySet *NS = new FuzzySet(-7, -3.5, -3.5, 3);
FuzzySet *DZ = new FuzzySet(-3.5, 0, 0, 3.5);
FuzzySet *PS = new FuzzySet(3, 3.5, 3.5, 7);
FuzzySet *PM = new FuzzySet(3.5, 7, 7, 10);
FuzzySet *PL = new FuzzySet(7, 10.0, 10.0, 10.0);

// error2
FuzzySet *NVL2 = new FuzzySet(-12, -12, -12, -1);
FuzzySet *NL2 = new FuzzySet(-12,-10, -10,-6);
FuzzySet *NM2 = new FuzzySet(-10 ,-6,-6,-3);
FuzzySet *NS2 = new FuzzySet(-6, -3, -3, 0);
FuzzySet *DZ2 = new FuzzySet(-3, 0, 0, 3);
FuzzySet *PS2 = new FuzzySet(0 ,3, 3, 6);
FuzzySet *PM2 = new FuzzySet(3, 6, 6, 10);
FuzzySet *PL2 = new FuzzySet(6 ,10, 10, 12);
FuzzySet *PVL2 = new FuzzySet(10, 12, 12, 12);

// stepmotor
FuzzySet *NHigh = new FuzzySet(-1200, -1200, -1200, -1000);
FuzzySet *NMid = new FuzzySet(-1200, -1000, -1000, -300);
FuzzySet *NLow = new FuzzySet(-1000, -300, -300, 100);
FuzzySet *Neutral = new FuzzySet(-300, 100, 100, 300);
FuzzySet *PLow = new FuzzySet(100, 300, 300, 1000);
FuzzySet *PMid = new FuzzySet(300, 1000, 1000, 1200);
FuzzySet *PHigh = new FuzzySet(1000, 1200, 1200, 1200);

// variables
// variable error1 with universe 0-60 as input
FuzzyInput *error1 = new FuzzyInput(1);
error1->addFuzzySet(NL);
error1->addFuzzySet(NM);
error1->addFuzzySet(NS);
error1->addFuzzySet(DZ);
error1->addFuzzySet(PS);
error1->addFuzzySet(PM);
error1->addFuzzySet(PL);
fuzzy->addFuzzyInput(error1);

// variable error2 with universe 0-600 as input
FuzzyInput *error2 = new FuzzyInput(2);
error2->addFuzzySet(NVL2);
error2->addFuzzySet(NL2);
error2->addFuzzySet(NM2);
error2->addFuzzySet(NS2);
error2->addFuzzySet(DZ2);
error2->addFuzzySet(PS2);
error2->addFuzzySet(PM2);
error2->addFuzzySet(PL2);
error2->addFuzzySet(PVL2);
fuzzy->addFuzzyInput(error2);

// variable MOTOR with universe 0-255 as output
FuzzyOutput *MOTOR = new FuzzyOutput(1);
MOTOR->addFuzzySet(NHigh);
MOTOR->addFuzzySet(NMid);
MOTOR->addFuzzySet(NLow);
MOTOR->addFuzzySet(Neutral);
MOTOR->addFuzzySet(PHigh);
MOTOR->addFuzzySet(PMid);
MOTOR->addFuzzySet(PLow);

fuzzy->addFuzzyOutput(MOTOR);

// rules
// if error1 is NL and error2 is NVL2 then MOTOR is Nhigh
FuzzyRuleAntecedent *iferror1NLAnderror2IsNVL2 = new FuzzyRuleAntecedent();
iferror1NLAnderror2IsNVL2->joinWithAND(NL, NVL2);
FuzzyRuleConsequent *thenMOTORNHigh = new FuzzyRuleConsequent();
thenMOTORNHigh->addOutput(NHigh);
FuzzyRule *fuzzyRule1 = new FuzzyRule(1, iferror1NLAnderror2IsNVL2, thenMOTORNHigh);
fuzzy->addFuzzyRule(fuzzyRule1);

// if error1 is PL and error2 is PVL2 then MOTOR is PHigh
FuzzyRuleAntecedent *iferror1PLAnderror2IsPVL2 = new FuzzyRuleAntecedent();
iferror1PLAnderror2IsPVL2->joinWithAND(PL, PVL2);
FuzzyRuleConsequent *thenMOTORPHigh = new FuzzyRuleConsequent();
thenMOTORPHigh->addOutput(PHigh);
FuzzyRule *fuzzyRule2 = new FuzzyRule(2, iferror1PLAnderror2IsPVL2, thenMOTORPHigh);
fuzzy->addFuzzyRule(fuzzyRule2);

// if error1 is PL and error2 is PVL2 then MOTOR is PHigh
FuzzyRuleAntecedent *iferror1PSAnderror2IsPM2 = new FuzzyRuleAntecedent();
iferror1PSAnderror2IsPM2->joinWithAND(PS, PM2);
FuzzyRuleConsequent *thenMOTORPMid = new FuzzyRuleConsequent();
thenMOTORPHigh->addOutput(PHigh);
FuzzyRule fuzzyRule3 = new FuzzyRule(3, iferror1PSAnderror2IsPM2, thenMOTORPMid);
fuzzy->addFuzzyRule(fuzzyRule3);
/
// if error1 is mid then MOTOR is midb
FuzzyRuleAntecedent *iferror1Mid = new FuzzyRuleAntecedent();
iferror1Mid->joinSingle(mid);
FuzzyRuleConsequent *thenMOTORMidb = new FuzzyRuleConsequent();
thenMOTORMidb->addOutput(midb);
FuzzyRule *fuzzyRule3 = new FuzzyRule(3, iferror1Mid, thenMOTORMidb);
fuzzy->addFuzzyRule(fuzzyRule3);

// if error1 is big then MOTOR is low
FuzzyRuleAntecedent *iferror1Big = new FuzzyRuleAntecedent();
iferror1Big->joinSingle(big);
FuzzyRuleConsequent thenMOTORLow = new FuzzyRuleConsequent();
thenMOTORLow->addOutput(lowb);
FuzzyRule
fuzzyRule4 = new FuzzyRule(4, iferror1Big, thenMOTORLow);

fuzzy->addFuzzyRule(fuzzyRule4);
// if error1 is verybig then MOTOR is off
FuzzyRuleAntecedent iferror1VeryBig = new FuzzyRuleAntecedent();
iferror1VeryBig->joinSingle(verybig);
FuzzyRule
fuzzyRule5 = new FuzzyRule(5, iferror1VeryBig, thenMOTOROff);
fuzzy->addFuzzyRule(fuzzyRule5);
*/
}
// returns the error1 means target depth-actual distance
int error1() {
digitalWrite(TRIGGER, LOW);
delayMicroseconds(5);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
long pulse = pulseIn(ECHO, HIGH) / 2;
temp=(pulse * 10 / 292)- temp;
return( i-(pulse * 10 / 292));
}

// returns the error2
int error2() {
// return analogRead(error2);
return(temp);
}

// prints in serial monitor
void print(int err1, int err2, int output) {
Serial.print("error1: ");
Serial.print(err1);
Serial.print(" error2: ");
Serial.print(err2);
Serial.print(" => output revolution: ");
Serial.print(output);
Serial.println();

}

// main method
void loop() {
// get error1 and error2
int err2 = error2();
int err1 = error1();

// if the inputs are weird, ignore them
// if (dist < 0 || dist > 80 || light > 600) return;

// fuzzyfication
fuzzy->setInput(1, err1); // erro1 as fuzzy input 1 (error1)
fuzzy->setInput(2, err2); // error2 as fuzzy input 2 (error2)
fuzzy->fuzzify();

// defuzzyfication
int output = fuzzy->defuzzify(1); // defuzzify fuzzy output 1 (MOTOR)
if (output<=0)
{
digitalWrite(dirPin,HIGH);
digitalWrite(stepPin, HIGH);
delay(-100output);
digitalWrite(stepPin,LOW);
}
if (output>0)
{
digitalWrite(dirPin,LOW);
analogWrite(stepPin, HIGH);
delay(100
output);
digitalWrite(stepPin,LOW);
}
print(err1,err2,output);

}