Last active
February 24, 2022 13:31
-
-
Save SammyOina/c085212321bdcb9ab7e07fad4e9953a2 to your computer and use it in GitHub Desktop.
simple pid controlled fan with encoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Sammy Oina Kerata | |
* ENM221-0089/2017 | |
* fan speed control with temprature with encoder | |
*/ | |
float revCounts=0; //revolutions counted | |
float motorSpeed=0; //current motor speed | |
unsigned long prevTime = 0; //previous time used to calculate | |
float speedFreq=0; //motor speed in HZ | |
float kp = 3.4; //proportional gain of the motor control | |
float kd = 34; //derivative gain | |
float previousError = 0; //previous error of motor speed | |
int targetSpeed = 0; //target motor speed | |
void setup () { | |
pinMode(A0,INPUT); | |
pinMode(6,OUTPUT); | |
attachInterrupt(1,stepsCounter, RISING); //count pulses using interrupts from the motor | |
digitalWrite(6,HIGH); //start motor on high speed | |
Serial.begin(115200); | |
delay(3000); //allow motor to get high speed | |
revCounts = 0; | |
prevTime = millis(); | |
} | |
void loop() { | |
float temp = ((analogRead(A0)/1024.0)*5000)/10; //get temperature from lm35 | |
Serial.print("Temp: "); | |
Serial.print(temp); | |
Serial.print(" "); | |
if (temp >= 26){ //vary target motor speed with select temperature | |
targetSpeed = 150; | |
}else if (temp >= 23){ | |
targetSpeed = 120; | |
}else if (temp >= 20){ | |
targetSpeed = 90; | |
}else{ | |
targetSpeed = 0; | |
} | |
if (targetSpeed != 0){ | |
targetSpeed += 44; | |
} | |
float error = targetSpeed - motorSpeed; //get error on speed | |
float proportionalVal = error * kp; //get PID values | |
float derivativeVal = (error - previousError) * kd; | |
previousError = error; | |
float KD = proportionalVal + derivativeVal; | |
float motorVal = constrain(KD, 0, 255); //write motor speed | |
analogWrite(6, motorVal); | |
if (revCounts >= 24){ //calculate motor speed | |
unsigned long currentTime= millis(); | |
int timeDiff = currentTime - prevTime; | |
speedFreq = (revCounts *1000) / (24 * (timeDiff)); | |
prevTime = currentTime; | |
revCounts = 0; | |
motorSpeed = speedFreq * 60; | |
} | |
Serial.print("Motor Speed: "); | |
Serial.println(motorSpeed); | |
//delay(500); | |
} | |
void stepsCounter(){ //count motor steps | |
int x = digitalRead(5); | |
if (x == 1){ | |
revCounts++; | |
}else{ | |
revCounts--; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
float revCounts=0; //revolutions counted | |
float motorSpeed=0; //current motor speed | |
unsigned long prevTime = 0; //previous time used to calculate | |
float speedFreq=0; //motor speed in HZ | |
void setup() { | |
// put your setup code here, to run once: | |
attachInterrupt(1,stepsCounter, RISING); //count pulses using interrupts from the motor | |
Serial.begin(115200); | |
revCounts = 0; | |
prevTime = millis(); | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
if (revCounts >= 24){ //calculate motor speed | |
unsigned long currentTime= millis(); | |
int timeDiff = currentTime - prevTime; | |
speedFreq = (revCounts *1000) / (24 * (timeDiff)); | |
prevTime = currentTime; | |
revCounts = 0; | |
motorSpeed = speedFreq * 60; | |
} | |
Serial.print("Motor Speed: "); | |
Serial.println(motorSpeed); | |
} | |
void stepsCounter(){ //count motor steps | |
revCounts++; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment