From c2b31a06ffce3371131a0fcb67cd221b7a89575c Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 5 Nov 2012 13:32:29 -0700 Subject: [PATCH] Tweaked dry run and check g-code switches. Now resets when toggled off. - To make managing the code easier and to help ensure a user starts with a fresh reset, the functionality of check g-code and dry run has been changed to automatically perform a soft reset when toggled off. Position will not be lost, unless there is a cycle active. Feed hold before toggling off it needed. This is mainly a safety issue. If a user dry runs a program and kills it mid-program, and then restarts it thinking to run it as normal, the g-code modes that we're set may not be what they expect, and very bad things can happen. - NOTE: Grbl is at 83.5% of flash capacity. Not a lot of room left, but I think we can squeeze in some more! --- gcode.c | 32 ++++++++++++++++++++------------ gcode.h | 1 + protocol.c | 18 ++++++++++++++---- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/gcode.c b/gcode.c index 8e09c53..b56e241 100755 --- a/gcode.c +++ b/gcode.c @@ -52,6 +52,7 @@ void gc_init() { memset(&gc, 0, sizeof(gc)); gc.feed_rate = settings.default_feed_rate; // Should be zero at initialization. + gc.seek_rate = settings.default_seek_rate; select_plane(X_AXIS, Y_AXIS, Z_AXIS); gc.absolute_mode = true; @@ -247,20 +248,25 @@ uint8_t gc_execute_line(char *line) NOTE: Independent non-motion/settings parameters are set out of this order for code efficiency and simplicity purposes, but this should not affect proper g-code execution. */ - // ([F]: Set feed rate. Already performed, but enforce rapids for dry runs.) - if (bit_istrue(gc.switches,BITFLAG_DRY_RUN)) { gc.feed_rate = settings.default_seek_rate; } + // ([F]: Set feed and seek rates. Used to enforce user feed rate for dry runs.) + // TODO: Dry runs move at whatever feed rate the user specifies. Need to update this to allow + // this feature. Users can also change the rates realtime like a feedrate override. Until that + // is installed, it will have to wait, but users could control it by using the default feed rate. + // TODO: Seek rates can change depending on the direction and maximum speeds of each axes. When + // max axis speed is installed, the calculation can be performed here, or maybe in the planner. + if (bit_istrue(gc.switches,BITFLAG_DRY_RUN)) { + // NOTE: Since dry run resets after disabled, the defaults rates should come back. + gc.feed_rate = settings.default_feed_rate; + gc.seek_rate = settings.default_feed_rate; + } // ([M6]: Tool change should be executed here.) // [M3,M4,M5]: Update spindle state - if (!(gc.switches & (BITFLAG_DRY_RUN | BITFLAG_CHECK_GCODE))) { - spindle_run(gc.spindle_direction); //, gc.spindle_speed); - } + if (!(gc.switches & BITFLAG_CHECK_GCODE)) { spindle_run(gc.spindle_direction); } // [*M7,M8,M9]: Update coolant state - if (!(gc.switches & (BITFLAG_DRY_RUN | BITFLAG_CHECK_GCODE))) { - coolant_run(gc.coolant_mode); - } + if (!(gc.switches & BITFLAG_CHECK_GCODE)) { 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 @@ -327,14 +333,14 @@ uint8_t gc_execute_line(char *line) target[i] = gc.position[i]; } } - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], settings.default_seek_rate, false); + mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], gc.seek_rate, false); } // Retreive G28/30 go-home position data (in machine coordinates) from EEPROM float coord_data[N_AXIS]; uint8_t home_select = SETTING_INDEX_G28; if (non_modal_action == NON_MODAL_GO_HOME_1) { home_select = SETTING_INDEX_G30; } if (!settings_read_coord_data(home_select,coord_data)) { return(STATUS_SETTING_READ_FAIL); } - mc_line(coord_data[X_AXIS], coord_data[Y_AXIS], coord_data[Z_AXIS], settings.default_seek_rate, false); + mc_line(coord_data[X_AXIS], coord_data[Y_AXIS], coord_data[Z_AXIS], gc.seek_rate, false); axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags. break; case NON_MODAL_SET_HOME_0: case NON_MODAL_SET_HOME_1: @@ -404,7 +410,9 @@ uint8_t gc_execute_line(char *line) break; case MOTION_MODE_SEEK: if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} - else { mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], settings.default_seek_rate, false); } + else { + mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], gc.seek_rate, false); + } break; case MOTION_MODE_LINEAR: // TODO: Inverse time requires F-word with each statement. Need to do a check. Also need @@ -547,7 +555,7 @@ uint8_t gc_execute_line(char *line) // If complete, reset to reload defaults (G92.2,G54,G17,G90,G94,M48,G40,M5,M9). Otherwise, // re-enable program flow after pause complete, where cycle start will resume the program. - if (gc.program_flow == PROGRAM_FLOW_COMPLETED) { sys.abort = true; } + if (gc.program_flow == PROGRAM_FLOW_COMPLETED) { sys.execute |= EXEC_RESET; } else { gc.program_flow = PROGRAM_FLOW_RUNNING; } } diff --git a/gcode.h b/gcode.h index 6369dfe..11980ad 100755 --- a/gcode.h +++ b/gcode.h @@ -83,6 +83,7 @@ typedef struct { int8_t spindle_direction; // 1 = CW, -1 = CCW, 0 = Stop {M3, M4, M5} uint8_t coolant_mode; // 0 = Disable, 1 = Flood Enable {M8, M9} float feed_rate; // Millimeters/min + float seek_rate; // Millimeters/min - Can change depending on switches and such. float position[3]; // Where the interpreter considers the tool to be at this point in the code uint8_t tool; // uint16_t spindle_speed; // RPM/100 diff --git a/protocol.c b/protocol.c index 068c7a2..cae64cb 100755 --- a/protocol.c +++ b/protocol.c @@ -123,7 +123,7 @@ void protocol_execute_runtime() // System abort. Steppers have already been force stopped. if (rt_exec & EXEC_RESET) { - sys.abort = true; + sys.abort = true; // Only place this is set true. return; // Nothing else to do but exit. } @@ -215,10 +215,20 @@ uint8_t protocol_execute_line(char *line) switch (line[++char_counter]) { case '0' : helper_var = BITFLAG_CHECK_GCODE; - // Sync position vectors if check mode is being disabled. May be different after checking. - if (bit_istrue(gc.switches,helper_var)) { sys_sync_current_position(); } + // If check mode is being disabled, automatically soft reset Grbl to ensure the user starts + // fresh with the g-code modes in their default, known state. + if (bit_istrue(gc.switches,helper_var)) { sys.execute |= EXEC_RESET; } + break; + case '1' : + helper_var = BITFLAG_DRY_RUN; + // If dry run is being disabled, automatically soft reset Grbl as with check g-code mode + if (bit_istrue(gc.switches,helper_var)) { + // If disabled while in cycle, immediately stop everything and notify user that stopping + // mid-cycle likely lost position. + if (bit_istrue(sys.state,STATE_CYCLE)) { mc_alarm(); } + sys.execute |= EXEC_RESET; // Soft-reset Grbl. + } break; - case '1' : helper_var = BITFLAG_DRY_RUN; break; case '2' : helper_var = BITFLAG_BLOCK_DELETE; break; case '3' : helper_var = BITFLAG_SINGLE_BLOCK; break; case '4' : helper_var = BITFLAG_OPT_STOP; break;