Pārlūkot izejas kodu

Realtime Reporting, S000, P000, R000 (#19330)

fedetony 4 gadus atpakaļ
vecāks
revīzija
32dba5e0c7
Revīzijas autora e-pasta adrese nav piesaistīta nevienam kontam

+ 9
- 0
Marlin/Configuration_adv.h Parādīt failu

@@ -2115,6 +2115,15 @@
2115 2115
  */
2116 2116
 //#define EMERGENCY_PARSER
2117 2117
 
2118
+/**
2119
+ * Realtime Reporting
2120
+ * Add support for commands S000 State, P000 Pause, and R000 Resume
2121
+ */
2122
+//#define REALTIME_REPORTING_COMMANDS
2123
+#if ENABLED(REALTIME_REPORTING_COMMANDS)
2124
+  //#define FULL_REPORT_TO_HOST_FEATURE   // Auto-report the machine status like Grbl CNC
2125
+#endif
2126
+
2118 2127
 // Bad Serial-connections can miss a received command by sending an 'ok'
2119 2128
 // Therefore some clients abort after 30 seconds in a timeout.
2120 2129
 // Some other clients start sending commands while receiving a 'wait'.

+ 76
- 58
Marlin/src/feature/e_parser.h Parādīt failu

@@ -34,29 +34,33 @@
34 34
 // External references
35 35
 extern bool wait_for_user, wait_for_heatup;
36 36
 
37
+#if ENABLED(REALTIME_REPORTING_COMMANDS)
38
+  // From motion.h, which cannot be included here
39
+  void report_current_position_moving();
40
+  void quickpause_stepper();
41
+  void quickresume_stepper();
42
+#endif
43
+
37 44
 class EmergencyParser {
38 45
 
39 46
 public:
40 47
 
41
-  // Currently looking for: M108, M112, M410, M876
42
-  enum State : char {
48
+  // Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000
49
+  enum State : uint8_t {
43 50
     EP_RESET,
44 51
     EP_N,
45 52
     EP_M,
46 53
     EP_M1,
47
-    EP_M10,
48
-    EP_M108,
49
-    EP_M11,
50
-    EP_M112,
51
-    EP_M4,
52
-    EP_M41,
53
-    EP_M410,
54
+    EP_M10, EP_M108,
55
+    EP_M11, EP_M112,
56
+    EP_M4, EP_M41, EP_M410,
54 57
     #if ENABLED(HOST_PROMPT_SUPPORT)
55
-      EP_M8,
56
-      EP_M87,
57
-      EP_M876,
58
-      EP_M876S,
59
-      EP_M876SN,
58
+      EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
59
+    #endif
60
+    #if ENABLED(REALTIME_REPORTING_COMMANDS)
61
+      EP_S, EP_S0, EP_S00, EP_GRBL_STATUS,
62
+      EP_R, EP_R0, EP_R00, EP_GRBL_RESUME,
63
+      EP_P, EP_P0, EP_P00, EP_GRBL_PAUSE,
60 64
     #endif
61 65
     EP_IGNORE // to '\n'
62 66
   };
@@ -71,7 +75,6 @@ public:
71 75
   EmergencyParser() { enable(); }
72 76
 
73 77
   FORCE_INLINE static void enable()  { enabled = true; }
74
-
75 78
   FORCE_INLINE static void disable() { enabled = false; }
76 79
 
77 80
   FORCE_INLINE static void update(State &state, const uint8_t c) {
@@ -79,21 +82,45 @@ public:
79 82
       case EP_RESET:
80 83
         switch (c) {
81 84
           case ' ': case '\n': case '\r': break;
82
-          case 'N': state = EP_N;      break;
83
-          case 'M': state = EP_M;      break;
84
-          default: state  = EP_IGNORE;
85
+          case 'N': state = EP_N; break;
86
+          case 'M': state = EP_M; break;
87
+          #if ENABLED(REALTIME_REPORTING_COMMANDS)
88
+            case 'S': state = EP_S; break;
89
+            case 'P': state = EP_P; break;
90
+            case 'R': state = EP_R; break;
91
+          #endif
92
+          default: state = EP_IGNORE;
85 93
         }
86 94
         break;
87 95
 
88 96
       case EP_N:
89 97
         switch (c) {
90 98
           case '0' ... '9':
91
-          case '-': case ' ':   break;
92
-          case 'M': state = EP_M;      break;
93
-          default:  state = EP_IGNORE;
99
+          case '-': case ' ':     break;
100
+          case 'M': state = EP_M; break;
101
+          #if ENABLED(REALTIME_REPORTING_COMMANDS)
102
+            case 'S': state = EP_S; break;
103
+            case 'P': state = EP_P; break;
104
+            case 'R': state = EP_R; break;
105
+          #endif
106
+          default: state = EP_IGNORE;
94 107
         }
95 108
         break;
96 109
 
110
+      #if ENABLED(REALTIME_REPORTING_COMMANDS)
111
+        case EP_S:   state = (c == '0') ? EP_S0          : EP_IGNORE; break;
112
+        case EP_S0:  state = (c == '0') ? EP_S00         : EP_IGNORE; break;
113
+        case EP_S00: state = (c == '0') ? EP_GRBL_STATUS : EP_IGNORE; break;
114
+
115
+        case EP_R:   state = (c == '0') ? EP_R0          : EP_IGNORE; break;
116
+        case EP_R0:  state = (c == '0') ? EP_R00         : EP_IGNORE; break;
117
+        case EP_R00: state = (c == '0') ? EP_GRBL_RESUME : EP_IGNORE; break;
118
+
119
+        case EP_P:   state = (c == '0') ? EP_P0          : EP_IGNORE; break;
120
+        case EP_P0:  state = (c == '0') ? EP_P00         : EP_IGNORE; break;
121
+        case EP_P00: state = (c == '0') ? EP_GRBL_PAUSE  : EP_IGNORE; break;
122
+      #endif
123
+
97 124
       case EP_M:
98 125
         switch (c) {
99 126
           case ' ': break;
@@ -114,48 +141,34 @@ public:
114 141
         }
115 142
         break;
116 143
 
117
-      case EP_M10:
118
-        state = (c == '8') ? EP_M108 : EP_IGNORE;
119
-        break;
120
-
121
-      case EP_M11:
122
-        state = (c == '2') ? EP_M112 : EP_IGNORE;
123
-        break;
124
-
125
-      case EP_M4:
126
-        state = (c == '1') ? EP_M41 : EP_IGNORE;
127
-        break;
128
-
129
-      case EP_M41:
130
-        state = (c == '0') ? EP_M410 : EP_IGNORE;
131
-        break;
144
+      case EP_M10: state = (c == '8') ? EP_M108 : EP_IGNORE; break;
145
+      case EP_M11: state = (c == '2') ? EP_M112 : EP_IGNORE; break;
146
+      case EP_M4:  state = (c == '1') ? EP_M41  : EP_IGNORE; break;
147
+      case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
132 148
 
133 149
       #if ENABLED(HOST_PROMPT_SUPPORT)
134
-      case EP_M8:
135
-        state = (c == '7') ? EP_M87 : EP_IGNORE;
136
-        break;
137 150
 
138
-      case EP_M87:
139
-        state = (c == '6') ? EP_M876 : EP_IGNORE;
140
-        break;
151
+        case EP_M8:  state = (c == '7') ? EP_M87  : EP_IGNORE; break;
152
+        case EP_M87: state = (c == '6') ? EP_M876 : EP_IGNORE; break;
141 153
 
142
-      case EP_M876:
143
-        switch (c) {
144
-          case ' ': break;
145
-          case 'S': state = EP_M876S; break;
146
-          default:  state = EP_IGNORE; break;
147
-        }
148
-        break;
154
+        case EP_M876:
155
+          switch (c) {
156
+            case ' ': break;
157
+            case 'S': state = EP_M876S; break;
158
+            default: state = EP_IGNORE; break;
159
+          }
160
+          break;
161
+
162
+        case EP_M876S:
163
+          switch (c) {
164
+            case ' ': break;
165
+            case '0' ... '9':
166
+              state = EP_M876SN;
167
+              M876_reason = uint8_t(c - '0');
168
+              break;
169
+          }
170
+          break;
149 171
 
150
-      case EP_M876S:
151
-        switch (c) {
152
-          case ' ': break;
153
-          case '0' ... '9':
154
-            state = EP_M876SN;
155
-            M876_reason = (uint8_t)(c - '0');
156
-            break;
157
-        }
158
-        break;
159 172
       #endif
160 173
 
161 174
       case EP_IGNORE:
@@ -171,6 +184,11 @@ public:
171 184
             #if ENABLED(HOST_PROMPT_SUPPORT)
172 185
               case EP_M876SN: host_response_handler(M876_reason); break;
173 186
             #endif
187
+            #if ENABLED(REALTIME_REPORTING_COMMANDS)
188
+              case EP_GRBL_STATUS: report_current_position_moving(); break;
189
+              case EP_GRBL_PAUSE: quickpause_stepper(); break;
190
+              case EP_GRBL_RESUME: quickresume_stepper(); break;
191
+            #endif
174 192
             default: break;
175 193
           }
176 194
           state = EP_RESET;

+ 4
- 1
Marlin/src/gcode/bedlevel/abl/G29.cpp Parādīt failu

@@ -217,9 +217,10 @@ public:
217 217
  *     There's no extra effect if you have a fixed Z probe.
218 218
  */
219 219
 G29_TYPE GcodeSuite::G29() {
220
-
221 220
   TERN_(PROBE_MANUALLY, static) G29_State abl;
222 221
 
222
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));
223
+
223 224
   reset_stepper_timeout();
224 225
 
225 226
   const bool seenQ = EITHER(DEBUG_LEVELING_FEATURE, PROBE_MANUALLY) && parser.seen('Q');
@@ -897,6 +898,8 @@ G29_TYPE GcodeSuite::G29() {
897 898
 
898 899
   report_current_position();
899 900
 
901
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
902
+
900 903
   G29_RETURN(ISNAN(abl.measured_z));
901 904
 }
902 905
 

+ 4
- 0
Marlin/src/gcode/bedlevel/mbl/G29.cpp Parādīt failu

@@ -60,6 +60,8 @@ inline void echo_not_entered(const char c) { SERIAL_CHAR(c); SERIAL_ECHOLNPGM("
60 60
  */
61 61
 void GcodeSuite::G29() {
62 62
 
63
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));
64
+
63 65
   static int mbl_probe_index = -1;
64 66
 
65 67
   MeshLevelingState state = (MeshLevelingState)parser.byteval('S', (int8_t)MeshReport);
@@ -187,6 +189,8 @@ void GcodeSuite::G29() {
187 189
   }
188 190
 
189 191
   report_current_position();
192
+
193
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
190 194
 }
191 195
 
192 196
 #endif // MESH_BED_LEVELING

+ 12
- 1
Marlin/src/gcode/bedlevel/ubl/G29.cpp Parādīt failu

@@ -31,6 +31,17 @@
31 31
 #include "../../gcode.h"
32 32
 #include "../../../feature/bedlevel/bedlevel.h"
33 33
 
34
-void GcodeSuite::G29() { ubl.G29(); }
34
+#if ENABLED(FULL_REPORT_TO_HOST_FEATURE)
35
+  #include "../../../module/motion.h"
36
+#endif
37
+
38
+void GcodeSuite::G29() {
39
+
40
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));
41
+
42
+  ubl.G29();
43
+
44
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
45
+}
35 46
 
36 47
 #endif // AUTO_BED_LEVELING_UBL

+ 4
- 0
Marlin/src/gcode/calibrate/G28.cpp Parādīt failu

@@ -211,6 +211,8 @@ void GcodeSuite::G28() {
211 211
 
212 212
   TERN_(LASER_MOVE_G28_OFF, cutter.set_inline_enabled(false));  // turn off laser
213 213
 
214
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOMING));
215
+
214 216
   #if ENABLED(DUAL_X_CARRIAGE)
215 217
     bool IDEX_saved_duplication_state = extruder_duplication_enabled;
216 218
     DualXMode IDEX_saved_mode = dual_x_carriage_mode;
@@ -479,6 +481,8 @@ void GcodeSuite::G28() {
479 481
   if (ENABLED(NANODLP_Z_SYNC) && (doZ || ENABLED(NANODLP_ALL_AXIS)))
480 482
     SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
481 483
 
484
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
485
+
482 486
   #if HAS_L64XX
483 487
     // Set L6470 absolute position registers to counts
484 488
     // constexpr *might* move this to PROGMEM.

+ 4
- 0
Marlin/src/gcode/calibrate/G33.cpp Parādīt failu

@@ -387,6 +387,8 @@ static float auto_tune_a() {
387 387
  */
388 388
 void GcodeSuite::G33() {
389 389
 
390
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_PROBE));
391
+
390 392
   const int8_t probe_points = parser.intval('P', DELTA_CALIBRATION_DEFAULT_POINTS);
391 393
   if (!WITHIN(probe_points, 0, 10)) {
392 394
     SERIAL_ECHOLNPGM("?(P)oints implausible (0-10).");
@@ -645,6 +647,8 @@ void GcodeSuite::G33() {
645 647
   while (((zero_std_dev < test_precision && iterations < 31) || iterations <= force_iterations) && zero_std_dev > calibration_precision);
646 648
 
647 649
   ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
650
+
651
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
648 652
 }
649 653
 
650 654
 #endif // DELTA_AUTO_CALIBRATION

+ 10
- 1
Marlin/src/gcode/gcode.cpp Parādīt failu

@@ -289,8 +289,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
289 289
     }
290 290
   #endif
291 291
 
292
-  // Handle a known G, M, or T
292
+  // Handle a known command or reply "unknown command"
293
+
293 294
   switch (parser.command_letter) {
295
+
294 296
     case 'G': switch (parser.codenum) {
295 297
 
296 298
       case 0: case 1:                                             // G0: Fast Move, G1: Linear Move
@@ -995,6 +997,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
995 997
       case 'D': D(parser.codenum); break;                         // Dn: Debug codes
996 998
     #endif
997 999
 
1000
+    #if ENABLED(REALTIME_REPORTING_COMMANDS)
1001
+      case 'S': case 'P': case 'R': break;                        // Invalid S, P, R commands already filtered
1002
+    #endif
1003
+
998 1004
     default:
999 1005
       #if ENABLED(WIFI_CUSTOM_COMMAND)
1000 1006
         if (wifi_custom_command(parser.command_ptr)) break;
@@ -1087,12 +1093,15 @@ void GcodeSuite::process_subcommands_now(char * gcode) {
1087 1093
         case IN_HANDLER:
1088 1094
         case IN_PROCESS:
1089 1095
           SERIAL_ECHO_MSG(STR_BUSY_PROCESSING);
1096
+          TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_position_moving());
1090 1097
           break;
1091 1098
         case PAUSED_FOR_USER:
1092 1099
           SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_USER);
1100
+          TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD));
1093 1101
           break;
1094 1102
         case PAUSED_FOR_INPUT:
1095 1103
           SERIAL_ECHO_MSG(STR_BUSY_PAUSED_FOR_INPUT);
1104
+          TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD));
1096 1105
           break;
1097 1106
         default:
1098 1107
           break;

+ 4
- 0
Marlin/src/gcode/host/M114.cpp Parādīt failu

@@ -176,6 +176,8 @@
176 176
     const xyze_float_t diff = from_steppers - leveled;
177 177
     SERIAL_ECHOPGM("Diff:   ");
178 178
     report_xyze(diff);
179
+
180
+    TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
179 181
   }
180 182
 
181 183
 #endif // M114_DETAIL
@@ -211,4 +213,6 @@ void GcodeSuite::M114() {
211 213
 
212 214
   TERN_(M114_LEGACY, planner.synchronize());
213 215
   report_current_position_projected();
216
+
217
+  TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
214 218
 }

+ 4
- 0
Marlin/src/gcode/motion/G0_G1.cpp Parādīt failu

@@ -54,6 +54,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
54 54
         | (parser.seen('Z') ? _BV(Z_AXIS) : 0) )
55 55
     #endif
56 56
   ) {
57
+    TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));
57 58
 
58 59
     #ifdef G0_FEEDRATE
59 60
       feedRate_t old_feedrate;
@@ -116,6 +117,9 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
116 117
         planner.synchronize();
117 118
         SERIAL_ECHOLNPGM(STR_Z_MOVE_COMP);
118 119
       }
120
+      TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
121
+    #else
122
+      TERN_(FULL_REPORT_TO_HOST_FEATURE, report_current_grblstate_moving());
119 123
     #endif
120 124
   }
121 125
 }

+ 4
- 0
Marlin/src/gcode/motion/G2_G3.cpp Parādīt failu

@@ -306,6 +306,8 @@ void plan_arc(
306 306
 void GcodeSuite::G2_G3(const bool clockwise) {
307 307
   if (MOTION_CONDITIONS) {
308 308
 
309
+    TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_RUNNING));
310
+
309 311
     #if ENABLED(SF_ARC_FIX)
310 312
       const bool relative_mode_backup = relative_mode;
311 313
       relative_mode = true;
@@ -364,6 +366,8 @@ void GcodeSuite::G2_G3(const bool clockwise) {
364 366
     }
365 367
     else
366 368
       SERIAL_ERROR_MSG(STR_ERR_ARC_ARGS);
369
+
370
+    TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
367 371
   }
368 372
 }
369 373
 

+ 18
- 5
Marlin/src/gcode/parser.cpp Parādīt failu

@@ -106,8 +106,10 @@ void GCodeParser::reset() {
106 106
 
107 107
 #endif
108 108
 
109
-// Populate all fields by parsing a single line of GCode
110
-// 58 bytes of SRAM are used to speed up seen/value
109
+/**
110
+ * Populate the command line state (command_letter, codenum, subcode, and string_arg)
111
+ * by parsing a single line of GCode. 58 bytes of SRAM are used to speed up seen/value.
112
+ */
111 113
 void GCodeParser::parse(char *p) {
112 114
 
113 115
   reset(); // No codes to report
@@ -147,10 +149,12 @@ void GCodeParser::parse(char *p) {
147 149
     #define SIGNED_CODENUM 1
148 150
   #endif
149 151
 
150
-  // Bail if the letter is not G, M, or T
151
-  // (or a valid parameter for the current motion mode)
152
+  /**
153
+   * Screen for good command letters. G, M, and T are always accepted.
154
+   * With Motion Modes enabled any axis letter can come first.
155
+   * With Realtime Reporting, commands S000, P000, and R000 are allowed.
156
+   */
152 157
   switch (letter) {
153
-
154 158
     case 'G': case 'M': case 'T': TERN_(MARLIN_DEV_MODE, case 'D':)
155 159
       // Skip spaces to get the numeric part
156 160
       while (*p == ' ') p++;
@@ -227,6 +231,15 @@ void GCodeParser::parse(char *p) {
227 231
       break;
228 232
     #endif // GCODE_MOTION_MODES
229 233
 
234
+    #if ENABLED(REALTIME_REPORTING_COMMANDS)
235
+      case 'S': case 'P': case 'R': {
236
+        codenum = 0;                  // The only valid codenum is 0
237
+        uint8_t digits = 0;
238
+        while (*p++ == '0') digits++; // Count up '0' characters
239
+        command_letter = (digits == 3) ? letter : '?'; // Three '0' digits is a good command
240
+      } return;                       // No parameters, so return
241
+    #endif
242
+
230 243
     default: return;
231 244
   }
232 245
 

+ 58
- 0
Marlin/src/module/motion.cpp Parādīt failu

@@ -230,6 +230,50 @@ void report_current_position_projected() {
230 230
   stepper.report_a_position(planner.position);
231 231
 }
232 232
 
233
+#if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS)
234
+
235
+  M_StateEnum M_State_grbl = M_INIT;
236
+
237
+  /**
238
+   * Output the current grbl compatible state to serial while moving
239
+   */
240
+  void report_current_grblstate_moving() { SERIAL_ECHOLNPAIR("S_XYZ:", int(M_State_grbl)); }
241
+
242
+  /**
243
+   * Output the current position (processed) to serial while moving
244
+   */
245
+  void report_current_position_moving() {
246
+
247
+    get_cartesian_from_steppers();
248
+    const xyz_pos_t lpos = cartes.asLogical();
249
+    SERIAL_ECHOPAIR("X:", lpos.x, " Y:", lpos.y, " Z:", lpos.z, " E:", current_position.e);
250
+
251
+    stepper.report_positions();
252
+    #if IS_SCARA
253
+      scara_report_positions();
254
+    #endif
255
+
256
+    report_current_grblstate_moving();
257
+  }
258
+
259
+  /**
260
+   * Set a Grbl-compatible state from the current marlin_state
261
+   */
262
+  M_StateEnum grbl_state_for_marlin_state() {
263
+    switch (marlin_state) {
264
+      case MF_INITIALIZING: return M_INIT;
265
+      case MF_SD_COMPLETE:  return M_ALARM;
266
+      case MF_WAITING:      return M_IDLE;
267
+      case MF_STOPPED:      return M_END;
268
+      case MF_RUNNING:      return M_RUNNING;
269
+      case MF_PAUSED:       return M_HOLD;
270
+      case MF_KILLED:       return M_ERROR;
271
+      default:              return M_IDLE;
272
+    }
273
+  }
274
+
275
+#endif
276
+
233 277
 /**
234 278
  * Run out the planner buffer and re-sync the current
235 279
  * position from the last-updated stepper positions.
@@ -241,6 +285,20 @@ void quickstop_stepper() {
241 285
   sync_plan_position();
242 286
 }
243 287
 
288
+#if ENABLED(REALTIME_REPORTING_COMMANDS)
289
+
290
+  void quickpause_stepper() {
291
+    planner.quick_pause();
292
+    //planner.synchronize();
293
+  }
294
+
295
+  void quickresume_stepper() {
296
+    planner.quick_resume();
297
+    //planner.synchronize();
298
+  }
299
+
300
+#endif
301
+
244 302
 /**
245 303
  * Set the planner/stepper positions directly from current_position with
246 304
  * no kinematic translation. Used for homing axes and cartesian/core syncing.

+ 37
- 2
Marlin/src/module/motion.h Parādīt failu

@@ -211,14 +211,49 @@ void report_real_position();
211 211
 void report_current_position();
212 212
 void report_current_position_projected();
213 213
 
214
+#if EITHER(FULL_REPORT_TO_HOST_FEATURE, REALTIME_REPORTING_COMMANDS)
215
+  #define HAS_GRBL_STATE 1
216
+  /**
217
+   * Machine states for GRBL or TinyG
218
+   */
219
+  enum M_StateEnum : uint8_t {
220
+    M_INIT = 0, //  0 machine is initializing
221
+    M_RESET,    //  1 machine is ready for use
222
+    M_ALARM,    //  2 machine is in alarm state (soft shut down)
223
+    M_IDLE,     //  3 program stop or no more blocks (M0, M1, M60)
224
+    M_END,      //  4 program end via M2, M30
225
+    M_RUNNING,  //  5 motion is running
226
+    M_HOLD,     //  6 motion is holding
227
+    M_PROBE,    //  7 probe cycle active
228
+    M_CYCLING,  //  8 machine is running (cycling)
229
+    M_HOMING,   //  9 machine is homing
230
+    M_JOGGING,  // 10 machine is jogging
231
+    M_ERROR     // 11 machine is in hard alarm state (shut down)
232
+  };
233
+  extern M_StateEnum M_State_grbl;
234
+  M_StateEnum grbl_state_for_marlin_state();
235
+  void report_current_grblstate_moving();
236
+  void report_current_position_moving();
237
+
238
+  #if ENABLED(FULL_REPORT_TO_HOST_FEATURE)
239
+    inline void set_and_report_grblstate(const M_StateEnum state) {
240
+      M_State_grbl = state;
241
+      report_current_grblstate_moving();
242
+    }
243
+  #endif
244
+
245
+  #if ENABLED(REALTIME_REPORTING_COMMANDS)
246
+    void quickpause_stepper();
247
+    void quickresume_stepper();
248
+  #endif
249
+#endif
250
+
214 251
 void get_cartesian_from_steppers();
215 252
 void set_current_from_steppers_for_axis(const AxisEnum axis);
216 253
 
217 254
 void quickstop_stepper();
218 255
 
219 256
 /**
220
- * sync_plan_position
221
- *
222 257
  * Set the planner/stepper positions directly from current_position with
223 258
  * no kinematic translation. Used for homing axes and cartesian/core syncing.
224 259
  */

+ 18
- 0
Marlin/src/module/planner.cpp Parādīt failu

@@ -1650,6 +1650,24 @@ void Planner::quick_stop() {
1650 1650
   stepper.quick_stop();
1651 1651
 }
1652 1652
 
1653
+#if ENABLED(REALTIME_REPORTING_COMMANDS)
1654
+
1655
+  void Planner::quick_pause() {
1656
+    // Suspend until quick_resume is called
1657
+    // Don't empty buffers or queues
1658
+    const bool did_suspend = stepper.suspend();
1659
+    if (did_suspend)
1660
+      TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_HOLD));
1661
+  }
1662
+
1663
+  // Resume if suspended
1664
+  void Planner::quick_resume() {
1665
+    TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(grbl_state_for_marlin_state()));
1666
+    stepper.wake_up();
1667
+  }
1668
+
1669
+#endif
1670
+
1653 1671
 void Planner::endstop_triggered(const AxisEnum axis) {
1654 1672
   // Record stepper position and discard the current block
1655 1673
   stepper.endstop_triggered(axis);

+ 7
- 0
Marlin/src/module/planner.h Parādīt failu

@@ -873,6 +873,13 @@ class Planner {
873 873
     // a Full Shutdown is required, or when endstops are hit)
874 874
     static void quick_stop();
875 875
 
876
+    #if ENABLED(REALTIME_REPORTING_COMMANDS)
877
+      // Force a quick pause of the machine (e.g., when a pause is required in the middle of move).
878
+      // NOTE: Hard-stops will lose steps so encoders are highly recommended if using these!
879
+      static void quick_pause();
880
+      static void quick_resume();
881
+    #endif
882
+
876 883
     // Called when an endstop is triggered. Causes the machine to stop inmediately
877 884
     static void endstop_triggered(const AxisEnum axis);
878 885
 

+ 2
- 2
buildroot/tests/LPC1768 Parādīt failu

@@ -26,8 +26,8 @@ restore_configs
26 26
 opt_set MOTHERBOARD BOARD_MKS_SBASE \
27 27
         EXTRUDERS 2 TEMP_SENSOR_1 1 \
28 28
         NUM_SERVOS 2 SERVO_DELAY '{ 300, 300 }'
29
-opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR ULTIMAKERCONTROLLER
30
-exec_test $1 $2 "MKS SBASE with SWITCHING_NOZZLE" "$3"
29
+opt_enable SWITCHING_NOZZLE SWITCHING_NOZZLE_E1_SERVO_NR ULTIMAKERCONTROLLER REALTIME_REPORTING_COMMANDS FULL_REPORT_TO_HOST_FEATURE
30
+exec_test $1 $2 "MKS SBASE with SWITCHING_NOZZLE, Grbl Realtime Report" "$3"
31 31
 
32 32
 restore_configs
33 33
 opt_set MOTHERBOARD BOARD_RAMPS_14_RE_ARM_EEB \

Notiek ielāde…
Atcelt
Saglabāt