CCCPaste

Fuzzy Logic

// Define fuzzy sets for error and change in error
#define LOW_ERROR 0
#define MEDIUM_ERROR 1
#define HIGH_ERROR 2

#define NEGATIVE 0
#define ZERO 1
#define POSITIVE 2

// Motor control pins
const int motorPin1 = 18;
const int motorPin2 = 19;

// Encoder input pins
const int encoderPin1 = 34;
const int encoderPin2 = 35;

// Variables for encoder and control
volatile int encoderPos = 0;
int encoderPosLast = 0;
double speedSetpoint = 200;
double speedMeasured = 0;

void setup() {
  pinMode(motorPin1, OUTPUT);
  pinMode(motorPin2, OUTPUT);
  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);

  attachInterrupt(digitalPinToInterrupt(encoderPin1), readEncoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderPin2), readEncoder, CHANGE);

  Serial.begin(115200);
}

void loop() {
  speedMeasured = readRPM();
  int error = speedSetpoint - speedMeasured;
  int dError = error - (speedSetpoint - encoderPosLast);
  int output = fuzzyLogicControl(error, dError);

  // Control motor speed
  analogWrite(motorPin1, output);
  analogWrite(motorPin2, 0);

  Serial.print("RPM: ");
  Serial.println(speedMeasured);
  delay(100);
}

void readEncoder() {
  int state1 = digitalRead(encoderPin1);
  int state2 = digitalRead(encoderPin2);
  encoderPos += (state1 == state2) ? 1 : -1;
}

double readRPM() {
  int deltaPos = encoderPos - encoderPosLast;
  encoderPosLast = encoderPos;
  return (deltaPos / 20.0) * 60.0;  // Convert to RPM
}

int fuzzyLogicControl(int error, int dError) {
  int output = 0;

  // Fuzzy rules implementation
  if (error == LOW_ERROR && dError == ZERO) {
    output = 150; // Moderate speed
  } else if (error == HIGH_ERROR && dError == POSITIVE) {
    output = 255; // Full speed
  } else if (error == LOW_ERROR && dError == NEGATIVE) {
    output = 100; // Low speed
  }
  // Add more rules as necessary

  return output;
}