blob: 414d215721ad4043a911c8319f10415856abe3cc [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
Luigi Santivetti42a1b332019-11-17 22:31:46 +0000211 #ifdef USE_ADC
212 report_util_uint8_setting(33,bit_istrue(settings.flags,BITFLAG_ADC_ENABLE));
213 #endif
Luigi Santivetti69972f92019-11-12 22:55:40 +0000214 // Print axis settings
215 uint8_t idx, set_idx;
216 uint8_t val = AXIS_SETTINGS_START_VAL;
217 for (set_idx=0; set_idx<AXIS_N_SETTINGS; set_idx++) {
218 for (idx=0; idx<N_AXIS; idx++) {
219 switch (set_idx) {
220 case 0: report_util_float_setting(val+idx,settings.steps_per_mm[idx],N_DECIMAL_SETTINGVALUE); break;
221 case 1: report_util_float_setting(val+idx,settings.max_rate[idx],N_DECIMAL_SETTINGVALUE); break;
222 case 2: report_util_float_setting(val+idx,settings.acceleration[idx]/(60*60),N_DECIMAL_SETTINGVALUE); break;
223 case 3: report_util_float_setting(val+idx,-settings.max_travel[idx],N_DECIMAL_SETTINGVALUE); break;
224 }
225 }
226 val += AXIS_SETTINGS_INCREMENT;
227 }
228}
229
230
231// Prints current probe parameters. Upon a probe command, these parameters are updated upon a
232// successful probe or upon a failed probe with the G38.3 without errors command (if supported).
233// These values are retained until Grbl is power-cycled, whereby they will be re-zeroed.
234void report_probe_parameters()
235{
236 // Report in terms of machine position.
237 printPgmString(PSTR("[PRB:"));
238 float print_position[N_AXIS];
239 system_convert_array_steps_to_mpos(print_position,sys_probe_position);
240 report_util_axis_values(print_position);
241 serial_write(':');
242 print_uint8_base10(sys.probe_succeeded);
243 report_util_feedback_line_feed();
244}
245
246
247// Prints Grbl NGC parameters (coordinate offsets, probing)
248void report_ngc_parameters()
249{
250 float coord_data[N_AXIS];
251 uint8_t coord_select;
252 for (coord_select = 0; coord_select <= SETTING_INDEX_NCOORD; coord_select++) {
253 if (!(settings_read_coord_data(coord_select,coord_data))) {
254 report_status_message(STATUS_SETTING_READ_FAIL);
255 return;
256 }
257 printPgmString(PSTR("[G"));
258 switch (coord_select) {
259 case 6: printPgmString(PSTR("28")); break;
260 case 7: printPgmString(PSTR("30")); break;
261 default: print_uint8_base10(coord_select+54); break; // G54-G59
262 }
263 serial_write(':');
264 report_util_axis_values(coord_data);
265 report_util_feedback_line_feed();
266 }
267 printPgmString(PSTR("[G92:")); // Print G92,G92.1 which are not persistent in memory
268 report_util_axis_values(gc_state.coord_offset);
269 report_util_feedback_line_feed();
270 printPgmString(PSTR("[TLO:")); // Print tool length offset value
271 printFloat_CoordValue(gc_state.tool_length_offset);
272 report_util_feedback_line_feed();
273 report_probe_parameters(); // Print probe parameters. Not persistent in memory.
274}
275
276
277// Print current gcode parser mode state
278void report_gcode_modes()
279{
280 printPgmString(PSTR("[GC:G"));
281 if (gc_state.modal.motion >= MOTION_MODE_PROBE_TOWARD) {
282 printPgmString(PSTR("38."));
283 print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2));
284 } else {
285 print_uint8_base10(gc_state.modal.motion);
286 }
287
288 report_util_gcode_modes_G();
289 print_uint8_base10(gc_state.modal.coord_select+54);
290
291 report_util_gcode_modes_G();
292 print_uint8_base10(gc_state.modal.plane_select+17);
293
294 report_util_gcode_modes_G();
295 print_uint8_base10(21-gc_state.modal.units);
296
297 report_util_gcode_modes_G();
298 print_uint8_base10(gc_state.modal.distance+90);
299
300 report_util_gcode_modes_G();
301 print_uint8_base10(94-gc_state.modal.feed_rate);
302
303 if (gc_state.modal.program_flow) {
304 report_util_gcode_modes_M();
305 switch (gc_state.modal.program_flow) {
306 case PROGRAM_FLOW_PAUSED : serial_write('0'); break;
307 // case PROGRAM_FLOW_OPTIONAL_STOP : serial_write('1'); break; // M1 is ignored and not supported.
308 case PROGRAM_FLOW_COMPLETED_M2 :
309 case PROGRAM_FLOW_COMPLETED_M30 :
310 print_uint8_base10(gc_state.modal.program_flow);
311 break;
312 }
313 }
314
315 report_util_gcode_modes_M();
316 switch (gc_state.modal.spindle) {
317 case SPINDLE_ENABLE_CW : serial_write('3'); break;
318 case SPINDLE_ENABLE_CCW : serial_write('4'); break;
319 case SPINDLE_DISABLE : serial_write('5'); break;
320 }
321
322 #ifdef ENABLE_M7
323 if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time.
324 if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { report_util_gcode_modes_M(); serial_write('7'); }
325 if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { report_util_gcode_modes_M(); serial_write('8'); }
326 } else { report_util_gcode_modes_M(); serial_write('9'); }
327 #else
328 report_util_gcode_modes_M();
329 if (gc_state.modal.coolant) { serial_write('8'); }
330 else { serial_write('9'); }
331 #endif
332
333 #ifdef ENABLE_PARKING_OVERRIDE_CONTROL
334 if (sys.override_ctrl == OVERRIDE_PARKING_MOTION) {
335 report_util_gcode_modes_M();
336 print_uint8_base10(56);
337 }
338 #endif
339
340 printPgmString(PSTR(" T"));
341 print_uint8_base10(gc_state.tool);
342
343 printPgmString(PSTR(" F"));
344 printFloat_RateValue(gc_state.feed_rate);
345
346 #ifdef VARIABLE_SPINDLE
347 printPgmString(PSTR(" S"));
348 printFloat(gc_state.spindle_speed,N_DECIMAL_RPMVALUE);
349 #endif
350
351 report_util_feedback_line_feed();
352}
353
354// Prints specified startup line
355void report_startup_line(uint8_t n, char *line)
356{
357 printPgmString(PSTR("$N"));
358 print_uint8_base10(n);
359 serial_write('=');
360 printString(line);
361 report_util_line_feed();
362}
363
364void report_execute_startup_message(char *line, uint8_t status_code)
365{
366 serial_write('>');
367 printString(line);
368 serial_write(':');
369 report_status_message(status_code);
370}
371
372// Prints build info line
373void report_build_info(char *line)
374{
375 printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":"));
376 printString(line);
377 report_util_feedback_line_feed();
378 printPgmString(PSTR("[OPT:")); // Generate compile-time build option list
379 #ifdef VARIABLE_SPINDLE
380 serial_write('V');
381 #endif
382 #ifdef USE_LINE_NUMBERS
383 serial_write('N');
384 #endif
385 #ifdef ENABLE_M7
386 serial_write('M');
387 #endif
388 #ifdef COREXY
389 serial_write('C');
390 #endif
391 #ifdef PARKING_ENABLE
392 serial_write('P');
393 #endif
394 #ifdef HOMING_FORCE_SET_ORIGIN
395 serial_write('Z');
396 #endif
397 #ifdef HOMING_SINGLE_AXIS_COMMANDS
398 serial_write('H');
399 #endif
400 #ifdef LIMITS_TWO_SWITCHES_ON_AXES
401 serial_write('T');
402 #endif
403 #ifdef ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES
404 serial_write('A');
405 #endif
406 #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
407 serial_write('D');
408 #endif
409 #ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED
410 serial_write('0');
411 #endif
412 #ifdef ENABLE_SOFTWARE_DEBOUNCE
413 serial_write('S');
414 #endif
415 #ifdef ENABLE_PARKING_OVERRIDE_CONTROL
416 serial_write('R');
417 #endif
418 #ifndef HOMING_INIT_LOCK
419 serial_write('L');
420 #endif
421 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
422 serial_write('+');
423 #endif
424 #ifndef ENABLE_RESTORE_EEPROM_WIPE_ALL // NOTE: Shown when disabled.
425 serial_write('*');
426 #endif
427 #ifndef ENABLE_RESTORE_EEPROM_DEFAULT_SETTINGS // NOTE: Shown when disabled.
428 serial_write('$');
429 #endif
430 #ifndef ENABLE_RESTORE_EEPROM_CLEAR_PARAMETERS // NOTE: Shown when disabled.
431 serial_write('#');
432 #endif
433 #ifndef ENABLE_BUILD_INFO_WRITE_COMMAND // NOTE: Shown when disabled.
434 serial_write('I');
435 #endif
436 #ifndef FORCE_BUFFER_SYNC_DURING_EEPROM_WRITE // NOTE: Shown when disabled.
437 serial_write('E');
438 #endif
439 #ifndef FORCE_BUFFER_SYNC_DURING_WCO_CHANGE // NOTE: Shown when disabled.
440 serial_write('W');
441 #endif
442 #ifdef ENABLE_DUAL_AXIS
443 serial_write('2');
444 #endif
Luigi Santivetti42a1b332019-11-17 22:31:46 +0000445 #ifdef USE_ADC
446 serial_write('@');
447 #endif
Luigi Santivetti69972f92019-11-12 22:55:40 +0000448 // NOTE: Compiled values, like override increments/max/min values, may be added at some point later.
449 serial_write(',');
450 print_uint8_base10(BLOCK_BUFFER_SIZE-1);
451 serial_write(',');
452 print_uint8_base10(RX_BUFFER_SIZE);
453
454 report_util_feedback_line_feed();
455}
456
457
458// Prints the character string line Grbl has received from the user, which has been pre-parsed,
459// and has been sent into protocol_execute_line() routine to be executed by Grbl.
460void report_echo_line_received(char *line)
461{
462 printPgmString(PSTR("[echo: ")); printString(line);
463 report_util_feedback_line_feed();
464}
465
466
467 // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram
468 // and the actual location of the CNC machine. Users may change the following function to their
469 // specific needs, but the desired real-time data report must be as short as possible. This is
470 // requires as it minimizes the computational overhead and allows grbl to keep running smoothly,
471 // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
472void report_realtime_status()
473{
474 uint8_t idx;
475 int32_t current_position[N_AXIS]; // Copy current state of the system position variable
476 memcpy(current_position,sys_position,sizeof(sys_position));
477 float print_position[N_AXIS];
478 system_convert_array_steps_to_mpos(print_position,current_position);
479
480 // Report current machine state and sub-states
481 serial_write('<');
482 switch (sys.state) {
483 case STATE_IDLE: printPgmString(PSTR("Idle")); break;
484 case STATE_CYCLE: printPgmString(PSTR("Run")); break;
485 case STATE_HOLD:
486 if (!(sys.suspend & SUSPEND_JOG_CANCEL)) {
487 printPgmString(PSTR("Hold:"));
488 if (sys.suspend & SUSPEND_HOLD_COMPLETE) { serial_write('0'); } // Ready to resume
489 else { serial_write('1'); } // Actively holding
490 break;
491 } // Continues to print jog state during jog cancel.
492 case STATE_JOG: printPgmString(PSTR("Jog")); break;
493 case STATE_HOMING: printPgmString(PSTR("Home")); break;
494 case STATE_ALARM: printPgmString(PSTR("Alarm")); break;
495 case STATE_CHECK_MODE: printPgmString(PSTR("Check")); break;
496 case STATE_SAFETY_DOOR:
497 printPgmString(PSTR("Door:"));
498 if (sys.suspend & SUSPEND_INITIATE_RESTORE) {
499 serial_write('3'); // Restoring
500 } else {
501 if (sys.suspend & SUSPEND_RETRACT_COMPLETE) {
502 if (sys.suspend & SUSPEND_SAFETY_DOOR_AJAR) {
503 serial_write('1'); // Door ajar
504 } else {
505 serial_write('0');
506 } // Door closed and ready to resume
507 } else {
508 serial_write('2'); // Retracting
509 }
510 }
511 break;
512 case STATE_SLEEP: printPgmString(PSTR("Sleep")); break;
513 }
514
515 float wco[N_AXIS];
516 if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE) ||
517 (sys.report_wco_counter == 0) ) {
518 for (idx=0; idx< N_AXIS; idx++) {
519 // Apply work coordinate offsets and tool length offset to current position.
520 wco[idx] = gc_state.coord_system[idx]+gc_state.coord_offset[idx];
521 if (idx == TOOL_LENGTH_OFFSET_AXIS) { wco[idx] += gc_state.tool_length_offset; }
522 if (bit_isfalse(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) {
523 print_position[idx] -= wco[idx];
524 }
525 }
526 }
527
528 // Report machine position
529 if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_POSITION_TYPE)) {
530 printPgmString(PSTR("|MPos:"));
531 } else {
532 printPgmString(PSTR("|WPos:"));
533 }
534 report_util_axis_values(print_position);
535
536 // Returns planner and serial read buffer states.
537 #ifdef REPORT_FIELD_BUFFER_STATE
538 if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_BUFFER_STATE)) {
539 printPgmString(PSTR("|Bf:"));
540 print_uint8_base10(plan_get_block_buffer_available());
541 serial_write(',');
542 print_uint8_base10(serial_get_rx_buffer_available());
543 }
544 #endif
545
546 #ifdef USE_LINE_NUMBERS
547 #ifdef REPORT_FIELD_LINE_NUMBERS
548 // Report current line number
549 plan_block_t * cur_block = plan_get_current_block();
550 if (cur_block != NULL) {
551 uint32_t ln = cur_block->line_number;
552 if (ln > 0) {
553 printPgmString(PSTR("|Ln:"));
554 printInteger(ln);
555 }
556 }
557 #endif
558 #endif
559
560 // Report realtime feed speed
561 #ifdef REPORT_FIELD_CURRENT_FEED_SPEED
562 #ifdef VARIABLE_SPINDLE
563 printPgmString(PSTR("|FS:"));
564 printFloat_RateValue(st_get_realtime_rate());
565 serial_write(',');
566 printFloat(sys.spindle_speed,N_DECIMAL_RPMVALUE);
567 #else
568 printPgmString(PSTR("|F:"));
569 printFloat_RateValue(st_get_realtime_rate());
570 #endif
571 #endif
572
573 #ifdef REPORT_FIELD_PIN_STATE
574 uint8_t lim_pin_state = limits_get_state();
575 uint8_t ctrl_pin_state = system_control_get_state();
576 uint8_t prb_pin_state = probe_get_state();
577 if (lim_pin_state | ctrl_pin_state | prb_pin_state) {
578 printPgmString(PSTR("|Pn:"));
579 if (prb_pin_state) { serial_write('P'); }
580 if (lim_pin_state) {
581 #ifdef ENABLE_DUAL_AXIS
582 #if (DUAL_AXIS_SELECT == X_AXIS)
583 if (bit_istrue(lim_pin_state,(bit(X_AXIS)|bit(N_AXIS)))) { serial_write('X'); }
584 if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); }
585 #endif
586 #if (DUAL_AXIS_SELECT == Y_AXIS)
587 if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X');
588 if (bit_istrue(lim_pin_state,(bit(Y_AXIS)|bit(N_AXIS)))) { serial_write('Y'); }
589 #endif
590 if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); }
591 #else
592 if (bit_istrue(lim_pin_state,bit(X_AXIS))) { serial_write('X'); }
593 if (bit_istrue(lim_pin_state,bit(Y_AXIS))) { serial_write('Y'); }
594 if (bit_istrue(lim_pin_state,bit(Z_AXIS))) { serial_write('Z'); }
595 #endif
596 }
597 if (ctrl_pin_state) {
598 #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN
599 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_SAFETY_DOOR)) { serial_write('D'); }
600 #endif
601 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_RESET)) { serial_write('R'); }
602 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_FEED_HOLD)) { serial_write('H'); }
603 if (bit_istrue(ctrl_pin_state,CONTROL_PIN_INDEX_CYCLE_START)) { serial_write('S'); }
604 }
605 }
606 #endif
607
608 #ifdef REPORT_FIELD_WORK_COORD_OFFSET
609 if (sys.report_wco_counter > 0) { sys.report_wco_counter--; }
610 else {
611 if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
612 sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh
613 } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_IDLE_COUNT-1); }
614 if (sys.report_ovr_counter == 0) { sys.report_ovr_counter = 1; } // Set override on next report.
615 printPgmString(PSTR("|WCO:"));
616 report_util_axis_values(wco);
617 }
618 #endif
619
620 #ifdef REPORT_FIELD_OVERRIDES
621 if (sys.report_ovr_counter > 0) { sys.report_ovr_counter--; }
622 else {
623 if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) {
624 sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Reset counter for slow refresh
625 } else { sys.report_ovr_counter = (REPORT_OVR_REFRESH_IDLE_COUNT-1); }
626 printPgmString(PSTR("|Ov:"));
627 print_uint8_base10(sys.f_override);
628 serial_write(',');
629 print_uint8_base10(sys.r_override);
630 serial_write(',');
631 print_uint8_base10(sys.spindle_speed_ovr);
632
633 uint8_t sp_state = spindle_get_state();
634 uint8_t cl_state = coolant_get_state();
635 if (sp_state || cl_state) {
636 printPgmString(PSTR("|A:"));
637 if (sp_state) { // != SPINDLE_STATE_DISABLE
638 #ifdef VARIABLE_SPINDLE
639 #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN
640 serial_write('S'); // CW
641 #else
642 if (sp_state == SPINDLE_STATE_CW) { serial_write('S'); } // CW
643 else { serial_write('C'); } // CCW
644 #endif
645 #else
646 if (sp_state & SPINDLE_STATE_CW) { serial_write('S'); } // CW
647 else { serial_write('C'); } // CCW
648 #endif
649 }
650 if (cl_state & COOLANT_STATE_FLOOD) { serial_write('F'); }
651 #ifdef ENABLE_M7
652 if (cl_state & COOLANT_STATE_MIST) { serial_write('M'); }
653 #endif
654 }
655 }
656 #endif
657
658 serial_write('>');
659 report_util_line_feed();
660}
661
Luigi Santivetti42a1b332019-11-17 22:31:46 +0000662#ifdef USE_ADC
663 void report_adc_status()
664 {
665 uint8_t i;
666
667 printPgmString(PSTR("ADC Buffer ["));
668
669 for (i = 0; i < ADC_CHANNELS_ENABLED_COUNT; i++) {
670 printPgmString(PSTR(" channel:"));
671 print_uint32_base10((uint32_t)i);
672 printPgmString(PSTR(", value:"));
673 //print_uint32_base10((uint32_t) adc_read_unsigned(i));
674 if (i + 1 < ADC_CHANNELS_ENABLED_COUNT) serial_write(',');
675 }
676
677 printPgmString(PSTR(" ]"));
678 report_util_line_feed();
679 }
680#endif
Luigi Santivetti69972f92019-11-12 22:55:40 +0000681
682#ifdef DEBUG
683 void report_realtime_debug()
684 {
685
686 }
687#endif