Skip to content

Instantly share code, notes, and snippets.

@SammyOina
Last active February 24, 2022 13:31
Show Gist options
  • Save SammyOina/c085212321bdcb9ab7e07fad4e9953a2 to your computer and use it in GitHub Desktop.
Save SammyOina/c085212321bdcb9ab7e07fad4e9953a2 to your computer and use it in GitHub Desktop.
simple pid controlled fan with encoder
/* 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--;
}
}
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