ソースを参照

Add G29_RETRY_AND_RECOVER feature

- Add an option to retry G29, optionally executing a G-code procedure after each failed probe.
Marcio Teixeira 7年前
コミット
5cc7916e69

+ 24
- 0
Marlin/Configuration_adv.h ファイルの表示

746
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
746
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
747
 #endif
747
 #endif
748
 
748
 
749
+/**
750
+ * Repeatedly attempt G29 leveling until it succeeds.
751
+ * Stop after G29_MAX_RETRIES attempts.
752
+ */
753
+//#define G29_RETRY_AND_RECOVER
754
+#if ENABLED(G29_RETRY_AND_RECOVER)
755
+  #define G29_MAX_RETRIES 3
756
+  #define G29_HALT_ON_FAILURE
757
+  /**
758
+   * Specify the GCODE commands that will be executed when leveling succeeds,
759
+   * between attempts, and after the maximum number of retries have been tried.
760
+   */
761
+  #define G29_SUCCESS_COMMANDS "M117 Bed leveling done."
762
+  #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0"
763
+  #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1"
764
+  /**
765
+   * Specify an action command to send to the host on a recovery attempt or failure.
766
+   * Will be sent in the form '//action:ACTION_ON_G29_FAILURE', e.g. '//action:probe_failed'.
767
+   * The host must be configured to handle the action command.
768
+   */
769
+  #define G29_ACTION_ON_RECOVER "probe_rewipe"
770
+  #define G29_ACTION_ON_FAILURE "probe_failed"
771
+#endif
772
+
749
 // @section extras
773
 // @section extras
750
 
774
 
751
 //
775
 //

+ 24
- 0
Marlin/src/config/default/Configuration_adv.h ファイルの表示

746
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
746
   //#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
747
 #endif
747
 #endif
748
 
748
 
749
+/**
750
+ * Repeatedly attempt G29 leveling until it succeeds.
751
+ * Stop after G29_MAX_RETRIES attempts.
752
+ */
753
+//#define G29_RETRY_AND_RECOVER
754
+#if ENABLED(G29_RETRY_AND_RECOVER)
755
+  #define G29_MAX_RETRIES 3
756
+  #define G29_HALT_ON_FAILURE
757
+  /**
758
+   * Specify the GCODE commands that will be executed when leveling succeeds,
759
+   * between attempts, and after the maximum number of retries have been tried.
760
+   */
761
+  #define G29_SUCCESS_COMMANDS "M117 Bed leveling done."
762
+  #define G29_RECOVER_COMMANDS "M117 Probe failed. Rewiping.\nG28\nG12 P0 S12 T0"
763
+  #define G29_FAILURE_COMMANDS "M117 Bed leveling failed.\nG0 Z10\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nM300 P25 S880\nM300 P50 S0\nG4 S1"
764
+  /**
765
+   * Specify an action command to send to the host on a recovery attempt or failure.
766
+   * Will be sent in the form '//action:ACTION_ON_G29_FAILURE', e.g. '//action:probe_failed'.
767
+   * The host must be configured to handle the action command.
768
+   */
769
+  #define G29_ACTION_ON_RECOVER "probe_rewipe"
770
+  #define G29_ACTION_ON_FAILURE "probe_failed"
771
+#endif
772
+
749
 // @section extras
773
 // @section extras
750
 
774
 
751
 //
775
 //

+ 91
- 4
Marlin/src/gcode/gcode.cpp ファイルの表示

61
   float GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
61
   float GcodeSuite::coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
62
 #endif
62
 #endif
63
 
63
 
64
+#if HAS_LEVELING && ENABLED(G29_RETRY_AND_RECOVER)
65
+  #include "../feature/bedlevel/bedlevel.h"
66
+  #include "../module/planner.h"
67
+#endif
68
+
64
 /**
69
 /**
65
  * Set target_extruder from the T parameter or the active_extruder
70
  * Set target_extruder from the T parameter or the active_extruder
66
  *
71
  *
125
   while (PENDING(millis(), time)) idle();
130
   while (PENDING(millis(), time)) idle();
126
 }
131
 }
127
 
132
 
133
+/**
134
+ * When G29_RETRY_AND_RECOVER is enabled, call G29() in
135
+ * a loop with recovery and retry handling.
136
+ */
137
+#if HAS_LEVELING && ENABLED(G29_RETRY_AND_RECOVER)
138
+
139
+  void GcodeSuite::G29_with_retry() {
140
+    set_bed_leveling_enabled(false);
141
+    for (uint8_t i = G29_MAX_RETRIES; i--;) {
142
+      G29();
143
+      if (planner.leveling_active) break;
144
+      #ifdef G29_ACTION_ON_RECOVER
145
+        SERIAL_ECHOLNPGM("//action:" G29_ACTION_ON_RECOVER);
146
+      #endif
147
+      #ifdef G29_RECOVERY_COMMANDS
148
+        process_subcommands_now_P(PSTR(G29_RECOVER_COMMANDS));
149
+      #endif
150
+    }
151
+    if (planner.leveling_active) {
152
+      #ifdef G29_SUCCESS_COMMANDS
153
+        process_subcommands_now_P(PSTR(G29_SUCCESS_COMMANDS));
154
+      #endif
155
+    }
156
+    else {
157
+      #ifdef G29_FAILURE_COMMANDS
158
+        process_subcommands_now_P(PSTR(G29_FAILURE_COMMANDS));
159
+      #endif
160
+      #ifdef G29_ACTION_ON_FAILURE
161
+        SERIAL_ECHOLNPGM("//action:" G29_ACTION_ON_FAILURE);
162
+      #endif
163
+      #if ENABLED(G29_HALT_ON_FAILURE)
164
+        kill(PSTR(MSG_ERR_PROBING_FAILED));
165
+      #endif
166
+    }
167
+  }
168
+
169
+#endif // HAS_LEVELING && G29_RETRY_AND_RECOVER
170
+
128
 //
171
 //
129
 // Placeholders for non-migrated codes
172
 // Placeholders for non-migrated codes
130
 //
173
 //
135
 /**
178
 /**
136
  * Process the parsed command and dispatch it to its handler
179
  * Process the parsed command and dispatch it to its handler
137
  */
180
  */
138
-void GcodeSuite::process_parsed_command() {
181
+void GcodeSuite::process_parsed_command(
182
+  #if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
183
+    const bool no_ok
184
+  #endif
185
+) {
139
   KEEPALIVE_STATE(IN_HANDLER);
186
   KEEPALIVE_STATE(IN_HANDLER);
140
 
187
 
141
   // Handle a known G, M, or T
188
   // Handle a known G, M, or T
190
       case 28: G28(false); break;                                 // G28: Home all axes, one at a time
237
       case 28: G28(false); break;                                 // G28: Home all axes, one at a time
191
 
238
 
192
       #if HAS_LEVELING
239
       #if HAS_LEVELING
193
-        case 29: G29(); break;                                    // G29: Bed leveling calibration
194
-      #endif
240
+        case 29:                                                  // G29: Bed leveling calibration
241
+          #if ENABLED(G29_RETRY_AND_RECOVER)
242
+            G29_with_retry();
243
+          #else
244
+            G29();
245
+          #endif
246
+          break;
247
+      #endif // HAS_LEVELING
195
 
248
 
196
       #if HAS_BED_PROBE
249
       #if HAS_BED_PROBE
197
         case 30: G30(); break;                                    // G30: Single Z probe
250
         case 30: G30(); break;                                    // G30: Single Z probe
612
 
665
 
613
   KEEPALIVE_STATE(NOT_BUSY);
666
   KEEPALIVE_STATE(NOT_BUSY);
614
 
667
 
615
-  ok_to_send();
668
+  #if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
669
+    if (!no_ok)
670
+  #endif
671
+      ok_to_send();
616
 }
672
 }
617
 
673
 
618
 /**
674
 /**
638
   process_parsed_command();
694
   process_parsed_command();
639
 }
695
 }
640
 
696
 
697
+#if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
698
+  /**
699
+   * Run a series of commands, bypassing the command queue to allow
700
+   * G-code "macros" to be called from within other G-code handlers.
701
+   */
702
+  void GcodeSuite::process_subcommands_now_P(const char *pgcode) {
703
+    // Save the parser state
704
+    char saved_cmd[strlen(parser.command_ptr) + 1];
705
+    strcpy(saved_cmd, parser.command_ptr);
706
+
707
+    // Process individual commands in string
708
+    while (pgm_read_byte_near(pgcode)) {
709
+      // Break up string at '\n' delimiters
710
+      const char *delim = strchr_P(pgcode, '\n');
711
+      size_t len = delim ? delim - pgcode : strlen_P(pgcode);
712
+      char cmd[len + 1];
713
+      strncpy_P(cmd, pgcode, len);
714
+      cmd[len] = '\0';
715
+      pgcode += len;
716
+      if (delim) pgcode++;
717
+
718
+      // Parse the next command in the string
719
+      parser.parse(cmd);
720
+      process_parsed_command(true);
721
+    }
722
+
723
+    // Restore the parser state
724
+    parser.parse(saved_cmd);
725
+  }
726
+#endif
727
+
641
 #if ENABLED(HOST_KEEPALIVE_FEATURE)
728
 #if ENABLED(HOST_KEEPALIVE_FEATURE)
642
 
729
 
643
   /**
730
   /**

+ 12
- 1
Marlin/src/gcode/gcode.h ファイルの表示

285
 
285
 
286
   static bool get_target_extruder_from_command();
286
   static bool get_target_extruder_from_command();
287
   static void get_destination_from_command();
287
   static void get_destination_from_command();
288
-  static void process_parsed_command();
288
+  static void process_parsed_command(
289
+    #if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
290
+      const bool no_ok = false
291
+    #endif
292
+  );
289
   static void process_next_command();
293
   static void process_next_command();
290
 
294
 
295
+  #if ENABLED(USE_EXECUTE_COMMANDS_IMMEDIATE)
296
+    static void process_subcommands_now_P(const char *pgcode);
297
+  #endif
298
+
291
   FORCE_INLINE static void home_all_axes() { G28(true); }
299
   FORCE_INLINE static void home_all_axes() { G28(true); }
292
 
300
 
293
   /**
301
   /**
380
 
388
 
381
   #if HAS_LEVELING
389
   #if HAS_LEVELING
382
     static void G29();
390
     static void G29();
391
+    #if ENABLED(G29_RETRY_AND_RECOVER)
392
+      static void G29_with_retry();
393
+    #endif
383
   #endif
394
   #endif
384
 
395
 
385
   #if HAS_BED_PROBE
396
   #if HAS_BED_PROBE

+ 4
- 0
Marlin/src/inc/Conditionals_post.h ファイルの表示

1448
 // If platform requires early initialization of watchdog to properly boot
1448
 // If platform requires early initialization of watchdog to properly boot
1449
 #define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM))
1449
 #define EARLY_WATCHDOG (ENABLED(USE_WATCHDOG) && defined(ARDUINO_ARCH_SAM))
1450
 
1450
 
1451
+#if ENABLED(G29_RETRY_AND_RECOVER)
1452
+  #define USE_EXECUTE_COMMANDS_IMMEDIATE
1453
+#endif
1454
+
1451
 #endif // CONDITIONALS_POST_H
1455
 #endif // CONDITIONALS_POST_H

読み込み中…
キャンセル
保存