blob: 666608a36a759eca2d4556b34cd8e62fa2522470 [file] [log] [blame]
Luigi Santivetti69972f92019-11-12 22:55:40 +00001/*
2 report.c - reporting and messaging methods
3 Part of Grbl
4
5 Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC
6
7 Grbl is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Grbl is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Grbl. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21/*
22 This file functions as the primary feedback interface for Grbl. Any outgoing data, such
23 as the protocol status messages, feedback messages, and status reports, are stored here.
24 For the most part, these functions primarily are called from protocol.c methods. If a
25 different style feedback is desired (i.e. JSON), then a user can change these following
26 methods to accomodate their needs.
27*/
28
29#include "grbl.h"
30
31
32// Internal report utilities to reduce flash with repetitive tasks turned into functions.
33void report_util_setting_prefix(uint8_t n) { serial_write('$'); print_uint8_base10(n); serial_write('='); }
34static void report_util_line_feed() { printPgmString(PSTR("\r\n")); }
35static void report_util_feedback_line_feed() { serial_write(']'); report_util_line_feed(); }
36static void report_util_gcode_modes_G() { printPgmString(PSTR(" G")); }
37static void report_util_gcode_modes_M() { printPgmString(PSTR(" M")); }
38// static void report_util_comment_line_feed() { serial_write(')'); report_util_line_feed(); }
39static void report_util_axis_values(float *axis_value) {
40 uint8_t idx;
41 for (idx=0; idx<N_AXIS; idx++) {
42 printFloat_CoordValue(axis_value[idx]);
43 if (idx < (N_AXIS-1)) { serial_write(','); }
44 }
45}
46
47/*
48static void report_util_setting_string(uint8_t n) {
49 serial_write(' ');
50 serial_write('(');
51 switch(n) {
52 case 0: printPgmString(PSTR("stp pulse")); break;
53 case 1: printPgmString(PSTR("idl delay")); break;
54 case 2: printPgmString(PSTR("stp inv")); break;
55 case 3: printPgmString(PSTR("dir inv")); break;
56 case 4: printPgmString(PSTR("stp en inv")); break;
57 case 5: printPgmString(PSTR("lim inv")); break;
58 case 6: printPgmString(PSTR("prb inv")); break;
59 case 10: printPgmString(PSTR("rpt")); break;
60 case 11: printPgmString(PSTR("jnc dev")); break;
61 case 12: printPgmString(PSTR("arc tol")); break;
62 case 13: printPgmString(PSTR("rpt inch")); break;
63 case 20: printPgmString(PSTR("sft lim")); break;
64 case 21: printPgmString(PSTR("hrd lim")); break;
65 case 22: printPgmString(PSTR("hm cyc")); break;
66 case 23: printPgmString(PSTR("hm dir inv")); break;
67 case 24: printPgmString(PSTR("hm feed")); break;
68 case 25: printPgmString(PSTR("hm seek")); break;
69 case 26: printPgmString(PSTR("hm delay")); break;
70 case 27: printPgmString(PSTR("hm pulloff")); break;
71 case 30: printPgmString(PSTR("rpm max")); break;
72 case 31: printPgmString(PSTR("rpm min")); break;
73 case 32: printPgmString(PSTR("laser")); break;
74 default:
75 n -= AXIS_SETTINGS_START_VAL;
76 uint8_t idx = 0;
77 while (n >= AXIS_SETTINGS_INCREMENT) {
78 n -= AXIS_SETTINGS_INCREMENT;
79 idx++;
80 }
81 serial_write(n+'x');
82 switch (idx) {
83 case 0: printPgmString(PSTR(":stp/mm")); break;
84 case 1: printPgmString(PSTR(":mm/min")); break;
85 case 2: printPgmString(PSTR(":mm/s^2")); break;
86 case 3: printPgmString(PSTR(":mm max")); break;
87 }
88 break;
89 }
90 report_util_comment_line_feed();
91}
92*/
93
94static void report_util_uint8_setting(uint8_t n, int val) {
95 report_util_setting_prefix(n);
96 print_uint8_base10(val);
97 report_util_line_feed(); // report_util_setting_string(n);
98}
99static void report_util_float_setting(uint8_t n, float val, uint8_t n_decimal) {
100 report_util_setting_prefix(n);
101 printFloat(val,n_decimal);
102 report_util_line_feed(); // report_util_setting_string(n);
103}
104
105
106// Handles the primary confirmation protocol response for streaming interfaces and human-feedback.
107// For every incoming line, this method responds with an 'ok' for a successful command or an
108// 'error:' to indicate some error event with the line or some critical system error during
109// operation. Errors events can originate from the g-code parser, settings module, or asynchronously
110// from a critical error, such as a triggered hard limit. Interface should always monitor for these
111// responses.
112void report_status_message(uint8_t status_code)
113{
114 switch(status_code) {
115 case STATUS_OK: // STATUS_OK
116 printPgmString(PSTR("ok\r\n")); break;
117 default:
118 printPgmString(PSTR("error:"));
119 print_uint8_base10(status_code);
120 report_util_line_feed();
121 }
122}
123
124// Prints alarm messages.
125void report_alarm_message(uint8_t alarm_code)
126{
127 printPgmString(PSTR("ALARM:"));
128 print_uint8_base10(alarm_code);
129 report_util_line_feed();
130 delay_ms(500); // Force delay to ensure message clears serial write buffer.
131}
132
133// Prints feedback messages. This serves as a centralized method to provide additional
134// user feedback for things that are not of the status/alarm message protocol. These are
135// messages such as setup warnings, switch toggling, and how to exit alarms.
136// NOTE: For interfaces, messages are always placed within brackets. And if silent mode
137// is installed, the message number codes are less than zero.
138void report_feedback_message(uint8_t message_code)
139{
140 printPgmString(PSTR("[MSG:"));
141 switch(message_code) {
142 case MESSAGE_CRITICAL_EVENT:
143 printPgmString(PSTR("Reset to continue")); break;
144 case MESSAGE_ALARM_LOCK:
145 printPgmString(PSTR("'$H'|'$X' to unlock")); break;
146 case MESSAGE_ALARM_UNLOCK:
147 printPgmString(PSTR("Caution: Unlocked")); break;
148 case MESSAGE_ENABLED:
149 printPgmString(PSTR("Enabled")); break;
150 case MESSAGE_DISABLED:
151 printPgmString(PSTR("Disabled")); break;
152 case MESSAGE_SAFETY_DOOR_AJAR:
153 printPgmString(PSTR("Check Door")); break;
154 case MESSAGE_CHECK_LIMITS:
155 printPgmString(PSTR("Check Limits")); break;
156 case MESSAGE_PROGRAM_END:
157 printPgmString(PSTR("Pgm End")); break;
158 case MESSAGE_RESTORE_DEFAULTS:
159 printPgmString(PSTR("Restoring defaults")); break;
160 case MESSAGE_SPINDLE_RESTORE:
161 printPgmString(PSTR("Restoring spindle")); break;
162 case MESSAGE_SLEEP_MODE:
163 printPgmString(PSTR("Sleeping")); break;
164 }
165 report_util_feedback_line_feed();
166}
167
168
169// Welcome message
170void report_init_message()
171{
172 printPgmString(PSTR("\r\nGrbl " GRBL_VERSION " ['$' for help]\r\n"));
173}
174
175// Grbl help message
176void report_grbl_help() {
177 printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]\r\n"));
178}
179
180
181// Grbl global settings print out.
182// NOTE: The numbering scheme here must correlate to storing in settings.c
183void report_grbl_settings() {
184 // Print Grbl settings.
185 report_util_uint8_setting(0,settings.pulse_microseconds);
186 report_util_uint8_setting(1,settings.stepper_idle_lock_time);
187 report_util_uint8_setting(2,settings.step_invert_mask);
188 report_util_uint8_setting(3,settings.dir_invert_mask);
189 report_util_uint8_setting(4,bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
190 report_util_uint8_setting(5,bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS));
191 report_util_uint8_setting(6,bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN));
192 report_util_uint8_setting(10,settings.status_report_mask);
193 report_util_float_setting(11,settings.junction_deviation,N_DECIMAL_SETTINGVALUE);
194 report_util_float_setting(12,settings.arc_tolerance,N_DECIMAL_SETTINGVALUE);
195 report_util_uint8_setting(13,bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
196 report_util_uint8_setting(20,bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
197 report_util_uint8_setting(21,bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
198 report_util_uint8_setting(22,bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
199 report_util_uint8_setting(23,settings.homing_dir_mask);
200 report_util_float_setting(24,settings.homing_feed_rate,N_DECIMAL_SETTINGVALUE);
201 report_util_float_setting(25,settings.homing_seek_rate,N_DECIMAL_SETTINGVALUE);
202 report_util_uint8_setting(26,settings.homing_debounce_delay);
203 report_util_float_setting(27,settings.homing_pulloff,N_DECIMAL_SETTINGVALUE);
204 report_util_float_setting(30,settings.rpm_max,N_DECIMAL_RPMVALUE);
205 report_util_float_setting(31,settings.rpm_min,N_DECIMAL_RPMVALUE);
206 #ifdef VARIABLE_SPINDLE
207 report_util_uint8_setting(32,bit_istrue(settings.flags,BITFLAG_LASER_MODE));
208 #else
209 report_util_uint8_setting(32,0);
210 #endif
211 // Print axis settings
212 uint8_t idx, set_idx;
213 uint8_t val = AXIS_SETTINGS_START_VAL;
214 for (set_idx=0; set_idx<AXIS_N_SETTINGS; set_idx++) {
215 for (idx=0; idx<N_AXIS; idx++) {
216 switch (set_idx) {
217 case 0: report_util_float_setting(val+idx,settings.steps_per_mm[idx],N_DECIMAL_SETTINGVALUE); break;
218 case 1: report_util_float_setting(val+idx,settings.max_rate[idx],N_DECIMAL_SETTINGVALUE); break;
219 case 2: report_util_float_setting(val+idx,settings.acceleration[idx]/(60*60),N_DECIMAL_SETTINGVALUE); break;
220 case 3: report_util_float_setting(val+idx,-settings.max_travel[idx],N_DECIMAL_SETTINGVALUE); break;
221 }
222 }
223 val += AXIS_SETTINGS_INCREMENT;
224 }
225}
226
227
228// Prints current probe parameters. Upon a probe command, these parameters are updated upon a
229// successful probe or upon a failed probe with the G38.3 without errors command (if supported).
230// These values are retained until Grbl is power-cycled, whereby they will be re-zeroed.
231void report_probe_parameters()
232{
233 // Report in terms of machine position.
234 printPgmString(PSTR("[PRB:"));
235 float print_position[N_AXIS];
236 system_convert_array_steps_to_mpos(print_position,sys_probe_position);
237 report_util_axis_values(print_position);
238 serial_write(':');
239 print_uint8_base10(sys.probe_succeeded);
240 report_util_feedback_line_feed();
241}
242
243
244// Prints Grbl NGC parameters (coordinate offsets, probing)
245void report_ngc_parameters()
246{
247 float coord_data[N_AXIS];
248 uint8_t coord_select;
249 for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
250 if (!(settings_read_coord_data(coord_select,coord_data))) {
251 report_status_message(STATUS_SETTING_READ_FAIL);
252 return;
253 }
254 printPgmString(PSTR("[G"));
255 switch (coord_select) {
256 case 6: printPgmString(PSTR("28")); break;
257 case 7: printPgmString(PSTR("30")); break;
258 default: print_uint8_base10(coord_select+54); break; // G54-G59
259 }
260 serial_write(':');
261 report_util_axis_values(coord_data);
262 report_util_feedback_line_feed();
263 }
264 printPgmString(PSTR("[G92:")); // Print G92,G92.1 which are not persistent in memory
265 report_util_axis_values(gc_state.coord_offset);
266 report_util_feedback_line_feed();
267 printPgmString(PSTR("[TLO:")); // Print tool length offset value
268 printFloat_CoordValue(gc_state.tool_length_offset);
269 report_util_feedback_line_feed();
270 report_probe_parameters(); // Print probe parameters. Not persistent in memory.
271}
272
273
274// Print current gcode parser mode state
275void report_gcode_modes()
276{
277 printPgmString(PSTR("[GC:G"));
278 if (gc_state.modal.motion >= MOTION_MODE_PROBE_TOWARD) {
279 printPgmString(PSTR("38."));
280 print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2));
281 } else {
282 print_uint8_base10(gc_state.modal.motion);
283 }
284
285 report_util_gcode_modes_G();
286 print_uint8_base10(gc_state.modal.coord_select+54);
287
288 report_util_gcode_modes_G();
289 print_uint8_base10(gc_state.modal.plane_select+17);
290
291 report_util_gcode_modes_G();
292 print_uint8_base10(21-gc_state.modal.units);
293
294 report_util_gcode_modes_G();
295 print_uint8_base10(gc_state.modal.distance+90);
296
297 report_util_gcode_modes_G();
298 print_uint8_base10(94-gc_state.modal.feed_rate);
299
300 if (gc_state.modal.program_flow) {
301 report_util_gcode_modes_M();
302 switch (gc_state.modal.program_flow) {
303 case PROGRAM_FLOW_PAUSED : serial_write('0'); break;
304 // case PROGRAM_FLOW_OPTIONAL_STOP : serial_write('1'); break; // M1 is ignored and not supported.
305 case PROGRAM_FLOW_COMPLETED_M2 :
306 case PROGRAM_FLOW_COMPLETED_M30 :
307 print_uint8_base10(gc_state.modal.program_flow);
308 break;
309 }
310 }
311
312 report_util_gcode_modes_M();
313 switch (gc_state.modal.spindle) {
314 case SPINDLE_ENABLE_CW : serial_write('3'); break;
315 case SPINDLE_ENABLE_CCW : serial_write('4'); break;
316 case SPINDLE_DISABLE : serial_write('5'); break;
317 }
318
319 #ifdef ENABLE_M7
320 if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time.
321 if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { report_util_gcode_modes_M(); serial_write('7'); }
322 if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { report_util_gcode_modes_M(); serial_write('8'); }
323 } else { report_util_gcode_modes_M(); serial_write('9'); }
324 #else
325 report_util_gcode_modes_M();
326 if (gc_state.modal.coolant) { serial_write('8'); }
327 else { serial_write('9'); }
328 #endif
329
330 #ifdef ENABLE_PARKING_OVERRIDE_CONTROL
331 if (sys.override_ctrl == OVERRIDE_PARKING_MOTION) {
332 report_util_gcode_modes_M();
333 print_uint8_base10(56);
334 }
335 #endif
336
337 printPgmString(PSTR(" T"));
338 print_uint8_base10(gc_state.tool);
339
340 printPgmString(PSTR(" F"));
341 printFloat_RateValue(gc_state.feed_rate);
342
343 #ifdef VARIABLE_SPINDLE
344 printPgmString(PSTR(" S"));
345 printFloat(gc_state.spindle_speed,N_DECIMAL_RPMVALUE);
346 #endif
347
348 report_util_feedback_line_feed();
349}
350
351// Prints specified startup line
352void report_startup_line(uint8_t n, char *line)
353{
354 printPgmString(PSTR("$N"));
355 print_uint8_base10(n);
356 serial_write('=');
357 printString(line);
358 report_util_line_feed();
359}
360
361void report_execute_startup_message(char *line, uint8_t status_code)
362{
363 serial_write('>');
364 printString(line);
365 serial_write(':');
366 report_status_message(status_code);
367}
368
369// Prints build info line
370void report_build_info(char *line)
371{
372 printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":"));
373 printString(line);
374 report_util_feedback_line_feed();
375 printPgmString(PSTR("[OPT:")); // Generate compile-time build option list
376 #ifdef VARIABLE_SPINDLE
377 serial_write('V');
378 #endif
379 #ifdef USE_LINE_NUMBERS
380 serial_write('N');
381 #endif
382 #ifdef ENABLE_M7
383 serial_write('M');
384 #endif
385 #ifdef COREXY
386 serial_write('C');
387 #endif
388 #ifdef PARKING_ENABLE
389 serial_write('P');
390 #endif
391 #ifdef HOMING_FORCE_SET_ORIGIN
392 serial_write('Z');
393 #endif
394 #ifdef HOMING_SINGLE_AXIS_COMMANDS
395 serial_write('H');
396 #endif
397 #ifdef LIMITS_TWO_SWITCHES_ON_AXES
398 serial_write('T');
399 #endif
400 #ifdef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES
401 serial_write('A');
402 #endif
403 #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
404 serial_write('D');
405 #endif
406 #ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED
407 serial_write('0');
408 #endif
409 #ifdef ENABLE_SOFTWARE_DEBOUNCE
410 serial_write('S');
411 #endif
412 #ifdef ENABLE_PARKING_OVERRIDE_CONTROL
413 serial_write('R');
414 #endif
415 #ifndef HOMING_INIT_LOCK
416 serial_write('L');
417 #endif
418 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
419 serial_write('+');
420 #endif
421 #ifndef ENABLE_RESTORE_EEPROM_WIPE_ALL // NOTE: Shown when disabled.
422 serial_write('*');
423 #endif
424 #ifndef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // NOTE: Shown when disabled.
425 serial_write('$');
426 #endif
427 #ifndef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // NOTE: Shown when disabled.
428 serial_write('#');
429 #endif
430 #ifndef ENABLE_BUILD_INFO_WRITE_COMMAND // NOTE: Shown when disabled.
431 serial_write('I');
432 #endif
433 #ifndef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // NOTE: Shown when disabled.
434 serial_write('E');
435 #endif
436 #ifndef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // NOTE: Shown when disabled.
437 serial_write('W');
438 #endif
439 #ifdef ENABLE_DUAL_AXIS
440 serial_write('2');
441 #endif
442 // NOTE: Compiled values, like override increments/max/min values, may be added at some point later.
443 serial_write(',');
444 print_uint8_base10(BLOCK_BUFFER_SIZE-1);
445 serial_write(',');
446 print_uint8_base10(RX_BUFFER_SIZE);
447
448 report_util_feedback_line_feed();
449}
450
451
452// Prints the character string line Grbl has received from the user, which has been pre-parsed,
453// and has been sent into protocol_execute_line() routine to be executed by Grbl.
454void report_echo_line_received(char *line)
455{
456 printPgmString(PSTR("[echo: ")); printString(line);
457 report_util_feedback_line_feed();
458}
459
460
461 // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram
462 // and the actual location of the CNC machine. Users may change the following function to their
463 // specific needs, but the desired real-time data report must be as short as possible. This is
464 // requires as it minimizes the computational overhead and allows grbl to keep running smoothly,
465 // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
466void report_realtime_status()
467{
468 uint8_t idx;
469 int32_t current_position[N_AXIS]; // Copy current state of the system position variable
470 memcpy(current_position,sys_position,sizeof(sys_position));
471 float print_position[N_AXIS];
472 system_convert_array_steps_to_mpos(print_position,current_position);
473
474 // Report current machine state and sub-states
475 serial_write('<');
476 switch (sys.state) {
477 case STATE_IDLE: printPgmString(PSTR("Idle")); break;
478 case STATE_CYCLE: printPgmString(PSTR("Run")); break;
479 case STATE_HOLD:
480 if (!(sys.suspend & SUSPEND_JOG_CANCEL)) {
481 printPgmString(PSTR("Hold:"));
482 if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume
483 else { serial_write('1'); } // Actively holding
484 break;
485 } // Continues to print jog state during jog cancel.
486 case STATE_JOG: printPgmString(PSTR("Jog")); break;
487 case STATE_HOMING: printPgmString(PSTR("Home")); break;
488 case STATE_ALARM: printPgmString(PSTR("Alarm")); break;
489 case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break;
490 case STATE_SAFETY_DOOR:
491 printPgmString(PSTR("Door:"));
492 if (sys.suspend & SUSPEND_INITIATE_RESTORE) {
493 serial_write('3'); // Restoring
494 } else {
495 if (sys.suspend & SUSPEND_RETRACT_COMPLETE) {
496 if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) {
497 serial_write('1'); // Door ajar
498 } else {
499 serial_write('0');
500 } // Door closed and ready to resume
501 } else {
502 serial_write('2'); // Retracting
503 }
504 }
505 break;
506 case STATE_SLEEP: printPgmString(PSTR("Sleep")); break;
507 }
508
509 float wco[N_AXIS];
510 if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE) ||
511 (sys.report_wco_counter == 0) ) {
512 for (idx=0; idx< N_AXIS; idx++) {
513 // Apply work coordinate offsets and tool length offset to current position.
514 wco[idx] = gc_state.coord_system[idx]+gc_state.coord_offset[idx];
515 if (idx == TOOL_LENGTH_OFFSET_AXIS) { wco[idx] += gc_state.tool_length_offset; }
516 if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) {
517 print_position[idx] -= wco[idx];
518 }
519 }
520 }
521
522 // Report machine position
523 if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) {
524 printPgmString(PSTR("|MPos:"));
525 } else {
526 printPgmString(PSTR("|WPos:"));
527 }
528 report_util_axis_values(print_position);
529
530 // Returns planner and serial read buffer states.
531 #ifdef REPORT_FIELD_BUFFER_STATE
532 if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_BUFFER_STATE)) {
533 printPgmString(PSTR("|Bf:"));
534 print_uint8_base10(plan_get_block_buffer_available());
535 serial_write(',');
536 print_uint8_base10(serial_get_rx_buffer_available());
537 }
538 #endif
539
540 #ifdef USE_LINE_NUMBERS
541 #ifdef REPORT_FIELD_LINE_NUMBERS
542 // Report current line number
543 plan_block_t * cur_block = plan_get_current_block();
544 if (cur_block != NULL) {
545 uint32_t ln = cur_block->line_number;
546 if (ln > 0) {
547 printPgmString(PSTR("|Ln:"));
548 printInteger(ln);
549 }
550 }
551 #endif
552 #endif
553
554 // Report realtime feed speed
555 #ifdef REPORT_FIELD_CURRENT_FEED_SPEED
556 #ifdef VARIABLE_SPINDLE
557 printPgmString(PSTR("|FS:"));
558 printFloat_RateValue(st_get_realtime_rate());
559 serial_write(',');
560 printFloat(sys.spindle_speed,N_DECIMAL_RPMVALUE);
561 #else
562 printPgmString(PSTR("|F:"));
563 printFloat_RateValue(st_get_realtime_rate());
564 #endif
565 #endif
566
567 #ifdef REPORT_FIELD_PIN_STATE
568 uint8_t lim_pin_state = limits_get_state();
569 uint8_t ctrl_pin_state = system_control_get_state();
570 uint8_t prb_pin_state = probe_get_state();
571 if (lim_pin_state | ctrl_pin_state | prb_pin_state) {
572 printPgmString(PSTR("|Pn:"));
573 if (prb_pin_state) { serial_write('P'); }
574 if (lim_pin_state) {
575 #ifdef ENABLE_DUAL_AXIS
576 #if (DUAL_AXIS_SELECT == X_AXIS)
577 if (bit_istrue(lim_pin_state,(bit(X_AXIS)|bit(N_AXIS)))) { serial_write('X'); }
578 if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); }
579 #endif
580 #if (DUAL_AXIS_SELECT == Y_AXIS)
581 if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X');
582 if (bit_istrue(lim_pin_state,(bit(Y_AXIS)|bit(N_AXIS)))) { serial_write('Y'); }
583 #endif
584 if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); }
585 #else
586 if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X'); }
587 if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); }
588 if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); }
589 #endif
590 }
591 if (ctrl_pin_state) {
592 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
593 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_SAFETY_DOOR)) { serial_write('D'); }
594 #endif
595 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_RESET)) { serial_write('R'); }
596 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_FEED_HOLD)) { serial_write('H'); }
597 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_CYCLE_START)) { serial_write('S'); }
598 }
599 }
600 #endif
601
602 #ifdef REPORT_FIELD_WORK_COORD_OFFSET
603 if (sys.report_wco_counter > 0) { sys.report_wco_counter--; }
604 else {
605 if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
606 sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh
607 } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT-1); }
608 if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report.
609 printPgmString(PSTR("|WCO:"));
610 report_util_axis_values(wco);
611 }
612 #endif
613
614 #ifdef REPORT_FIELD_OVERRIDES
615 if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; }
616 else {
617 if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
618 sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh
619 } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT-1); }
620 printPgmString(PSTR("|Ov:"));
621 print_uint8_base10(sys.f_override);
622 serial_write(',');
623 print_uint8_base10(sys.r_override);
624 serial_write(',');
625 print_uint8_base10(sys.spindle_speed_ovr);
626
627 uint8_t sp_state = spindle_get_state();
628 uint8_t cl_state = coolant_get_state();
629 if (sp_state || cl_state) {
630 printPgmString(PSTR("|A:"));
631 if (sp_state) { // != SPINDLE_STATE_DISABLE
632 #ifdef VARIABLE_SPINDLE
633 #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
634 serial_write('S'); // CW
635 #else
636 if (sp_state == SPINDLE_STATE_CW) { serial_write('S'); } // CW
637 else { serial_write('C'); } // CCW
638 #endif
639 #else
640 if (sp_state & SPINDLE_STATE_CW) { serial_write('S'); } // CW
641 else { serial_write('C'); } // CCW
642 #endif
643 }
644 if (cl_state & COOLANT_STATE_FLOOD) { serial_write('F'); }
645 #ifdef ENABLE_M7
646 if (cl_state & COOLANT_STATE_MIST) { serial_write('M'); }
647 #endif
648 }
649 }
650 #endif
651
652 serial_write('>');
653 report_util_line_feed();
654}
655
656
657#ifdef DEBUG
658 void report_realtime_debug()
659 {
660
661 }
662#endif