// 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;
}