Critical M0/2/30 fix. Homing updates.

- Critical fix for M0 program pause. Due to its recent change, it would
cause Grbl to suspend but wouldn’t notify the user of why Grbl was not
doing anything. The state would show IDLE and a cycle start would
resume it. Grbl now enters a HOLD state to better indicate the state
change.

- Critical fix for M2 and M30 program end. As with M0, the state
previously would show IDLE while suspended. Grbl now does not suspend
upon program end and leaves job control to the GUI. Grbl simply reports
a `[Pgm End]` as a feedback message and resets certain g-code modes.

- M2/30 g-code reseting fix. Previously Grbl would soft-reset after an
M2/30, but this was not complaint to the (linuxcnc) g-code standard. It
simply resets [G1,G17,G90,G94,G40,G54,M5,M9,M48] and keeps all other
modes the same.

- M0/M2/M30 check-mode fix. It now does not suspend the machine during
check-mode.

- Minor bug fix related to commands similar to G90.1, but not G90.1,
not reporting an unsupported command.

- Homing cycle refactoring. To help reduce the chance of users
misunderstanding their limit switch wiring, Grbl only moves a short
distance for the locate cycles only. In addition, the homing cycle
pulls-off the limit switch by the pull-off distance to re-engage and
locate home. This should improve its accuracy.

- HOMING_FORCE_ORIGIN now sets the origin to the pull-off location,
rather than where the limit switch was triggered.

- Updated default junction deviation to 0.01mm. Recent tests showed
that this improves Grbl’s cornering behavior a bit.

- Added the ShapeOko3 defaults.

- Added new feedback message `[Pgm End]` for M2/30 notification.

- Limit pin reporting is now a $10 status report option. Requested by
OEMs to help simplify support troubleshooting.
This commit is contained in:
Sonny Jeon 2015-05-17 13:25:36 -06:00
parent 4c20a2173f
commit 664854b9df
11 changed files with 201 additions and 131 deletions

View File

@ -1,3 +1,29 @@
----------------
Date: 2015-03-29
Author: Sonny Jeon
Subject: Fix for limit pin reporting compile-option
- The limit pin reporting wasnt working correctly due to calling the
wrong similarly-named function. Verified to be working now.
----------------
Date: 2015-03-29
Author: Sonny Jeon
Subject: Commit history, logo license, full-arc fix.
- Commit history added to repo, as an easier way for people to see view
the changes over time.
- Grbl logo copyright license added. All rights reserved with regards
to the Grbl logo.
- G2/3 full circles would sometime not execute. The problem was due to
numerical round-off of a trig calculation. Added a machine epsilon
define to help detect and correct for this problem. Tested and should
not effect general operation of arcs.
---------------- ----------------
Date: 2015-03-27 Date: 2015-03-27
Author: Sungeun Jeon Author: Sungeun Jeon

View File

@ -79,7 +79,7 @@
// Number of homing cycles performed after when the machine initially jogs to limit switches. // Number of homing cycles performed after when the machine initially jogs to limit switches.
// This help in preventing overshoot and should improve repeatability. This value should be one or // This help in preventing overshoot and should improve repeatability. This value should be one or
// greater. // greater.
#define N_HOMING_LOCATE_CYCLE 2 // Integer (1-128) #define N_HOMING_LOCATE_CYCLE 1 // Integer (1-128)
// After homing, Grbl will set by default the entire machine space into negative space, as is typical // After homing, Grbl will set by default the entire machine space into negative space, as is typical
// for professional CNC machines, regardless of where the limit switches are located. Uncomment this // for professional CNC machines, regardless of where the limit switches are located. Uncomment this

View File

@ -49,7 +49,6 @@
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -87,10 +86,9 @@
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS)) #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION))
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_JUNCTION_DEVIATION 0.01 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // true #define DEFAULT_REPORT_INCHES 0 // true
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -129,10 +127,9 @@
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS)) #define DEFAULT_DIRECTION_INVERT_MASK ((1<<Y_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled) #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION))
#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -171,10 +168,9 @@
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS)) #define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled) #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION))
#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -187,6 +183,46 @@
#define DEFAULT_HOMING_PULLOFF 1.0 // mm #define DEFAULT_HOMING_PULLOFF 1.0 // mm
#endif #endif
#ifdef DEFAULTS_SHAPEOKO_3
// Description: Shapeoko CNC mill with three NEMA 23 stepper motors, driven by CarbideMotion
#define MICROSTEPS_XY 8
#define STEP_REVS_XY 200
#define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth
#define MICROSTEPS_Z 8
#define STEP_REVS_Z 200
#define MM_PER_REV_Z (2.0*20) // 2mm belt pitch, 20 pulley teeth
#define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
#define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY)
#define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z)
#define DEFAULT_X_MAX_RATE 5000.0 // mm/min
#define DEFAULT_Y_MAX_RATE 5000.0 // mm/min
#define DEFAULT_Z_MAX_RATE 5000.0 // mm/min
#define DEFAULT_X_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
#define DEFAULT_Y_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
#define DEFAULT_Z_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2
#define DEFAULT_X_MAX_TRAVEL 425.0 // mm
#define DEFAULT_Y_MAX_TRAVEL 465.0 // mm
#define DEFAULT_Z_MAX_TRAVEL 80.0 // mm
#define DEFAULT_STEP_PULSE_MICROSECONDS 10
#define DEFAULT_STEPPING_INVERT_MASK 0
#define DEFAULT_DIRECTION_INVERT_MASK ((1<<X_AXIS)|(1<<Z_AXIS))
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-254, 255 keeps steppers enabled)
#define DEFAULT_STATUS_REPORT_MASK 255 // All enabled
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.01 // mm
#define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
#define DEFAULT_HARD_LIMIT_ENABLE 0 // false
#define DEFAULT_HOMING_ENABLE 0 // false
#define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
#define DEFAULT_HOMING_FEED_RATE 100.0 // mm/min
#define DEFAULT_HOMING_SEEK_RATE 1000.0 // mm/min
#define DEFAULT_HOMING_DEBOUNCE_DELAY 25 // msec (0-65k)
#define DEFAULT_HOMING_PULLOFF 5.0 // mm
#endif
#ifdef DEFAULTS_ZEN_TOOLWORKS_7x7 #ifdef DEFAULTS_ZEN_TOOLWORKS_7x7
// Description: Zen Toolworks 7x7 mill with three Shinano SST43D2121 65oz-in NEMA 17 stepper motors. // Description: Zen Toolworks 7x7 mill with three Shinano SST43D2121 65oz-in NEMA 17 stepper motors.
// Leadscrew is different from some ZTW kits, where most are 1.25mm/rev rather than 8.0mm/rev here. // Leadscrew is different from some ZTW kits, where most are 1.25mm/rev rather than 8.0mm/rev here.
@ -214,7 +250,6 @@
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -250,7 +285,6 @@
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false
@ -286,7 +320,6 @@
#define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm
#define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm
#define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_REPORT_INCHES 0 // false
#define DEFAULT_AUTO_START 1 // true
#define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_ST_ENABLE 0 // false
#define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false
#define DEFAULT_SOFT_LIMIT_ENABLE 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false

View File

@ -219,7 +219,7 @@ uint8_t gc_execute_line(char *line)
else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91 else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91
} else { } else {
word_bit = MODAL_GROUP_G4; word_bit = MODAL_GROUP_G4;
if (mantissa != 10) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported] if ((mantissa != 10) || (int_value == 90)) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported]
mantissa = 0; // Set to zero to indicate valid non-integer G command. mantissa = 0; // Set to zero to indicate valid non-integer G command.
// Otherwise, arc IJK incremental mode is default. G91.1 does nothing. // Otherwise, arc IJK incremental mode is default. G91.1 does nothing.
} }
@ -1028,18 +1028,41 @@ uint8_t gc_execute_line(char *line)
// refill and can only be resumed by the cycle start run-time command. // refill and can only be resumed by the cycle start run-time command.
gc_state.modal.program_flow = gc_block.modal.program_flow; gc_state.modal.program_flow = gc_block.modal.program_flow;
if (gc_state.modal.program_flow) { if (gc_state.modal.program_flow) {
protocol_buffer_synchronize(); // Finish all remaining buffered motions. Program paused when complete. protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on.
if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) {
if (sys.state != STATE_CHECK_MODE) {
bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause.
protocol_execute_realtime(); // Execute suspend.
}
} else { // == PROGRAM_FLOW_COMPLETED
// Upon program complete, only a subset of g-codes reset to certain defaults, according to
// LinuxCNC's program end descriptions and testing. Only modal groups [G-code 1,2,3,5,7,12]
// and [M-code 7,8,9] reset to [G1,G17,G90,G94,G40,G54,M5,M9,M48]. The remaining modal groups
// [G-code 4,6,8,10,13,14,15] and [M-code 4,5,6] and the modal words [F,S,T,H] do not reset.
gc_state.modal.motion = MOTION_MODE_LINEAR;
gc_state.modal.plane_select = PLANE_SELECT_XY;
gc_state.modal.distance = DISTANCE_MODE_ABSOLUTE;
gc_state.modal.feed_rate = FEED_RATE_MODE_UNITS_PER_MIN;
// gc_state.modal.cutter_comp = CUTTER_COMP_DISABLE; // Not supported.
gc_state.modal.coord_select = 0; // G54
gc_state.modal.spindle = SPINDLE_DISABLE;
gc_state.modal.coolant = COOLANT_DISABLE;
// gc_state.modal.override = OVERRIDE_DISABLE; // Not supported.
sys.suspend = true; // Execute coordinate change and spindle/coolant stop.
protocol_execute_realtime(); // Suspend execution. For both program pause or program end. if (sys.state != STATE_CHECK_MODE) {
if (!(settings_read_coord_data(gc_state.modal.coord_select,coordinate_data))) { FAIL(STATUS_SETTING_READ_FAIL); }
// If complete, reset to reload defaults (G92.2,G54,G17,G90,G94,M48,G40,M5,M9). Otherwise, memcpy(gc_state.coord_system,coordinate_data,sizeof(coordinate_data));
// re-enable program flow after pause complete, where cycle start will resume the program. spindle_stop();
if (gc_state.modal.program_flow == PROGRAM_FLOW_COMPLETED) { mc_reset(); } coolant_stop();
else { gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; } // Resume from program pause.
} }
// TODO: % to denote start of program. Sets auto cycle start? report_feedback_message(MESSAGE_PROGRAM_END);
}
gc_state.modal.program_flow = PROGRAM_FLOW_RUNNING; // Reset program flow.
}
// TODO: % to denote start of program.
return(STATUS_OK); return(STATUS_OK);
} }

View File

@ -23,7 +23,7 @@
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "0.9i" #define GRBL_VERSION "0.9i"
#define GRBL_VERSION_BUILD "20150329" #define GRBL_VERSION_BUILD "20150516"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -22,9 +22,13 @@
#include "grbl.h" #include "grbl.h"
// Homing axis search distance multiplier. Computed by this value times the axis max travel. // Homing axis search distance multiplier. Computed by this value times the cycle travel.
#ifndef HOMING_AXIS_SEARCH_SCALAR
#define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged.
#endif
#ifndef HOMING_AXIS_LOCATE_SCALAR
#define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared.
#endif
void limits_init() void limits_init()
{ {
@ -126,16 +130,12 @@ void limits_go_home(uint8_t cycle_mask)
{ {
if (sys.abort) { return; } // Block if system reset has been issued. if (sys.abort) { return; } // Block if system reset has been issued.
// Initialize homing in search mode to quickly engage the specified cycle_mask limit switches. // Initialize
bool approach = true;
float homing_rate = settings.homing_seek_rate;
uint8_t invert_pin, idx;
uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
float target[N_AXIS];
uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS];
float target[N_AXIS];
float max_travel = 0.0; float max_travel = 0.0;
uint8_t idx;
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
// Initialize limit and step pin masks // Initialize limit and step pin masks
limit_pin[idx] = get_limit_pin_mask(idx); limit_pin[idx] = get_limit_pin_mask(idx);
@ -149,32 +149,33 @@ void limits_go_home(uint8_t cycle_mask)
// NOTE: settings.max_travel[] is stored as a negative value. // NOTE: settings.max_travel[] is stored as a negative value.
max_travel = max(max_travel,(-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]); max_travel = max(max_travel,(-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]);
} }
} }
plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. // Set search mode with approach at seek rate to quickly engage the specified cycle_mask limit switches.
plan_sync_position(); // Sync planner position to current machine position. bool approach = true;
float homing_rate = settings.homing_seek_rate;
uint8_t limit_state, axislock, n_active_axis;
do { do {
// Initialize invert_pin boolean based on approach and invert pin user setting.
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { invert_pin = approach; } system_convert_array_steps_to_mpos(target,sys.position);
else { invert_pin = !approach; }
// Initialize and declare variables needed for homing routine. // Initialize and declare variables needed for homing routine.
uint8_t axislock = 0; axislock = 0;
uint8_t n_active_axis = 0; n_active_axis = 0;
system_convert_array_steps_to_mpos(target,sys.position);
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
// Set target location for active axes and setup computation for homing rate. // Set target location for active axes and setup computation for homing rate.
if (bit_istrue(cycle_mask,bit(idx))) { if (bit_istrue(cycle_mask,bit(idx))) {
n_active_axis++; n_active_axis++;
sys.position[idx] = 0;
// Set target direction based on cycle mask and homing cycle approach state. // Set target direction based on cycle mask and homing cycle approach state.
// NOTE: This happens to compile smaller than any other implementation tried.
if (bit_istrue(settings.homing_dir_mask,bit(idx))) { if (bit_istrue(settings.homing_dir_mask,bit(idx))) {
if (approach) { target[idx] -= max_travel; } if (approach) { target[idx] = -max_travel; }
else { target[idx] += max_travel; } else { target[idx] = max_travel; }
} else { } else {
if (approach) { target[idx] += max_travel; } if (approach) { target[idx] = max_travel; }
else { target[idx] -= max_travel; } else { target[idx] = -max_travel; }
} }
// Apply axislock to the step port pins active in this cycle. // Apply axislock to the step port pins active in this cycle.
axislock |= step_pin[idx]; axislock |= step_pin[idx];
@ -184,9 +185,9 @@ void limits_go_home(uint8_t cycle_mask)
homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate. homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate.
sys.homing_axis_lock = axislock; sys.homing_axis_lock = axislock;
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle. plan_sync_position(); // Sync planner position to current machine position.
uint8_t limit_state;
// Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle.
#ifdef USE_LINE_NUMBERS #ifdef USE_LINE_NUMBERS
plan_buffer_line(target, homing_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion. plan_buffer_line(target, homing_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion.
#else #else
@ -196,36 +197,53 @@ void limits_go_home(uint8_t cycle_mask)
st_prep_buffer(); // Prep and fill segment buffer from newly planned block. st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
st_wake_up(); // Initiate motion st_wake_up(); // Initiate motion
do { do {
if (approach) {
// Check limit state. Lock out cycle axes when they change. // Check limit state. Lock out cycle axes when they change.
limit_state = LIMIT_PIN; limit_state = LIMIT_PIN;
if (invert_pin) { limit_state ^= LIMIT_MASK; } if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; }
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
if (axislock & step_pin[idx]) { if (axislock & step_pin[idx]) {
if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); } if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); }
} }
} }
sys.homing_axis_lock = axislock; sys.homing_axis_lock = axislock;
}
st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
// Exit routines: User abort homing and alarm upon safety door or no limit switch found. // Exit routines: User abort homing and alarm upon safety door or no limit switch found.
// No time to run protocol_execute_realtime() in this loop. // No time to run protocol_execute_realtime() in this loop.
if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) {
if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_CYCLE_STOP)) { mc_reset(); } if ((sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) ||
((approach) && (sys.rt_exec_state & EXEC_CYCLE_STOP))) {
mc_reset();
protocol_execute_realtime(); protocol_execute_realtime();
return; return;
} else {
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
break;
} }
}
} while (STEP_MASK & axislock); } while (STEP_MASK & axislock);
st_reset(); // Immediately force kill steppers and reset step segment buffer. st_reset(); // Immediately force kill steppers and reset step segment buffer.
plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions.
plan_sync_position(); // Sync planner position to current machine position
delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate.
// Reverse direction and reset homing rate for locate cycle(s). // Reverse direction and reset homing rate for locate cycle(s).
homing_rate = settings.homing_feed_rate;
approach = !approach; approach = !approach;
// After first cycle, homing enters locating phase. Shorten search to pull-off distance.
if (approach) {
max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR;
homing_rate = settings.homing_feed_rate;
} else {
max_travel = settings.homing_pulloff;
homing_rate = settings.homing_seek_rate;
}
} while (n_cycle-- > 0); } while (n_cycle-- > 0);
// The active cycle axes should now be homed and machine limits have been located. By // The active cycle axes should now be homed and machine limits have been located. By
@ -242,10 +260,13 @@ void limits_go_home(uint8_t cycle_mask)
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
// NOTE: settings.max_travel[] is stored as a negative value. // NOTE: settings.max_travel[] is stored as a negative value.
if (cycle_mask & bit(idx)) { if (cycle_mask & bit(idx)) {
#ifdef HOMING_FORCE_SET_ORIGIN
set_axis_position = 0; set_axis_position = 0;
#ifndef HOMING_FORCE_SET_ORIGIN #else
if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) { if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
set_axis_position = lround(settings.max_travel[idx]*settings.steps_per_mm[idx]); set_axis_position = lround((settings.max_travel[idx]+settings.homing_pulloff)*settings.steps_per_mm[idx]);
} else {
set_axis_position = lround(-settings.homing_pulloff*settings.steps_per_mm[idx]);
} }
#endif #endif
@ -269,39 +290,6 @@ void limits_go_home(uint8_t cycle_mask)
} }
plan_sync_position(); // Sync planner position to homed machine position. plan_sync_position(); // Sync planner position to homed machine position.
// Set pull-off motion target. Seperated from above loop if target is dependent on sys.position.
if (settings.homing_pulloff > 0.0) {
for (idx=0; idx<N_AXIS; idx++) {
if (cycle_mask & bit(idx)) {
#ifdef HOMING_FORCE_SET_ORIGIN
target[idx] = settings.homing_pulloff;
if ( bit_isfalse(settings.homing_dir_mask,bit(idx)) ) { target[idx] = -target[idx]; }
#else
if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) {
target[idx] = settings.homing_pulloff+settings.max_travel[idx];
} else {
target[idx] = -settings.homing_pulloff;
}
#endif
} else {
// Non-active cycle axis. Set target to not move during pull-off.
target[idx] = system_convert_axis_steps_to_mpos(sys.position, idx);
}
}
#ifdef USE_LINE_NUMBERS
plan_buffer_line(target, settings.homing_seek_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan motion.
#else
plan_buffer_line(target, settings.homing_seek_rate, false); // Bypass mc_line(). Directly plan motion.
#endif
// Initiate pull-off using main motion control routines.
// TODO : Clean up state routines so that this motion still shows homing state.
sys.state = STATE_IDLE;
bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START);
protocol_execute_realtime();
protocol_buffer_synchronize(); // Complete pull-off motion.
}
// Set system state to homing before returning. // Set system state to homing before returning.
sys.state = STATE_HOMING; sys.state = STATE_HOMING;
} }

View File

@ -136,6 +136,8 @@ void report_feedback_message(uint8_t message_code)
printPgmString(PSTR("Disabled")); break; printPgmString(PSTR("Disabled")); break;
case MESSAGE_SAFETY_DOOR_AJAR: case MESSAGE_SAFETY_DOOR_AJAR:
printPgmString(PSTR("Check Door")); break; printPgmString(PSTR("Check Door")); break;
case MESSAGE_PROGRAM_END:
printPgmString(PSTR("Pgm End")); break;
} }
printPgmString(PSTR("]\r\n")); printPgmString(PSTR("]\r\n"));
} }
@ -420,7 +422,7 @@ void report_realtime_status()
// the system power on location (0,0,0) and work coordinate position (G54 and G92 applied). Eventually // the system power on location (0,0,0) and work coordinate position (G54 and G92 applied). Eventually
// to be added are distance to go on block, processed block id, and feed rate. Also a settings bitmask // to be added are distance to go on block, processed block id, and feed rate. Also a settings bitmask
// for a user to select the desired real-time data. // for a user to select the desired real-time data.
uint8_t i; uint8_t idx;
int32_t current_position[N_AXIS]; // Copy current state of the system position variable int32_t current_position[N_AXIS]; // Copy current state of the system position variable
memcpy(current_position,sys.position,sizeof(sys.position)); memcpy(current_position,sys.position,sizeof(sys.position));
float print_position[N_AXIS]; float print_position[N_AXIS];
@ -445,21 +447,21 @@ void report_realtime_status()
// Report machine position // Report machine position
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_MACHINE_POSITION)) { if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_MACHINE_POSITION)) {
printPgmString(PSTR(",MPos:")); printPgmString(PSTR(",MPos:"));
for (i=0; i< N_AXIS; i++) { for (idx=0; idx< N_AXIS; idx++) {
printFloat_CoordValue(print_position[i]); printFloat_CoordValue(print_position[idx]);
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } if (idx < (N_AXIS-1)) { printPgmString(PSTR(",")); }
} }
} }
// Report work position // Report work position
if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_WORK_POSITION)) { if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_WORK_POSITION)) {
printPgmString(PSTR(",WPos:")); printPgmString(PSTR(",WPos:"));
for (i=0; i< N_AXIS; i++) { for (idx=0; idx< N_AXIS; idx++) {
// Apply work coordinate offsets and tool length offset to current position. // Apply work coordinate offsets and tool length offset to current position.
print_position[i] -= gc_state.coord_system[i]+gc_state.coord_offset[i]; print_position[idx] -= gc_state.coord_system[idx]+gc_state.coord_offset[idx];
if (i == TOOL_LENGTH_OFFSET_AXIS) { print_position[i] -= gc_state.tool_length_offset; } if (idx == TOOL_LENGTH_OFFSET_AXIS) { print_position[idx] -= gc_state.tool_length_offset; }
printFloat_CoordValue(print_position[i]); printFloat_CoordValue(print_position[idx]);
if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } if (idx < (N_AXIS-1)) { printPgmString(PSTR(",")); }
} }
} }
@ -492,14 +494,13 @@ void report_realtime_status()
printFloat_RateValue(st_get_realtime_rate()); printFloat_RateValue(st_get_realtime_rate());
#endif #endif
#ifdef REPORT_LIMIT_PIN_STATE if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) {
printPgmString(PSTR(",Lim:")); printPgmString(PSTR(",Lim:"));
uint8_t idx;
for (idx=0; idx<N_AXIS; idx++) { for (idx=0; idx<N_AXIS; idx++) {
if (LIMIT_PIN & get_limit_pin_mask(idx)) { printString(PSTR("1")); } if (LIMIT_PIN & get_limit_pin_mask(idx)) { printPgmString(PSTR("1")); }
else { printString(PSTR("0")); } else { printPgmString(PSTR("0")); }
}
} }
#endif
#ifdef REPORT_CONTROL_PIN_STATE #ifdef REPORT_CONTROL_PIN_STATE
printPgmString(PSTR(",Ctl:")); printPgmString(PSTR(",Ctl:"));

View File

@ -68,6 +68,7 @@
#define MESSAGE_ENABLED 4 #define MESSAGE_ENABLED 4
#define MESSAGE_DISABLED 5 #define MESSAGE_DISABLED 5
#define MESSAGE_SAFETY_DOOR_AJAR 6 #define MESSAGE_SAFETY_DOOR_AJAR 6
#define MESSAGE_PROGRAM_END 7
// Prints system status messages. // Prints system status messages.
void report_status_message(uint8_t status_code); void report_status_message(uint8_t status_code);

View File

@ -44,6 +44,7 @@
#define BITFLAG_RT_STATUS_WORK_POSITION bit(1) #define BITFLAG_RT_STATUS_WORK_POSITION bit(1)
#define BITFLAG_RT_STATUS_PLANNER_BUFFER bit(2) #define BITFLAG_RT_STATUS_PLANNER_BUFFER bit(2)
#define BITFLAG_RT_STATUS_SERIAL_RX bit(3) #define BITFLAG_RT_STATUS_SERIAL_RX bit(3)
#define BITFLAG_RT_STATUS_LIMIT_PINS bit(4)
// Define EEPROM memory address location values for Grbl settings and parameters // Define EEPROM memory address location values for Grbl settings and parameters
// NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and // NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and

View File

@ -324,11 +324,8 @@ ISR(TIMER1_COMPA_vect)
st.exec_block = &st_block_buffer[st.exec_block_index]; st.exec_block = &st_block_buffer[st.exec_block_index];
// Initialize Bresenham line and distance counters // Initialize Bresenham line and distance counters
st.counter_x = (st.exec_block->step_event_count >> 1); st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1);
st.counter_y = st.counter_x;
st.counter_z = st.counter_x;
} }
st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask; st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask;
#ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING

View File

@ -71,7 +71,7 @@
typedef struct { typedef struct {
uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
uint8_t state; // Tracks the current state of Grbl. uint8_t state; // Tracks the current state of Grbl.
uint8_t suspend; // System suspend flag. Allows only realtime commands. Used primarily for holds. uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door.
volatile uint8_t rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks.
volatile uint8_t rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. volatile uint8_t rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms.