i know the working of PID and its coding but the problem is i dont understand how the calculated PID value will change the PWM of the motor accordingly to reach the required RPM.
volatile int rpmcount = 0;
float rpm = 0;
unsigned long lastmillis = 0;
int pwm = 5;
int dir1 = 11;
int dir2 = 12;
float rotation = 0.00;
float kp=2.5;
float kd=2.0;
float setp = 200.00;
float error =0 ;
float last = 0;
float derr = 0;
float pid = 0;
float mult=8;
void setup(){
//setp = setp*(255.00/262.22);
Serial.begin(9600);
attachInterrupt(0, rpm_fan, RISING);//interrupt cero (0) is on pin two(2)
pinMode(pwm,OUTPUT);
pinMode(dir1,OUTPUT);
pinMode(dir2,OUTPUT);
}
void loop(){
digitalWrite(dir1,HIGH);
digitalWrite(dir2,LOW);
if(c==0)
{
analogWrite(pwm_initalval,);
}
if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
detachInterrupt(0); //Disable interrupt when calculating
rpm = (rpmcount * 60.0)/135.0 ; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/
//Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.println(rpm); // print the rpm value.
//Serial.print("\t Hz=\t"); //print the word "Hz".
//Serial.println(pid/*rpmcount*/); /*print revolutions per second or Hz. And print new line or enter.*/
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
error = (setp - rpm);
derr = last - error;
pid = mul*((kp*error)+(kd*derr)) ;
last = error;
if (pid <255 && pid >0){
analogWrite(pwm,(int)pid); //set motor speed
}
else{
if (pid>255){
//pid = 255;
analogWrite(pwm,255);
}
if(pid<0){
//pid = 0;
analogWrite(pwm,0);
}
attachInterrupt(0, rpm_fan, RISING); //enable interrupt
}
}
}
void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
}
i have written the complete code above, but i am not able to achieve the required RPM correctly. what's wrong in this? is there somehting missing which i am not getting?