瀏覽代碼

Merge pull request #9040 from thinkyhead/bf2_m303_bughunt

[2.0.x] M303 pid autotune cleanup, comment
Scott Lahteine 7 年之前
父節點
當前提交
41246b45f1
No account linked to committer's email address
共有 3 個文件被更改,包括 43 次插入51 次删除
  1. 1
    1
      Marlin/src/gcode/temperature/M303.cpp
  2. 41
    49
      Marlin/src/module/temperature.cpp
  3. 1
    1
      Marlin/src/module/temperature.h

+ 1
- 1
Marlin/src/gcode/temperature/M303.cpp 查看文件

@@ -26,7 +26,7 @@
26 26
 /**
27 27
  * M303: PID relay autotune
28 28
  *
29
- *       S<temperature> sets the target temperature. (default 150C)
29
+ *       S<temperature> sets the target temperature. (default 150C / 70C)
30 30
  *       E<extruder> (-1 for the bed) (default 0)
31 31
  *       C<cycles>
32 32
  *       U<bool> with a non-zero value will apply the result to current settings

+ 41
- 49
Marlin/src/module/temperature.cpp 查看文件

@@ -219,8 +219,8 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
219 219
    * Alternately heat and cool the nozzle, observing its behavior to
220 220
    * determine the best PID values to achieve a stable temperature.
221 221
    */
222
-  void Temperature::PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result/*=false*/) {
223
-    float input = 0.0;
222
+  void Temperature::PID_autotune(const float &target, const int8_t hotend, const int8_t ncycles, const bool set_result/*=false*/) {
223
+    float current = 0.0;
224 224
     int cycles = 0;
225 225
     bool heating = true;
226 226
 
@@ -232,34 +232,19 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
232 232
           workKp = 0, workKi = 0, workKd = 0,
233 233
           max = 0, min = 10000;
234 234
 
235
+    #define HAS_TP_BED (ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED))
236
+    #if HAS_TP_BED && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
237
+      #define TV(B,H) (hotend < 0 ? (B) : (H))
238
+    #elif HAS_TP_BED
239
+      #define TV(B,H) (B)
240
+    #else
241
+      #define TV(B,H) (H)
242
+    #endif
243
+
235 244
     #if WATCH_THE_BED || WATCH_HOTENDS
236
-      const float watch_temp_target = temp -
237
-        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
238
-          (hotend < 0 ? (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1) : (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1))
239
-        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
240
-          (WATCH_BED_TEMP_INCREASE + TEMP_BED_HYSTERESIS + 1)
241
-        #else
242
-          (WATCH_TEMP_INCREASE + TEMP_HYSTERESIS + 1)
243
-        #endif
244
-      ;
245
-      const int8_t watch_temp_period =
246
-        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
247
-          hotend < 0 ? WATCH_BED_TEMP_PERIOD : WATCH_TEMP_PERIOD
248
-        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
249
-          WATCH_BED_TEMP_PERIOD
250
-        #else
251
-          WATCH_TEMP_PERIOD
252
-        #endif
253
-      ;
254
-      const int8_t watch_temp_increase =
255
-        #if ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED) && ENABLED(THERMAL_PROTECTION_HOTENDS) && ENABLED(PIDTEMP)
256
-          hotend < 0 ? WATCH_BED_TEMP_INCREASE : WATCH_TEMP_INCREASE
257
-        #elif ENABLED(THERMAL_PROTECTION_BED) && ENABLED(PIDTEMPBED)
258
-          WATCH_BED_TEMP_INCREASE
259
-        #else
260
-          WATCH_TEMP_INCREASE
261
-        #endif
262
-      ;
245
+      const int8_t watch_temp_period = TV(WATCH_BED_TEMP_PERIOD, WATCH_TEMP_PERIOD),
246
+                   watch_temp_increase = TV(WATCH_BED_TEMP_INCREASE, WATCH_TEMP_INCREASE);
247
+      const float watch_temp_target = target - float(watch_temp_increase + TV(TEMP_BED_HYSTERESIS, TEMP_HYSTERESIS) + 1);
263 248
       millis_t temp_change_ms = next_temp_ms + watch_temp_period * 1000UL;
264 249
       float next_watch_temp = 0.0;
265 250
       bool heated = false;
@@ -300,7 +285,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
300 285
       soft_pwm_amount_bed = bias = d = (MAX_BED_POWER) >> 1;
301 286
     #endif
302 287
 
303
-    wait_for_heatup = true;
288
+    wait_for_heatup = true; // Can be interrupted with M108
304 289
 
305 290
     // PID Tuning loop
306 291
     while (wait_for_heatup) {
@@ -310,7 +295,8 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
310 295
       if (temp_meas_ready) { // temp sample ready
311 296
         updateTemperaturesFromRawValues();
312 297
 
313
-        input =
298
+        // Get the current temperature and constrain it
299
+        current =
314 300
           #if HAS_PID_FOR_BOTH
315 301
             hotend < 0 ? current_temperature_bed : current_temperature[hotend]
316 302
           #elif ENABLED(PIDTEMP)
@@ -319,9 +305,8 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
319 305
             current_temperature_bed
320 306
           #endif
321 307
         ;
322
-
323
-        NOLESS(max, input);
324
-        NOMORE(min, input);
308
+        NOLESS(max, current);
309
+        NOMORE(min, current);
325 310
 
326 311
         #if HAS_AUTO_FAN
327 312
           if (ELAPSED(ms, next_auto_fan_check_ms)) {
@@ -330,7 +315,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
330 315
           }
331 316
         #endif
332 317
 
333
-        if (heating && input > temp) {
318
+        if (heating && current > target) {
334 319
           if (ELAPSED(ms, t2 + 5000UL)) {
335 320
             heating = false;
336 321
             #if HAS_PID_FOR_BOTH
@@ -345,11 +330,11 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
345 330
             #endif
346 331
             t1 = ms;
347 332
             t_high = t1 - t2;
348
-            max = temp;
333
+            max = target;
349 334
           }
350 335
         }
351 336
 
352
-        if (!heating && input < temp) {
337
+        if (!heating && current < target) {
353 338
           if (ELAPSED(ms, t1 + 5000UL)) {
354 339
             heating = true;
355 340
             t2 = ms;
@@ -373,7 +358,7 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
373 358
               SERIAL_PROTOCOLPAIR(MSG_T_MIN, min);
374 359
               SERIAL_PROTOCOLPAIR(MSG_T_MAX, max);
375 360
               if (cycles > 2) {
376
-                Ku = (4.0 * d) / (M_PI * (max - min) * 0.5); // i.e., CIRCLE_CIRC((max - min) * 0.25)
361
+                Ku = (4.0 * d) / (M_PI * (max - min) * 0.5);
377 362
                 Tu = ((float)(t_low + t_high) * 0.001);
378 363
                 SERIAL_PROTOCOLPAIR(MSG_KU, Ku);
379 364
                 SERIAL_PROTOCOLPAIR(MSG_TU, Tu);
@@ -413,41 +398,48 @@ uint8_t Temperature::soft_pwm_amount[HOTENDS],
413 398
               soft_pwm_amount_bed = (bias + d) >> 1;
414 399
             #endif
415 400
             cycles++;
416
-            min = temp;
401
+            min = target;
417 402
           }
418 403
         }
419 404
       }
405
+
406
+      // Did the temperature overshoot very far?
420 407
       #define MAX_OVERSHOOT_PID_AUTOTUNE 20
421
-      if (input > temp + MAX_OVERSHOOT_PID_AUTOTUNE) {
408
+      if (current > target + MAX_OVERSHOOT_PID_AUTOTUNE) {
422 409
         SERIAL_PROTOCOLLNPGM(MSG_PID_TEMP_TOO_HIGH);
423 410
         break;
424 411
       }
425
-      // Every 2 seconds...
412
+
413
+      // Report heater states every 2 seconds
426 414
       if (ELAPSED(ms, next_temp_ms)) {
427 415
         #if HAS_TEMP_HOTEND || HAS_TEMP_BED
428 416
           print_heaterstates();
429 417
           SERIAL_EOL();
430 418
         #endif
431
-
432 419
         next_temp_ms = ms + 2000UL;
433 420
 
421
+        // Make sure heating is actually working
434 422
         #if WATCH_THE_BED || WATCH_HOTENDS
435
-          if (!heated && input > next_watch_temp) {
436
-            if (input > watch_temp_target) heated = true;
437
-            next_watch_temp = input + watch_temp_increase;
438
-            temp_change_ms = ms + watch_temp_period * 1000UL;
423
+          if (!heated) {                                          // If not yet reached target...
424
+            if (current > next_watch_temp) {                      // Over the watch temp?
425
+              next_watch_temp = current + watch_temp_increase;    // - set the next temp to watch for
426
+              temp_change_ms = ms + watch_temp_period * 1000UL;   // - move the expiration timer up
427
+              if (current > watch_temp_target) heated = true;     // - Flag if target temperature reached
428
+            }
429
+            else if (ELAPSED(ms, temp_change_ms))                 // Watch timer expired
430
+              _temp_error(hotend, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD));
439 431
           }
440
-          else if (!heated && ELAPSED(ms, temp_change_ms))
441
-            _temp_error(hotend, PSTR(MSG_T_HEATING_FAILED), PSTR(MSG_HEATING_FAILED_LCD));
442
-          else if (heated && input < temp - MAX_OVERSHOOT_PID_AUTOTUNE)
432
+          else if (current < target - (MAX_OVERSHOOT_PID_AUTOTUNE)) // Heated, then temperature fell too far?
443 433
             _temp_error(hotend, PSTR(MSG_T_THERMAL_RUNAWAY), PSTR(MSG_THERMAL_RUNAWAY));
444 434
         #endif
445 435
       } // every 2 seconds
436
+
446 437
       // Timeout after 20 minutes since the last undershoot/overshoot cycle
447 438
       if (((ms - t1) + (ms - t2)) > (20L * 60L * 1000L)) {
448 439
         SERIAL_PROTOCOLLNPGM(MSG_PID_TIMEOUT);
449 440
         break;
450 441
       }
442
+
451 443
       if (cycles > ncycles) {
452 444
         SERIAL_PROTOCOLLNPGM(MSG_PID_AUTOTUNE_FINISHED);
453 445
 

+ 1
- 1
Marlin/src/module/temperature.h 查看文件

@@ -445,7 +445,7 @@ class Temperature {
445 445
      * Perform auto-tuning for hotend or bed in response to M303
446 446
      */
447 447
     #if HAS_PID_HEATING
448
-      static void PID_autotune(const float temp, const int8_t hotend, const int8_t ncycles, const bool set_result=false);
448
+      static void PID_autotune(const float &target, const int8_t hotend, const int8_t ncycles, const bool set_result=false);
449 449
 
450 450
       /**
451 451
        * Update the temp manager when PID values change

Loading…
取消
儲存