Bladeren bron

Merge pull request #9040 from thinkyhead/bf2_m303_bughunt

[2.0.x] M303 pid autotune cleanup, comment
Scott Lahteine 7 jaren geleden
bovenliggende
commit
41246b45f1
No account linked to committer's email address
3 gewijzigde bestanden met toevoegingen van 43 en 51 verwijderingen
  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 Bestand weergeven

26
 /**
26
 /**
27
  * M303: PID relay autotune
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
  *       E<extruder> (-1 for the bed) (default 0)
30
  *       E<extruder> (-1 for the bed) (default 0)
31
  *       C<cycles>
31
  *       C<cycles>
32
  *       U<bool> with a non-zero value will apply the result to current settings
32
  *       U<bool> with a non-zero value will apply the result to current settings

+ 41
- 49
Marlin/src/module/temperature.cpp Bestand weergeven

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

+ 1
- 1
Marlin/src/module/temperature.h Bestand weergeven

445
      * Perform auto-tuning for hotend or bed in response to M303
445
      * Perform auto-tuning for hotend or bed in response to M303
446
      */
446
      */
447
     #if HAS_PID_HEATING
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
        * Update the temp manager when PID values change
451
        * Update the temp manager when PID values change

Laden…
Annuleren
Opslaan