The code in the bottom is part of Configuration.h in Marlin firmware source code.
When PID auto tuning fails to produce consistent temperature control, the wiki page suggest you manually change three variables, P, I, and D.
For manual adjustments:
if it overshoots a lot and oscillates, either the integral gain needs to be increased or all gains should be reduced
Too much overshoot? Increase D, decrease P.
Response too damped? Increase P.
Ramps up quickly to a value below target temperature (0-160 fast) and then slows down as it approaches target (160-170 slow, 170-180 really slow, etc) temperature? Try increasing the I constant.
What if the manual adjustment wouldn’t produce satisfactory PID values? Fluctuation over five degrees around target temperature, i.e. 200 Celsius degrees, printing a quality object is impossible. The object will have noticeable layers. Controlling temperature between one to two degrees is essential for quality 3D printing.
I spent hours to PID tuning after replacement of the thermistor on E3D V6 Hotend without success. It prints objects but the quality is below my expectation. While in printing temperature was changing 195 C to 210.
Out of frustration, I looked into Marline source code, changed the values of few variables in the below, made good PID tuning.
Play with PID_MAX, PID_INTEGRAL_DRIVE_MAX values. These two values affects the current heater uses during temperature adjustment. Default settings are both 255, which means the controller uses maximum amount of current.
Excessive current overshoots temperature and it creates fluctuation at target temperature. For instance, let’s set the target temperature at 200 C. The controller supplies current that heats up the heater block always 10 degrees over.
At 190 C, it will be 200 C and cuts current to maintain it. Then the temperature drops. The controller puts current at 197 C, then the heater block will goes up to 207 C. This is already too much and the controller cuts off current until it detects 200 C. Getting back to full power, 200 C becomes 210 C+.
190 -> 200 -> 197 -> 207 -> 200 -> 210
We need to remove excessive current that the controller believes in it’s good value. How to do it?
255 is default value, which is the maximum current. To make it 90% of the maximum value, do 255 * 0.9. And convert into integer is 230 or 229 (229.50)
I obtained 218, which is about 85% of maximum current.
I got PID_INTEGRAL_DRIVE_MAX 230 by multiplying 0.9 to 255, 90% of the value.
Reduced current indeed produced ideal PID values that I used to have, plus or minus one or two degrees of variation at target temperature.
// PID settings:
// Comment the following line to disable PID and enable bang-bang.
#define BANG_MAX 255 // limits current to nozzle while in bang-bang mode; 255=full current
// __test__ soft pwm uses PID_MAX/2. Half of power that PSU generates.
// My ATX PSU has 20A in 12V+ rail. Maxium Power output is 240W.
#define PID_MAX 218 // (255) limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
#define PID_DEBUG // Sends debug data to the serial port.
// #define PID_OPENLOOP 1 // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
#define PID_FUNCTIONAL_RANGE 10 // (10) If the temperature difference between the target temperature and the actual temperature
// is more then PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
#define PID_INTEGRAL_DRIVE_MAX 230 // (255) limit for the integral term
#define K1 0.95 //smoothing factor within the PID
#define PID_dT ((16.0 * 8.0)/(F_CPU / 64.0 / 256.0)) //sampling period of the temperature routine