good morning, I want to ask, so I made a pid program to control the output voltage to be constant (automatic control pwm) and this condition works even though the input voltage changes (variable), but when the voltage is below the setpoint, the pid is still counting until the duty is at max, so when there is a voltage above the setpoint the voltage jumps high because the duty is at 100 percent, so I give the if else function (if below 15v the pwm is 0, if for example above 15v use pid) but why is this condition pwm 0 continues, right? or is it wrong in the program? thank you
Program =
#include<PWM.h>
#include <PID_v1.h>
int pwm = 9;
double Setpoint;
double Input;
double Output ;
double Kp = 0.02, Ki = 20, Kd = 0.00016;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
void setup()
{
Serial.begin (9600);
pinMode (analogRead(A0), INPUT);
pinMode (pwm, OUTPUT);
TCCR1B = TCCR1B & B11111000 | B00000001; //frek
myPID.SetMode(AUTOMATIC);
myPID.SetTunings(Kp, Ki, Kd);
myPID.SetSampleTime(0.1);
}
void loop()
{
//read Vsensor Output
float Vout_sensor =(analogRead (A0)* (5.0 / 1024.0));
float Vout = (Vout_sensor/(1000.0/(10000.0+1000.0))); // Real value
//maping ADC sensor 1023 - 0 255
int val = analogRead(A0);
val = map (val, 0,1023, 0, 255);
Input = val;
Setpoint = 64; // set point 13.8 volt
// if else
if (val <=69)
{
analogWrite(pwm,0);
}
else
{
myPID.Compute();
analogWrite(pwm, Output);
}
}
Your topic has been moved to a more suitable location on the forum. Installation and Troubleshooting is not for problems with (nor for advice on) your project See About the Installation & Troubleshooting category.
You could try (val>=69)...
But this is not the way to do it.
It seems you have integral windup.
How did you chosec kp, ki and kd?
Try with kd=0.
If that solves your problem, and you suffer from an offset, you could look for a kd value lower than your current value that gives a stable response.
Your PID may also have an Imax that can be set...
What is the unit of time? Is it in seconds for sample time, s for Ki and /s for Kd?
How fast is your response time?
Did you write the PID library? Or is it a well tested library?
i did with matlab with nichols method and trial and error, the pid is actually running normally (the output voltage can be constant even though the input varies) the problem is because i use a buck converter, when the input voltage is 0V or below the setpoint, the pid continues to work so the duty cycle is in a state maximum (100%) and when the input voltage is more than the set point a voltage spike occurs, therefore I tried to use the if else function on the arduino, if input < set point, pid off, but how do I write the program?
If you shut off your controller before the setpoint is reached, how can you ever expect the setpoint to be reached?
My guess is that you would need to catch the case where the input is incorrect (close to 0V) and then set pwm to 0. But that will lead to integral windup in your controller. So you would need to reset the controller as well.
It might be better to write your own PID algorithm. What is likely to be happening is the integral term is saturating .
If you write your own you could reset the integral term to zero .
Failing that a cheat might be to make the set point follow the measured value when it goes negative .( if ….)
Note by using your “map “ you have reduced the precision of control ( 1 part in 255 instead of 1024) , leave as 0-0124 , don’t map and adjust the set point value instead .
Why is your pid result 100% if your measured value is below your setpoint?
Is your gain too high? Or is the 100% gradually reached(integral windup). Or both?
What system response did you use in your model?
What is the real system response?
Are they comparable???