|
@@ -217,7 +217,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
|
217
|
217
|
|
218
|
218
|
#if HAS_PID_HEATING
|
219
|
219
|
|
220
|
|
- void Temperature::PID_autotune(float temp, int hotend, int ncycles, bool set_result/*=false*/) {
|
|
220
|
+ void Temperature::PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result/*=false*/) {
|
221
|
221
|
float input = 0.0;
|
222
|
222
|
int cycles = 0;
|
223
|
223
|
bool heating = true;
|
|
@@ -226,27 +226,59 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
|
226
|
226
|
long t_high = 0, t_low = 0;
|
227
|
227
|
|
228
|
228
|
long bias, d;
|
229
|
|
- float Ku, Tu;
|
230
|
|
- float workKp = 0, workKi = 0, workKd = 0;
|
231
|
|
- float max = 0, min = 10000;
|
|
229
|
+ float Ku, Tu,
|
|
230
|
+ workKp = 0, workKi = 0, workKd = 0,
|
|
231
|
+ max = 0, min = 10000;
|
|
232
|
+
|
|
233
|
+ #if WATCH_THE_BED || WATCH_HOTENDS
|
|
234
|
+ const float watch_temp_target = temp -
|
|
235
|
+ #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
|
|
236
|
+ (hotend < 0 ? (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1) : (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))
|
|
237
|
+ #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
|
|
238
|
+ (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)
|
|
239
|
+ #else
|
|
240
|
+ (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)
|
|
241
|
+ #endif
|
|
242
|
+ ;
|
|
243
|
+ const int8_t watch_temp_period =
|
|
244
|
+ #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
|
|
245
|
+ hotend < 0 ? temp - THERMAL_PROTECTION_BED_PERIOD : THERMAL_PROTECTION_PERIOD
|
|
246
|
+ #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
|
|
247
|
+ THERMAL_PROTECTION_BED_PERIOD
|
|
248
|
+ #else
|
|
249
|
+ THERMAL_PROTECTION_PERIOD
|
|
250
|
+ #endif
|
|
251
|
+ ;
|
|
252
|
+ const int8_t hysteresis =
|
|
253
|
+ #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
|
|
254
|
+ hotend < 0 ? TEMP_BED_HYSTERESIS : TEMP_HYSTERESIS
|
|
255
|
+ #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
|
|
256
|
+ TEMP_BED_HYSTERESIS
|
|
257
|
+ #else
|
|
258
|
+ TEMP_HYSTERESIS
|
|
259
|
+ #endif
|
|
260
|
+ ;
|
|
261
|
+ millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL;
|
|
262
|
+ float next_watch_temp = 0.0;
|
|
263
|
+ bool heated = false;
|
|
264
|
+ #endif
|
232
|
265
|
|
233
|
266
|
#if HAS_AUTO_FAN
|
234
|
267
|
next_auto_fan_check_ms = next_temp_ms + 2500UL;
|
235
|
268
|
#endif
|
236
|
269
|
|
237
|
|
- if (hotend >=
|
238
|
|
- #if ENABLED(PIDTEMP)
|
239
|
|
- HOTENDS
|
240
|
|
- #else
|
241
|
|
- 0
|
242
|
|
- #endif
|
243
|
|
- || hotend <
|
244
|
|
- #if ENABLED(PIDTEMPBED)
|
245
|
|
- -1
|
246
|
|
- #else
|
247
|
|
- 0
|
248
|
|
- #endif
|
249
|
|
- ) {
|
|
270
|
+ #if ENABLED(PIDTEMP)
|
|
271
|
+ #define _TOP_HOTEND HOTENDS - 1
|
|
272
|
+ #else
|
|
273
|
+ #define _TOP_HOTEND -1
|
|
274
|
+ #endif
|
|
275
|
+ #if ENABLED(PIDTEMPBED)
|
|
276
|
+ #define _BOT_HOTEND -1
|
|
277
|
+ #else
|
|
278
|
+ #define _BOT_HOTEND 0
|
|
279
|
+ #endif
|
|
280
|
+
|
|
281
|
+ if (!WITHIN(hotend, _BOT_HOTEND, _TOP_HOTEND)) {
|
250
|
282
|
SERIAL_ECHOLN(MSG_PID_BAD_EXTRUDER_NUM);
|
251
|
283
|
return;
|
252
|
284
|
}
|
|
@@ -332,7 +364,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
|
332
|
364
|
;
|
333
|
365
|
bias += (d * (t_high - t_low)) / (t_low + t_high);
|
334
|
366
|
bias = constrain(bias, 20, max_pow - 20);
|
335
|
|
- d = (bias > max_pow / 2) ? max_pow - 1 - bias : bias;
|
|
367
|
+ d = (bias > max_pow >> 1) ? max_pow - 1 - bias : bias;
|
336
|
368
|
|
337
|
369
|
SERIAL_PROTOCOLPAIR(MSG_BIAS, bias);
|
338
|
370
|
SERIAL_PROTOCOLPAIR(MSG_D, d);
|
|
@@ -396,6 +428,16 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
|
396
|
428
|
#endif
|
397
|
429
|
|
398
|
430
|
next_temp_ms = ms + 2000UL;
|
|
431
|
+
|
|
432
|
+ #if WATCH_THE_BED || WATCH_HOTENDS
|
|
433
|
+ if (!heated && input > next_watch_temp) {
|
|
434
|
+ if (input > watch_temp_target) heated = true;
|
|
435
|
+ next_watch_temp = input + hysteresis;
|
|
436
|
+ temp_change_ms = ms + watch_temp_period * 1000UL;
|
|
437
|
+ }
|
|
438
|
+ else if ((!heated && ELAPSED(ms, temp_change_ms)) || (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE))
|
|
439
|
+ _temp_error(hotend, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
|
|
440
|
+ #endif
|
399
|
441
|
} // every 2 seconds
|
400
|
442
|
// Timeout after 20 minutes since the last undershoot/overshoot cycle
|
401
|
443
|
if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) {
|