суббота, 7 июня 2014 г.

Extruder temperature + Teacup firmware

I spent quite a lot of time struggling with the extruder temperature on my repral-like 3D printer. I played and studied PID a lot, but the temperature still oscillated within horrible +5/-15C. The most unpleasant was that previously I dealt with normal (not Arduino-based) PID-controllers and this was remarkably simple. A famous title "PID wihout a PhD" made my situation even worse...


I spent some time studying source codes and my schematics.
First, I made a mistake placing my temperature sensor close to the extruder power control - the sensor and the power cable shared the same ground wire, so when extruder was powered, it affected reading from my sensor. This problem was solved, but the temperature was still unstable.

Second, usual PID controllers do not use any I_limit factors. All right, I set it to the maximum ~32000 (a value higher than 32768 will lead to overflow). Still, it did not work.
 
Third, I studied heater.c source code - to my surprise, I found out that temperature sampling as well as PID control timing is 10 ms (100 Hz)! What is the use of so huge speed in controlling?

Scheme of my extruder is simple - the most important aspect is that the temperature sensor is very close to the extruder body - not surprisingly, I do want to measure its temperature. This leads to the obvious consequence that temperature changes very-very slowly. When heating stops, it takes about 30 seconds to start cooling down.
  Displaying Photo note
So what is wrong with the 100Hz? It is simply 3 orders of magnitude faster than the physical process! One solution is to place the temperature sensor after the heating elements, so it will "feel" heating rather than actual temperature of the extruder body. This is not so bad solution, as when heating power is constant, extruder temperature will be constant as well. But physically, I want to measure temperature of the extruder, so I did not want to change it.
In this case, my temperature change frequency is an order of 0.1 Hz, so using 100Hz PID controlling overflowed I_limit within about 16 seconds, rendering Integral component virtually useless.

The solution is simple. Open clock.c file and move temp_tick(); from clock_10ms to clock_250ms routine. Now PID is applied every 250ms! Unfortunately, temperature is read also every 250ms - higher sampling rate may be beneficial for averaging and noise elimination, but considering response time of 30 sec, I have about 120 points to safely average the temperature. Even with 4Hz frequency, I had to use very high I_limit to smooth my slow heater.
At P=4, I=0.01, D=3, I_limit=24000, my temperature got stable within +/-0.25C and PWM value of 216 +/-2.

(Buy the way, 250ms sampling greatly improves Debug feature of the Teacup - uncomment Debug in config.c, type "M111 S1" in the G-code parser and you can easily tune your PID without flooding your RS connection with excessive data).

Similarly, slow sampling rate improves relay-controlled heat-bed. It cannot flicker like a mad with 250mssampling - the highest frequency is 4Hz (better than 100 Hz). To minimize this problem further, I used the following PID settings: P=10, I=0.2, D=0, I_limit=10. The latter I_limit means that even when my temperature goes 1C below the target (4 unit in teacup scale), it will take 2.5 seconds to turn on the relay back - no flickering is possible at all.

Комментариев нет:

Отправить комментарий