From 5dd6d90122dce991a99eab5aa3a5c991dd5c938a Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 15 Nov 2012 21:53:11 -0700 Subject: [PATCH] Added Grbl state in status report. Removed switch support. - Added Grbl state (Idle, Running, Queued, Hold, etc) to the real-time status reporting feature as feedback to the user of what Grbl is doing. Updated the help message to reflect this change. - Removed switches (dry run, block delete, single block mode). To keep Grbl simple and not muddled up from things that can easily be taken care of by an external interface, these were removed. - Check g-code mode was retained, but the command was moved to '$C' from '$S0'. --- config.h | 2 +- gcode.c | 20 +++++++---------- gcode.h | 11 --------- motion_control.c | 2 +- nuts_bolts.h | 17 +++++++------- protocol.c | 58 ++++++++++++++++++++---------------------------- report.c | 41 ++++++++++++++++------------------ report.h | 2 +- 8 files changed, 63 insertions(+), 90 deletions(-) diff --git a/config.h b/config.h index 6fe5620..b193850 100755 --- a/config.h +++ b/config.h @@ -123,7 +123,7 @@ // that do not and must not exist in the streamed g-code program. ASCII control characters may be // used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in // g-code programs, maybe selected for interface programs. -// TODO: Solidify these default characters. Temporary for now. +// NOTE: If changed, manually update help message in report.c. #define CMD_STATUS_REPORT '?' #define CMD_FEED_HOLD '!' #define CMD_CYCLE_START '~' diff --git a/gcode.c b/gcode.c index 9f145a2..d9de80e 100755 --- a/gcode.c +++ b/gcode.c @@ -60,8 +60,6 @@ void gc_init() if (!(settings_read_coord_data(gc.coord_select,gc.coord_system))) { report_status_message(STATUS_SETTING_READ_FAIL); } - -// protocol_status_message(settings_execute_startup()); } // Sets g-code parser position in mm. Input in steps. Called by the system abort and hard @@ -176,11 +174,7 @@ uint8_t gc_execute_line(char *line) // Set 'M' commands switch(int_value) { case 0: gc.program_flow = PROGRAM_FLOW_PAUSED; break; // Program pause - case 1: // Program pause with optional stop on, otherwise do nothing. - if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) { - gc.program_flow = PROGRAM_FLOW_PAUSED; - } - break; + case 1: break; // Optional stop not supported. Ignore. case 2: case 30: gc.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset case 3: gc.spindle_direction = 1; break; case 4: gc.spindle_direction = -1; break; @@ -260,10 +254,10 @@ uint8_t gc_execute_line(char *line) // ([M6]: Tool change should be executed here.) // [M3,M4,M5]: Update spindle state - if (!(gc.switches & BITFLAG_CHECK_GCODE)) { spindle_run(gc.spindle_direction); } + if (sys.state != STATE_CHECK_MODE) { spindle_run(gc.spindle_direction); } // [*M7,M8,M9]: Update coolant state - if (!(gc.switches & BITFLAG_CHECK_GCODE)) { coolant_run(gc.coolant_mode); } + if (sys.state != STATE_CHECK_MODE) { coolant_run(gc.coolant_mode); } // [G54,G55,...,G59]: Coordinate system selection if ( bit_istrue(modal_group_words,bit(MODAL_GROUP_12)) ) { // Check if called in block @@ -281,7 +275,7 @@ uint8_t gc_execute_line(char *line) FAIL(STATUS_INVALID_STATEMENT); } else { // Ignore dwell in check gcode modes - if (!(gc.switches & BITFLAG_CHECK_GCODE)) { mc_dwell(p); } + if (sys.state != STATE_CHECK_MODE) { mc_dwell(p); } } break; case NON_MODAL_SET_COORDINATE_DATA: @@ -544,7 +538,7 @@ uint8_t gc_execute_line(char *line) // M0,M1,M2,M30: Perform non-running program flow actions. During a program pause, the buffer may // refill and can only be resumed by the cycle start run-time command. - if (gc.program_flow || bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) { + if (gc.program_flow) { plan_synchronize(); // Finish all remaining buffered motions. Program paused when complete. sys.auto_start = false; // Disable auto cycle start. Forces pause until cycle start issued. @@ -588,12 +582,14 @@ static int next_statement(char *letter, float *float_ptr, char *line, uint8_t *c - Evaluation of expressions - Variables - Probing - - Override control + - Override control (TBD) - Tool changes + - Switches (*) Indicates optional parameter, enabled through config.h and re-compile group 0 = {G92.2, G92.3} (Non modal: Cancel and re-enable G92 offsets) group 1 = {G38.2, G81 - G89} (Motion modes: straight probe, canned cycles) + group 4 = {M1} (Optional stop, ignored) group 6 = {M6} (Tool change) group 8 = {*M7} enable mist coolant group 9 = {M48, M49} enable/disable feed and speed override switches diff --git a/gcode.h b/gcode.h index 8315ed2..f3671c2 100755 --- a/gcode.h +++ b/gcode.h @@ -62,19 +62,8 @@ #define NON_MODAL_SET_COORDINATE_OFFSET 7 // G92 #define NON_MODAL_RESET_COORDINATE_OFFSET 8 //G92.1 -// Define bit flag masks for gc.switches. (8 flag limit) -#define BITFLAG_CHECK_GCODE bit(0) -#define BITFLAG_BLOCK_DELETE bit(1) -#define BITFLAG_SINGLE_BLOCK bit(2) -#define BITFLAG_OPT_STOP bit(3) -// #define bit(4) -// #define bit(5) -// #define bit(6) -// #define bit(7) - typedef struct { uint8_t status_code; // Parser status for current block - uint8_t switches; // Handles non-gcode switches modes. Set externally by protocol. Default off uint8_t motion_mode; // {G0, G1, G2, G3, G80} uint8_t inverse_feed_rate_mode; // {G93, G94} uint8_t inches_mode; // 0 = millimeter mode, 1 = inches mode {G20, G21} diff --git a/motion_control.c b/motion_control.c index 6cc000f..d5ba8c9 100755 --- a/motion_control.c +++ b/motion_control.c @@ -64,7 +64,7 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat } while ( plan_check_full_buffer() ); // If in check gcode mode, prevent motion by blocking planner. - if (bit_isfalse(gc.switches,BITFLAG_CHECK_GCODE)) { + if (sys.state != STATE_CHECK_MODE) { plan_buffer_line(x, y, z, feed_rate, invert_feed_rate); // If idle, indicate to the system there is now a planned block in the buffer ready to cycle diff --git a/nuts_bolts.h b/nuts_bolts.h index 1f588ca..316c9ce 100755 --- a/nuts_bolts.h +++ b/nuts_bolts.h @@ -69,14 +69,15 @@ // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for // critical events. -#define STATE_IDLE 0 // Must be zero. -#define STATE_INIT 1 // Initial power up state. -#define STATE_QUEUED 2 // Indicates buffered blocks, awaiting cycle start. -#define STATE_CYCLE 3 // Cycle is running -#define STATE_HOLD 4 // Executing feed hold -#define STATE_HOMING 5 // Performing homing cycle -#define STATE_ALARM 6 // In alarm state. Locks out all g-code processes. Allows settings access. -// #define STATE_JOG 7 // Jogging mode is unique like homing. +#define STATE_IDLE 0 // Must be zero. +#define STATE_INIT 1 // Initial power up state. +#define STATE_QUEUED 2 // Indicates buffered blocks, awaiting cycle start. +#define STATE_CYCLE 3 // Cycle is running +#define STATE_HOLD 4 // Executing feed hold +#define STATE_HOMING 5 // Performing homing cycle +#define STATE_ALARM 6 // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE 7 // G-code check mode. Locks out planner and motion only. +// #define STATE_JOG 8 // Jogging mode is unique like homing. // Define global system variables typedef struct { diff --git a/protocol.c b/protocol.c index 9ece210..c97770a 100755 --- a/protocol.c +++ b/protocol.c @@ -195,6 +195,28 @@ uint8_t protocol_execute_line(char *line) if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); } else { report_gcode_modes(); } break; + case 'C' : // Set check g-code mode + if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); } + // Perform reset when toggling off. Check g-code mode should only work if Grbl + // is idle and ready, regardless of alarm locks. This is mainly to keep things + // simple and consistent. + if ( sys.state == STATE_CHECK_MODE ) { + mc_reset(); + report_feedback_message(MESSAGE_DISABLED); + } else { + if (sys.state) { return(STATUS_IDLE_ERROR); } + sys.state = STATE_CHECK_MODE; + report_feedback_message(MESSAGE_ENABLED); + } + break; + case 'X' : // Disable alarm lock + if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); } + if (sys.state == STATE_ALARM) { + report_feedback_message(MESSAGE_ALARM_UNLOCK); + sys.state = STATE_IDLE; + // Don't run startup script. Prevents stored moves in startup from causing accidents. + } + break; case 'H' : // Perform homing cycle if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { // Only perform homing if Grbl is idle or lost. @@ -216,35 +238,6 @@ uint8_t protocol_execute_line(char *line) // handled by the planner. It would be possible for the jog subprogram to insert blocks into the // block buffer without having the planner plan them. It would need to manage de/ac-celerations // on its own carefully. This approach could be effective and possibly size/memory efficient. - case 'S' : // Switch modes - // Set helper_var as switch bitmask or clearing flag - switch (line[++char_counter]) { - case '0' : helper_var = BITFLAG_CHECK_GCODE; break; - case '1' : helper_var = BITFLAG_BLOCK_DELETE; break; - case '2' : helper_var = BITFLAG_SINGLE_BLOCK; break; - case '3' : helper_var = BITFLAG_OPT_STOP; break; - default : return(STATUS_INVALID_STATEMENT); - } - if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); } - if ( helper_var & BITFLAG_CHECK_GCODE ) { - // Perform reset when toggling off. Check g-code mode should only work if Grbl - // is idle and ready, regardless of homing locks. This is mainly to keep things - // simple and consistent. - if ( bit_istrue(gc.switches,helper_var) ) { mc_reset(); } - else if (sys.state) { return(STATUS_IDLE_ERROR); } - } - gc.switches ^= helper_var; - if (bit_istrue(gc.switches,helper_var)) { report_feedback_message(MESSAGE_ENABLED); } - else { report_feedback_message(MESSAGE_DISABLED); } - break; - case 'X' : // Disable alarm lock - if ( line[++char_counter] != 0 ) { return(STATUS_UNSUPPORTED_STATEMENT); } - if (sys.state == STATE_ALARM) { - report_feedback_message(MESSAGE_ALARM_UNLOCK); - sys.state = STATE_IDLE; - // Don't run startup script. Prevents stored moves in startup from causing accidents. - } - break; case 'N' : // Startup lines. if ( line[++char_counter] == 0 ) { // Print startup lines for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) { @@ -323,11 +316,8 @@ void protocol_process() } else { if (c <= ' ') { // Throw away whitepace and control characters - } else if (c == '/') { - // Disable block delete and throw away characters. Will ignore until EOL. - if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) { - iscomment = true; - } + } else if (c == '/') { + // Block delete not supported. Ignore character. } else if (c == '(') { // Enable comments flag and ignore all characters until ')' or EOL. iscomment = true; diff --git a/report.c b/report.c index 485d240..e1bf30d 100644 --- a/report.c +++ b/report.c @@ -131,15 +131,12 @@ void report_grbl_help() { "$N (view startup blocks)\r\n" "$x=value (save Grbl setting)\r\n" "$Nx=line (save startup block)\r\n" - "$S0 (toggle check gcode)\r\n" - "$S1 (toggle blk del)\r\n" - "$S2 (toggle single blk)\r\n" - "$S3 (toggle opt stop)\r\n" + "$C (check gcode mode)\r\n" "$X (kill alarm lock)\r\n" "$H (run homing cycle)\r\n" "~ (cycle start)\r\n" "! (feed hold)\r\n" - "? (position)\r\n" + "? (current status)\r\n" "ctrl-x (reset Grbl)\r\n")); } @@ -214,7 +211,7 @@ void report_gcode_parameters() } -// Print current gcode parser mode state and active switches +// Print current gcode parser mode state void report_gcode_modes() { switch (gc.motion_mode) { @@ -268,15 +265,7 @@ void report_gcode_modes() printPgmString(PSTR(" F")); if (gc.inches_mode) { printFloat(gc.feed_rate*INCH_PER_MM); } else { printFloat(gc.feed_rate); } - - // Print active switches - if (gc.switches) { - if (bit_istrue(gc.switches,BITFLAG_CHECK_GCODE)) { printPgmString(PSTR(" $S0")); } - if (bit_istrue(gc.switches,BITFLAG_BLOCK_DELETE)) { printPgmString(PSTR(" $S1")); } - if (bit_istrue(gc.switches,BITFLAG_SINGLE_BLOCK)) { printPgmString(PSTR(" $S2")); } - if (bit_istrue(gc.switches,BITFLAG_OPT_STOP)) { printPgmString(PSTR(" $S3")); } - } - + printPgmString(PSTR("\r\n")); } @@ -304,20 +293,29 @@ void report_realtime_status() memcpy(current_position,sys.position,sizeof(sys.position)); float print_position[3]; - // TODO: Add Grbl state feedback, i.e. IDLE, RUN, HOLD, HOME, etc. + // Report current machine state + switch (sys.state) { + case STATE_IDLE: printPgmString(PSTR("[Idle")); break; +// case STATE_INIT: printPgmString(PSTR("[Init")); break; // Never observed + case STATE_QUEUED: printPgmString(PSTR("[Queue")); break; + case STATE_CYCLE: printPgmString(PSTR("[Run")); break; + case STATE_HOLD: printPgmString(PSTR("[Hold")); break; + case STATE_HOMING: printPgmString(PSTR("[Home")); break; + case STATE_ALARM: printPgmString(PSTR("[Alarm")); break; + case STATE_CHECK_MODE: printPgmString(PSTR("[Check")); break; + } // Report machine position - printPgmString(PSTR("MPos:[")); + printPgmString(PSTR(",MPos:")); for (i=0; i<= 2; i++) { print_position[i] = current_position[i]/settings.steps_per_mm[i]; if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { print_position[i] *= INCH_PER_MM; } printFloat(print_position[i]); - if (i < 2) { printPgmString(PSTR(",")); } - else { printPgmString(PSTR("]")); } + printPgmString(PSTR(",")); } // Report work position - printPgmString(PSTR(",WPos:[")); + printPgmString(PSTR("WPos:")); for (i=0; i<= 2; i++) { if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { print_position[i] -= (gc.coord_system[i]+gc.coord_offset[i])*INCH_PER_MM; @@ -326,8 +324,7 @@ void report_realtime_status() } printFloat(print_position[i]); if (i < 2) { printPgmString(PSTR(",")); } - else { printPgmString(PSTR("]")); } } - printPgmString(PSTR("\r\n")); + printPgmString(PSTR("]\r\n")); } diff --git a/report.h b/report.h index 885114f..8f1555c 100644 --- a/report.h +++ b/report.h @@ -71,7 +71,7 @@ void report_realtime_status(); // Prints Grbl persistent coordinate parameters void report_gcode_parameters(); -// Prints current g-code parser mode state and active switches +// Prints current g-code parser mode state void report_gcode_modes(); // Prints startup line