Browse Source

Fix, improve Power Loss Recovery (#13703)

- Save and restore workspace offsets
- Add retract and purge (hidden) options
- Always restore axis relative modes
- Use added `G92.9` to do position restores
Msq001 6 years ago
parent
commit
455ee23499

+ 67
- 18
Marlin/src/feature/power_loss_recovery.cpp View File

@@ -151,6 +151,12 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
151 151
 
152 152
     // Machine state
153 153
     COPY(info.current_position, current_position);
154
+    #if HAS_HOME_OFFSET
155
+      COPY(info.home_offset, home_offset);
156
+    #endif
157
+    #if HAS_POSITION_SHIFT
158
+      COPY(info.position_shift, position_shift);
159
+    #endif
154 160
     info.feedrate = uint16_t(feedrate_mm_s * 60.0f);
155 161
 
156 162
     #if HOTENDS > 1
@@ -187,7 +193,7 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
187 193
       info.retract_hop = fwretract.current_hop;
188 194
     #endif
189 195
 
190
-    //relative mode
196
+    // Relative mode
191 197
     info.relative_mode = relative_mode;
192 198
     info.relative_modes_e = gcode.axis_relative_modes[E_AXIS];
193 199
 
@@ -239,9 +245,9 @@ void PrintJobRecovery::resume() {
239 245
     gcode.process_subcommands_now_P(PSTR("M420 S0 Z0"));
240 246
   #endif
241 247
 
242
-  // Set Z to 0, raise Z by 2mm, and Home (XY only for Cartesian) with no raise
243
-  // (Only do simulated homing in Marlin Dev Mode.)
244
-  gcode.process_subcommands_now_P(PSTR("G92.0 Z0\nG1 Z" STRINGIFY(RECOVERY_ZRAISE) "\nG28 R0"
248
+  // Set Z to 0, raise Z by RECOVERY_ZRAISE, and Home (XY only for Cartesian)
249
+  // with no raise. (Only do simulated homing in Marlin Dev Mode.)
250
+  gcode.process_subcommands_now_P(PSTR("G92.9 E0 Z0\nG1 Z" STRINGIFY(RECOVERY_ZRAISE) "\nG28 R0"
245 251
     #if ENABLED(MARLIN_DEV_MODE)
246 252
       " S"
247 253
     #elif !IS_KINEMATIC
@@ -252,7 +258,7 @@ void PrintJobRecovery::resume() {
252 258
   // Pretend that all axes are homed
253 259
   axis_homed = axis_known_position = xyz_bits;
254 260
 
255
-  char cmd[40], str_1[16], str_2[16];
261
+  char cmd[50], str_1[16], str_2[16];
256 262
 
257 263
   // Select the previously active tool (with no_move)
258 264
   #if EXTRUDERS > 1
@@ -315,16 +321,16 @@ void PrintJobRecovery::resume() {
315 321
     memcpy(&mixer.gradient, &info.gradient, sizeof(info.gradient));
316 322
   #endif
317 323
 
318
-  // Restore Z (plus raise) and E positions with G92.0
319
-  dtostrf(info.current_position[Z_AXIS] + RECOVERY_ZRAISE, 1, 3, str_1);
320
-  dtostrf(info.current_position[E_AXIS]
321
-    #if ENABLED(SAVE_EACH_CMD_MODE)
322
-      - 5 // Extra extrusion on restart
323
-    #endif
324
-    , 1, 3, str_2
325
-  );
326
-  sprintf_P(cmd, PSTR("G92.0 Z%s E%s"), str_1, str_2);
327
-  gcode.process_subcommands_now(cmd);
324
+  // Extrude and retract to clean the nozzle
325
+  #if POWER_LOSS_PURGE_LEN
326
+    //sprintf_P(cmd, PSTR("G1 E%d F200"), POWER_LOSS_PURGE_LEN);
327
+    //gcode.process_subcommands_now(cmd);
328
+    gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_PURGE_LEN) " F200"));
329
+  #endif
330
+  #if POWER_LOSS_RETRACT_LEN
331
+    sprintf_P(cmd, PSTR("G1 E%d F3000"), POWER_LOSS_PURGE_LEN - POWER_LOSS_RETRACT_LEN);
332
+    gcode.process_subcommands_now(cmd);
333
+  #endif
328 334
 
329 335
   // Move back to the saved XY
330 336
   dtostrf(info.current_position[X_AXIS], 1, 3, str_1);
@@ -337,13 +343,37 @@ void PrintJobRecovery::resume() {
337 343
   sprintf_P(cmd, PSTR("G1 Z%s F200"), str_1);
338 344
   gcode.process_subcommands_now(cmd);
339 345
 
346
+  // Un-retract
347
+  #if POWER_LOSS_PURGE_LEN
348
+    //sprintf_P(cmd, PSTR("G1 E%d F3000"), POWER_LOSS_PURGE_LEN);
349
+    //gcode.process_subcommands_now(cmd);
350
+    gcode.process_subcommands_now_P(PSTR("G1 E" STRINGIFY(POWER_LOSS_PURGE_LEN) " F3000"));
351
+  #endif
352
+
340 353
   // Restore the feedrate
341 354
   sprintf_P(cmd, PSTR("G1 F%d"), info.feedrate);
342 355
   gcode.process_subcommands_now(cmd);
343 356
 
344
-  //relative mode
345
-  if (info.relative_mode) relative_mode = true;
346
-  if (info.relative_modes_e) gcode.axis_relative_modes[E_AXIS] = true;
357
+  // Restore E position with G92.9
358
+  dtostrf(info.current_position[E_AXIS], 1, 3, str_1);
359
+  sprintf_P(cmd, PSTR("G92.9 E%s"), str_1);
360
+  gcode.process_subcommands_now(cmd);
361
+
362
+  // Relative mode
363
+  relative_mode = info.relative_mode;
364
+  gcode.axis_relative_modes[E_AXIS] = info.relative_modes_e;
365
+
366
+  #if HAS_HOME_OFFSET || HAS_POSITION_SHIFT
367
+    LOOP_XYZ(i) {
368
+      #if HAS_HOME_OFFSET
369
+        home_offset[i] = info.home_offset[i];
370
+      #endif
371
+      #if HAS_POSITION_SHIFT
372
+        position_shift[i] = info.position_shift[i];
373
+      #endif
374
+      update_workspace_offset((AxisEnum)i);
375
+    }
376
+  #endif
347 377
 
348 378
   // Process commands from the old pending queue
349 379
   uint8_t c = info.commands_in_queue, r = info.cmd_queue_index_r;
@@ -372,6 +402,25 @@ void PrintJobRecovery::resume() {
372 402
           DEBUG_ECHO(info.current_position[i]);
373 403
         }
374 404
         DEBUG_EOL();
405
+
406
+        #if HAS_HOME_OFFSET
407
+          DEBUG_ECHOPGM("home_offset: ");
408
+          LOOP_XYZ(i) {
409
+            if (i) DEBUG_CHAR(',');
410
+            DEBUG_ECHO(info.home_offset[i]);
411
+          }
412
+          DEBUG_EOL();
413
+        #endif
414
+
415
+        #if HAS_POSITION_SHIFT
416
+          DEBUG_ECHOPGM("position_shift: ");
417
+          LOOP_XYZ(i) {
418
+            if (i) DEBUG_CHAR(',');
419
+            DEBUG_ECHO(info.position_shift[i]);
420
+          }
421
+          DEBUG_EOL();
422
+        #endif
423
+
375 424
         DEBUG_ECHOLNPAIR("feedrate: ", info.feedrate);
376 425
 
377 426
         #if HOTENDS > 1

+ 9
- 0
Marlin/src/feature/power_loss_recovery.h View File

@@ -35,6 +35,8 @@
35 35
 #define SAVE_INFO_INTERVAL_MS 0
36 36
 //#define SAVE_EACH_CMD_MODE
37 37
 //#define DEBUG_POWER_LOSS_RECOVERY
38
+#define POWER_LOSS_PURGE_LEN 20
39
+#define POWER_LOSS_RETRACT_LEN 10
38 40
 
39 41
 typedef struct {
40 42
   uint8_t valid_head;
@@ -42,6 +44,13 @@ typedef struct {
42 44
   // Machine state
43 45
   float current_position[NUM_AXIS];
44 46
 
47
+  #if HAS_HOME_OFFSET
48
+    float home_offset[XYZ];
49
+  #endif
50
+  #if HAS_POSITION_SHIFT
51
+    float position_shift[XYZ];
52
+  #endif
53
+
45 54
   uint16_t feedrate;
46 55
 
47 56
   #if HOTENDS > 1

+ 50
- 38
Marlin/src/gcode/geometry/G92.cpp View File

@@ -33,9 +33,23 @@
33 33
  */
34 34
 void GcodeSuite::G92() {
35 35
 
36
-  #if ENABLED(CNC_COORDINATE_SYSTEMS)
37
-    switch (parser.subcode) {
38
-      case 1:
36
+  bool didE = false;
37
+  #if IS_SCARA || !HAS_POSITION_SHIFT
38
+    bool didXYZ = false;
39
+  #else
40
+    constexpr bool didXYZ = false;
41
+  #endif
42
+
43
+  #if USE_GCODE_SUBCODES
44
+    const uint8_t subcode_G92 = parser.subcode;
45
+  #else
46
+    constexpr uint8_t subcode_G92 = 0;
47
+  #endif
48
+
49
+  switch (subcode_G92) {
50
+    default: break;
51
+    #if ENABLED(CNC_COORDINATE_SYSTEMS)
52
+      case 1: {
39 53
         // Zero the G92 values and restore current position
40 54
         #if !IS_SCARA
41 55
           LOOP_XYZ(i) {
@@ -46,44 +60,42 @@ void GcodeSuite::G92() {
46 60
             }
47 61
           }
48 62
         #endif // Not SCARA
49
-        return;
50
-    }
51
-  #endif
52
-
53
-  #if ENABLED(CNC_COORDINATE_SYSTEMS)
54
-    #define IS_G92_0 (parser.subcode == 0)
55
-  #else
56
-    #define IS_G92_0 true
57
-  #endif
58
-
59
-  bool didE = false;
60
-  #if IS_SCARA || !HAS_POSITION_SHIFT
61
-    bool didXYZ = false;
62
-  #else
63
-    constexpr bool didXYZ = false;
64
-  #endif
65
-
66
-  if (IS_G92_0) LOOP_XYZE(i) {
67
-    if (parser.seenval(axis_codes[i])) {
68
-      const float l = parser.value_axis_units((AxisEnum)i),
69
-                  v = i == E_AXIS ? l : LOGICAL_TO_NATIVE(l, i),
70
-                  d = v - current_position[i];
71
-      if (!NEAR_ZERO(d)) {
72
-        #if IS_SCARA || !HAS_POSITION_SHIFT
73
-          if (i == E_AXIS) didE = true; else didXYZ = true;
74
-          current_position[i] = v;        // Without workspaces revert to Marlin 1.0 behavior
75
-        #elif HAS_POSITION_SHIFT
76
-          if (i == E_AXIS) {
77
-            didE = true;
78
-            current_position[E_AXIS] = v; // When using coordinate spaces, only E is set directly
63
+      } return;
64
+    #endif
65
+    #if ENABLED(POWER_LOSS_RECOVERY)
66
+      case 9: {
67
+        LOOP_XYZE(i) {
68
+          if (parser.seenval(axis_codes[i])) {
69
+            current_position[i] = parser.value_axis_units((AxisEnum)i);
70
+            if (i == E_AXIS) didE = true; else didXYZ = true;
79 71
           }
80
-          else {
81
-            position_shift[i] += d;       // Other axes simply offset the coordinate space
82
-            update_workspace_offset((AxisEnum)i);
72
+        }
73
+      } break;
74
+    #endif
75
+    case 0: {
76
+      LOOP_XYZE(i) {
77
+        if (parser.seenval(axis_codes[i])) {
78
+          const float l = parser.value_axis_units((AxisEnum)i),
79
+                      v = i == E_AXIS ? l : LOGICAL_TO_NATIVE(l, i),
80
+                      d = v - current_position[i];
81
+          if (!NEAR_ZERO(d)) {
82
+            #if IS_SCARA || !HAS_POSITION_SHIFT
83
+              if (i == E_AXIS) didE = true; else didXYZ = true;
84
+              current_position[i] = v;        // Without workspaces revert to Marlin 1.0 behavior
85
+            #elif HAS_POSITION_SHIFT
86
+              if (i == E_AXIS) {
87
+                didE = true;
88
+                current_position[E_AXIS] = v; // When using coordinate spaces, only E is set directly
89
+              }
90
+              else {
91
+                position_shift[i] += d;       // Other axes simply offset the coordinate space
92
+                update_workspace_offset((AxisEnum)i);
93
+              }
94
+            #endif
83 95
           }
84
-        #endif
96
+        }
85 97
       }
86
-    }
98
+    } break;
87 99
   }
88 100
 
89 101
   #if ENABLED(CNC_COORDINATE_SYSTEMS)

+ 0
- 3
Marlin/src/gcode/sdcard/M23.cpp View File

@@ -31,9 +31,6 @@
31 31
  * M23: Open a file
32 32
  */
33 33
 void GcodeSuite::M23() {
34
-  #if ENABLED(POWER_LOSS_RECOVERY)
35
-    card.removeJobRecoveryFile();
36
-  #endif
37 34
   // Simplify3D includes the size, so zero out all spaces (#7227)
38 35
   for (char *fn = parser.string_arg; *fn; ++fn) if (*fn == ' ') *fn = '\0';
39 36
   card.openFile(parser.string_arg, true);

+ 1
- 0
Marlin/src/sd/cardreader.cpp View File

@@ -1030,6 +1030,7 @@ void CardReader::printingHasFinished() {
1030 1030
   // be zeroed and written instead of deleted.
1031 1031
   void CardReader::removeJobRecoveryFile() {
1032 1032
     if (jobRecoverFileExists()) {
1033
+      recovery.init();
1033 1034
       removeFile(job_recovery_file_name);
1034 1035
       #if ENABLED(DEBUG_POWER_LOSS_RECOVERY)
1035 1036
         SERIAL_ECHOPGM("Power-loss file delete");

Loading…
Cancel
Save