Exemple #1
0
// 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);
}
Exemple #2
0
// 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; 
}