// 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); }
// 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 // mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically // circumvent the processes for executing motions in normal operation. // NOTE: Only the abort runtime command can interrupt this process. void limits_go_home(uint8_t cycle_mask) { 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. 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); ///***5 float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; float max_travel = 0.0; for (idx=0; idx<N_AXIS; idx++) { // Initialize limit and step pin masks limit_pin[idx] = get_limit_pin_mask(idx); ///////****get the Pin of limit min x, y ,z , Limit OK step_pin[idx] = get_step_pin_mask(idx); ///////****get the Pin of limit min x, y ,z now I let it 0, 1, 2 // Determine travel distance to the furthest homing switch based on user max travel settings. // NOTE: settings.max_travel[] is stored as a negative value. if (max_travel > settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } } max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. 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; } else { invert_pin = !approach; } // Initialize and declare variables needed for homing routine. uint8_t n_active_axis = 0; uint8_t axislock = 0; for (idx=0; idx<N_AXIS; idx++) { // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; if (!approach) { target[idx] = -max_travel; } else { target[idx] = max_travel; } } else { target[idx] = 0.0; } // Set target direction based on cycle mask if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] = -target[idx]; } // Apply axislock to the step port pins active in this cycle. if (bit_istrue(cycle_mask,bit(idx))) { axislock |= step_pin[idx]; } } homing_rate *= sqrt(n_active_axis); // [sqrt(N_AXIS)] Adjust so individual axes all move at homing rate. sys.homing_axis_lock = axislock; // Perform homing cycle. Planner buffer should be empty, as required to initiate the homing cycle. uint8_t limit_state; #ifdef USE_LINE_NUMBERS plan_buffer_line(target, homing_rate, false, HOMING_CYCLE_LINE_NUMBER); // Bypass mc_line(). Directly plan homing motion. #else plan_buffer_line(target, homing_rate, false); // Bypass mc_line(). Directly plan homing motion. #endif st_prep_buffer(); // Prep and fill segment buffer from newly planned block. st_wake_up(); // Initiate motion do { // Check limit state. Lock out cycle axes when they change. /////////////////########################################*********** #if MotherBoard==3 /////**MB==3 #ifdef limit_int_style limit_state = LIMIT_PIN; if (invert_pin) { limit_state ^= LIMIT_MASK; } #else //************Get Limit Pin State. PiBot get limit/endstop mask same with the step mask. #if LIMIT_MAX_OPEN if(isXMinEndstopHit()) { limit_state^= MASK(X_LIMIT_BIT);} ////***read X_endstop then write into limite_state if(isYMinEndstopHit()) { limit_state^= MASK(Y_LIMIT_BIT);} if(isZMinEndstopHit()) { limit_state^= MASK(Z_LIMIT_BIT);} ////*****add MAX limit if(isXMaxEndstopHit()) { limit_state^= MASK(X_LIMIT_MAX_BIT);} ////***read X_endstop then write into limite_state if(isYMaxEndstopHit()) { limit_state^= MASK(Y_LIMIT_MAX_BIT);} if(isZMaxEndstopHit()) { limit_state^= MASK(Z_LIMIT_MAX_BIT);} ////*****add MAX limit #else if(isXMinEndstopHit()) { limit_state^= MASK(X_MASK);} ////***read X_endstop then write into limite_state if(isYMinEndstopHit()) { limit_state^= MASK(Y_MASK);} if(isZMinEndstopHit()) { limit_state^= MASK(Z_MASK);} ////*****add MAX limit #endif #endif #else /////**MB!=3 ////////################################################# limit_state = LIMIT_PIN; if (invert_pin) { limit_state ^= LIMIT_MASK; } #endif /////**MB==3 /////////////////////////////##################################### for (idx=0; idx<N_AXIS; idx++) { if (axislock & step_pin[idx]) { if (limit_state & limit_pin[idx]) { axislock &= ~(step_pin[idx]); } } } sys.homing_axis_lock = axislock; st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // Check only for user reset. No time to run protocol_execute_runtime() in this loop. if (sys.execute & EXEC_RESET) { protocol_execute_runtime(); return; } } while (STEP_MASK & axislock); st_reset(); // Immediately force kill steppers and reset step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared. delay_ms(settings.homing_debounce_delay); // Delay to allow transient dynamics to dissipate. // Reverse direction and reset homing rate for locate cycle(s). homing_rate = settings.homing_feed_rate; approach = !approach; } 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, // set up pull-off maneuver from axes limit switches that have been homed. This provides // some initial clearance off the switches and should also help prevent them from falsely // triggering when hard limits are enabled or when more than one axes shares a limit pin. for (idx=0; idx<N_AXIS; idx++) { // Set up pull off targets and machine positions for limit switches homed in the negative // direction, rather than the traditional positive. Leave non-homed positions as zero and // do not move them. // NOTE: settings.max_travel[] is stored as a negative value. if (cycle_mask & bit(idx)) { #ifdef HOMING_FORCE_SET_ORIGIN sys.position[idx] = 0; // Set axis homed location as axis 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]; sys.position[idx] = lround(settings.max_travel[idx]*settings.steps_per_mm[idx]); } else { target[idx] = -settings.homing_pulloff; sys.position[idx] = 0; } #endif } else { // Non-active cycle axis. Set target to not move during pull-off. target[idx] = (float)sys.position[idx]/settings.steps_per_mm[idx]; } } plan_sync_position(); // Sync planner position to current machine position for pull-off move. #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_QUEUED; bit_true_atomic(sys.execute, EXEC_CYCLE_START); protocol_execute_runtime(); protocol_buffer_synchronize(); // Complete pull-off motion. // Set system state to homing before returning. sys.state = STATE_HOMING; }