Homing and limit updates. Minor bug fixes.
- Updated new homing cycle to error out when a pull-off motion detects the limit is still active. - Created a limits_get_state() function to centralize it. It reports state as a bit-wise booleans according to axis numbering. - Updated the print uint8 functions. Generalized it to allow both base2 and base10 printouts, while allowing base2 prints with N_AXIS digits for limit state status reports. Doing this saved about 100bytes of flash as well. - Applied CoreXY status reporting bug fix by @phd0. Thanks!
This commit is contained in:
@ -55,6 +55,7 @@ void limits_init()
|
||||
}
|
||||
|
||||
|
||||
// Disables hard limits.
|
||||
void limits_disable()
|
||||
{
|
||||
LIMIT_PCMSK &= ~LIMIT_MASK; // Disable specific pins of the Pin Change Interrupt
|
||||
@ -62,6 +63,24 @@ void limits_disable()
|
||||
}
|
||||
|
||||
|
||||
// Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where
|
||||
// triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their
|
||||
// number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1.
|
||||
uint8_t limits_get_state()
|
||||
{
|
||||
uint8_t limit_state = 0;
|
||||
uint8_t pin = (LIMIT_PIN & LIMIT_MASK);
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; }
|
||||
if (pin) {
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (pin & get_limit_pin_mask(idx)) { limit_state |= (1 << idx); }
|
||||
}
|
||||
}
|
||||
return(limit_state);
|
||||
}
|
||||
|
||||
|
||||
// This is the Limit Pin Change Interrupt, which handles the hard limit feature. A bouncing
|
||||
// limit switch can cause a lot of problems, like false readings and multiple interrupt calls.
|
||||
// If a switch is triggered at all, something bad has happened and treat it as such, regardless
|
||||
@ -84,10 +103,8 @@ void limits_disable()
|
||||
if (sys.state != STATE_ALARM) {
|
||||
if (!(sys.rt_exec_alarm)) {
|
||||
#ifdef HARD_LIMIT_FORCE_STATE_CHECK
|
||||
uint8_t bits = (LIMIT_PIN & LIMIT_MASK);
|
||||
// Check limit pin state.
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits) {
|
||||
if (limits_get_state()) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
|
||||
}
|
||||
@ -106,10 +123,8 @@ void limits_disable()
|
||||
WDTCSR &= ~(1<<WDIE); // Disable watchdog timer.
|
||||
if (sys.state != STATE_ALARM) { // Ignore if already in alarm state.
|
||||
if (!(sys.rt_exec_alarm)) {
|
||||
uint8_t bits = (LIMIT_PIN & LIMIT_MASK);
|
||||
// Check limit pin state.
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
|
||||
if (bits) {
|
||||
if (limits_get_state()) {
|
||||
mc_reset(); // Initiate system kill.
|
||||
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event
|
||||
}
|
||||
@ -118,7 +133,7 @@ void limits_disable()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Homes the specified cycle axes, sets the machine position, and performs a pull-off motion after
|
||||
// completing. Homing is a special motion case, which involves rapid uncontrolled stops to locate
|
||||
// the trigger point of the limit switches. The rapid stops are handled by a system level axis lock
|
||||
@ -132,13 +147,12 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
|
||||
// Initialize
|
||||
uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1);
|
||||
uint8_t limit_pin[N_AXIS], step_pin[N_AXIS];
|
||||
uint8_t step_pin[N_AXIS];
|
||||
float target[N_AXIS];
|
||||
float max_travel = 0.0;
|
||||
uint8_t idx;
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
// Initialize limit and step pin masks
|
||||
limit_pin[idx] = get_limit_pin_mask(idx);
|
||||
// Initialize step pin masks
|
||||
step_pin[idx] = get_step_pin_mask(idx);
|
||||
#ifdef COREXY
|
||||
if ((idx==A_MOTOR)||(idx==B_MOTOR)) { step_pin[idx] = (get_step_pin_mask(X_AXIS)|get_step_pin_mask(Y_AXIS)); }
|
||||
@ -199,11 +213,10 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
do {
|
||||
if (approach) {
|
||||
// Check limit state. Lock out cycle axes when they change.
|
||||
limit_state = LIMIT_PIN;
|
||||
if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; }
|
||||
limit_state = limits_get_state();
|
||||
for (idx=0; idx<N_AXIS; idx++) {
|
||||
if (axislock & step_pin[idx]) {
|
||||
if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); }
|
||||
if (limit_state & (1 << idx)) { axislock &= ~(step_pin[idx]); }
|
||||
}
|
||||
}
|
||||
sys.homing_axis_lock = axislock;
|
||||
@ -211,16 +224,18 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
|
||||
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.
|
||||
// No time to run protocol_execute_realtime() in this loop.
|
||||
// Exit routines: 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)) ||
|
||||
((approach) && (sys.rt_exec_state & EXEC_CYCLE_STOP))) {
|
||||
mc_reset();
|
||||
// Homing failure: Limit switches are still engaged after pull-off motion
|
||||
if ( (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) || // Safety door or reset issued
|
||||
(!approach && (limits_get_state() & cycle_mask)) || // Limit switch still engaged after pull-off motion
|
||||
( approach && (sys.rt_exec_state & EXEC_CYCLE_STOP)) ) { // Limit switch not found during approach.
|
||||
mc_reset(); // Stop motors, if they are running.
|
||||
protocol_execute_realtime();
|
||||
return;
|
||||
} else {
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
|
||||
// Pull-off motion complete. Disable CYCLE_STOP from executing.
|
||||
bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -245,7 +260,7 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
|
||||
} while (n_cycle-- > 0);
|
||||
|
||||
|
||||
// The active cycle axes should now be homed and machine limits have been located. By
|
||||
// default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches
|
||||
// can be on either side of an axes, check and set axes machine zero appropriately. Also,
|
||||
@ -289,9 +304,8 @@ void limits_go_home(uint8_t cycle_mask)
|
||||
}
|
||||
}
|
||||
plan_sync_position(); // Sync planner position to homed machine position.
|
||||
|
||||
// Set system state to homing before returning.
|
||||
sys.state = STATE_HOMING;
|
||||
|
||||
// sys.state = STATE_HOMING; // Ensure system state set as homing before returning.
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user