Possible bug in PID routine


I tried to fight the vast overshoot PID autotune is giving me by using lower Kp & Ki values and also larger Kd values. But still, I was not able to get rid of a temperature overshoot whatsoever, so I checked the code. In your PID routine (extruder.cpp line 263 and later) the code is: 

if(act->heatManager == HTR_PID)
                float pidTerm = act->pidPGain * error;
                act->tempIState = constrain(act->tempIState + error, act->tempIStateLimitMin, act->tempIStateLimitMax);
                pidTerm += act->pidIGain * act->tempIState * 0.1; // 0.1 = 10Hz
                float dgain = act->pidDGain * (act->tempArray[act->tempPointer] - act->currentTemperatureC) * 3.333f;
                pidTerm += dgain;

So for adding the pidIGain you use a time constant of 0.1 seconds (10 Hz) and one line later you use a time constant of 3.333 Hz (0.3 seconds) for adding the pidDGain. Is this intended? In the deadtime control, the time constant is 3.333 Hz, too. So is the time constant of PIDIgain off and should be set to 0.3?

TY & BR!


  • The function is called every 100ms if possible. So 0.1 is correct.
    The D term uses temperature change per second. As you see it computes a difference between 2 temperatures. One is inside an array of length 4 an dit points to the value 0.3s before. So multiplying with 3.333 gives change per second. Reason to use 0.3s distance is to get a more stable result then change between last measurement. Measurement errors get here a much to big impact.

    Regarding overshoot, calibration is supposed to have that. See Extruder.cpp where values get computated:

                            Kp = 0.6*Ku;
                            Ki = 2*Kp/Tu;
                            Kd = Kp*Tu*0.125;
                            Kp = 0.33*Ku;
                            Ki = Kp/Tu;
                            Kd = Kp*Tu/3;
                            OUT_P_LN(" Some overshoot");
                            OUT_P_F_LN(" Kp: ",Kp);
                            OUT_P_F_LN(" Ki: ",Ki);
                            OUT_P_F_LN(" Kd: ",Kd);
                            Kp = 0.2*Ku;
                            Ki = 2*Kp/Tu;
                            Kd = Kp*Tu/3;
                            OUT_P_LN(" No overshoot");
                            OUT_P_F_LN(" Kp: ",Kp);
                            OUT_P_F_LN(" Ki: ",Ki);
                            OUT_P_F_LN(" Kd: ",Kd);

    You see the last set of equations would set it more conservative to have no overshoot.
  • I see, ty very much for the thorough explanation!
Sign In or Register to comment.