diff --git a/gcode.c b/gcode.c index d67ace0..8e7c28e 100644 --- a/gcode.c +++ b/gcode.c @@ -321,14 +321,14 @@ uint8_t gc_execute_line(char *line) target[i] = gc.position[i]; } } - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], -1.0, false); + mc_line(target, -1.0, 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], -1.0, false); + mc_line(coord_data, -1.0, false); memcpy(gc.position, coord_data, sizeof(coord_data)); // gc.position[] = coord_data[]; axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags. break; @@ -399,7 +399,7 @@ 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], -1.0, false); } + else { mc_line(target, -1.0, false); } break; case MOTION_MODE_LINEAR: // TODO: Inverse time requires F-word with each statement. Need to do a check. Also need @@ -407,8 +407,7 @@ uint8_t gc_execute_line(char *line) // and after an inverse time move and then check for non-zero feed rate each time. This // should be efficient and effective. if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} - else { mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], - (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); } + else { mc_line(target, (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); } break; case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: // Check if at least one of the axes of the selected plane has been specified. If in center diff --git a/motion_control.c b/motion_control.c index 6305bb4..04900a2 100644 --- a/motion_control.c +++ b/motion_control.c @@ -48,24 +48,31 @@ // However, this keeps the memory requirements lower since it doesn't have to call and hold two // plan_buffer_lines in memory. Grbl only has to retain the original line input variables during a // backlash segment(s). -void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rate) +void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate) { // TO TEST: Perform soft limit check here. Just check if the target x,y,z values are outside the // work envelope. Should be straightforward and efficient. By placing it here, rather than in // the g-code parser, it directly picks up motions from everywhere in Grbl. - if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { - if( (x> settings.mm_soft_limit[X_AXIS])||(y>settings.mm_soft_limit[Y_AXIS])||(z>settings.mm_soft_limit[Z_AXIS])) { - if (sys.state != STATE_ALARM) { - if (bit_isfalse(sys.execute,EXEC_ALARM)) { - mc_reset(); // Initiate system kill. - report_alarm_message(ALARM_SOFT_LIMIT); - sys.state = STATE_ALARM; - sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event - } - } + // TODO: Eventually move the soft limit check into limits.c. + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { + uint8_t i; + for (i=0; i settings.max_travel[i])) { + // TODO: Need to make this more in-line with the rest of the alarm and runtime execution handling. + // Not quite right. Also this should force Grbl to feed hold and exit, rather than stopping and alarm + // out. This would help retain machine position, but is this really required? + if (sys.state != STATE_ALARM) { + if (bit_isfalse(sys.execute,EXEC_ALARM)) { + mc_reset(); // Initiate system kill. + report_alarm_message(ALARM_SOFT_LIMIT); + sys.state = STATE_ALARM; + sys.execute |= EXEC_CRIT_EVENT; // Indicate hard limit critical event + } } + } + } } - + // If in check gcode mode, prevent motion by blocking planner. if (sys.state == STATE_CHECK_MODE) { return; } @@ -82,7 +89,7 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat protocol_execute_runtime(); // Check for any run-time commands if (sys.abort) { return; } // Bail, if system abort. } while ( plan_check_full_buffer() ); - plan_buffer_line(x, y, z, feed_rate, invert_feed_rate); + plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], feed_rate, invert_feed_rate); // If idle, indicate to the system there is now a planned block in the buffer ready to cycle // start. Otherwise ignore and continue on. @@ -96,6 +103,9 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat // when the buffer is completely full and primed; auto-starting, if there was only one g-code // command sent during manual operation; or if a system is prone to buffer starvation, auto-start // helps make sure it minimizes any dwelling/motion hiccups and keeps the cycle going. + // NOTE: Moved into main loop and plan_check_full_buffer() as a test. This forces Grbl to process + // all of the commands in the serial read buffer or until the planner buffer is full before auto + // cycle starting. Will eventually need to remove the following command. // if (sys.auto_start) { st_cycle_start(); } } @@ -204,14 +214,14 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8 arc_target[axis_0] = center_axis0 + r_axis0; arc_target[axis_1] = center_axis1 + r_axis1; arc_target[axis_linear] += linear_per_segment; - mc_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], feed_rate, invert_feed_rate); + mc_line(arc_target, feed_rate, invert_feed_rate); // Bail mid-circle on system abort. Runtime command check already performed by mc_line. if (sys.abort) { return; } } } // Ensure last segment arrives at target location. - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], feed_rate, invert_feed_rate); + mc_line(target, feed_rate, invert_feed_rate); } @@ -252,22 +262,18 @@ void mc_go_home() // Pull-off axes (that have been homed) from limit switches before continuing motion. // This provides some initial clearance off the switches and should also help prevent them // from falsely tripping when hard limits are enabled. - int8_t x_dir, y_dir, z_dir; - x_dir = y_dir = z_dir = 0; + float target[N_AXIS]; + target[X_AXIS] = target[Y_AXIS] = target[Z_AXIS] = settings.homing_pulloff; if (HOMING_LOCATE_CYCLE & (1<