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