bool Endstops::load_config()
{
bool limit_enabled= false;
+ size_t max_index= 0;
std::array<homing_info_t, k_max_actuators> temp_axis_array; // needs to be at least XYZ, but allow for ABC
{
continue;
}
+ // keep track of the maximum index that has been defined
+ if(i > max_index) max_index= i;
+
// init pin struct
pin_info->debounce= 0;
pin_info->axis= toupper(axis[0]);
// if no pins defined then disable the module
if(endstops.empty()) return false;
- // copy to the homing_axis array
+ // copy to the homing_axis array, make sure that undefined entries are filled in as well
+ // as the order is important and all slots must be filled upto the max_index
for (size_t i = 0; i < temp_axis_array.size(); ++i) {
if(temp_axis_array[i].axis == 0) {
// was not configured above, if it is XYZ then we need to force a dummy entry
t.axis_index= i;
t.pin_info= nullptr; // this tells it that it cannot be used for homing
homing_axis.push_back(t);
+
+ }else if(i <= max_index) {
+ // for instance case where we defined C without A or B
+ homing_info_t t;
+ t.axis= 'A' + i;
+ t.axis_index= i;
+ t.pin_info= nullptr; // this tells it that it cannot be used for homing
+ homing_axis.push_back(t);
}
}else{
slow_rate= homing_axis[Z_AXIS].slow_rate;
} else {
- // cartesians, concatenate all the moves we need to do into one gcode
+ // cartesians concatenate all the moves we need to do into one gcode
for( auto& e : homing_axis) {
if(!axis[e.axis_index]) continue; // only for axes we asked to move
// check that the endstops were hit and it did not stop short for some reason
// if the endstop is not triggered then enter ALARM state
- // with deltas we check all three axis were triggered
- for (size_t i = X_AXIS; i <= Z_AXIS; ++i) {
- if((axis_to_home[i] || this->is_delta || this->is_rdelta) && !homing_axis[i].pin_info->triggered) {
- this->status = NOT_HOMING;
- THEKERNEL->call_event(ON_HALT, nullptr);
- return;
+ // with deltas we check all three axis were triggered, but at least one of XYZ must be set to home
+ if(axis_to_home[X_AXIS] || axis_to_home[Y_AXIS] || axis_to_home[Z_AXIS]) {
+ for (size_t i = X_AXIS; i <= Z_AXIS; ++i) {
+ if((axis_to_home[i] || this->is_delta || this->is_rdelta) && !homing_axis[i].pin_info->triggered) {
+ this->status = NOT_HOMING;
+ THEKERNEL->call_event(ON_HALT, nullptr);
+ return;
+ }
}
}
THEROBOT->compensationTransform= nullptr;
// deltas always home Z axis only, which moves all three actuators
- bool home_in_z = this->is_delta || this->is_rdelta;
+ bool home_in_z_only = this->is_delta || this->is_rdelta;
// figure out which axis to home
axis_bitmap_t haxis;
haxis.reset();
- if(!home_in_z) { // ie not a delta
- bool axis_speced = (gcode->has_letter('X') || gcode->has_letter('Y') || gcode->has_letter('Z') ||
- gcode->has_letter('A') || gcode->has_letter('B') || gcode->has_letter('C'));
+ bool axis_speced = (gcode->has_letter('X') || gcode->has_letter('Y') || gcode->has_letter('Z') ||
+ gcode->has_letter('A') || gcode->has_letter('B') || gcode->has_letter('C'));
+ if(!home_in_z_only) { // ie not a delta
for (auto &p : homing_axis) {
// only enable homing if the endstop is defined,
if(p.pin_info == nullptr) continue;
}
} else {
- // Only Z axis homes (even though all actuators move this is handled by arm solution)
- haxis.set(Z_AXIS);
- // we also set the kinematics to a known good position, this is necessary for a rotary delta, but doesn't hurt for linear delta
- THEROBOT->reset_axis_position(0, 0, 0);
+ bool home_z= !axis_speced || gcode->has_letter('X') || gcode->has_letter('Y') || gcode->has_letter('Z');
+
+ // if we specified an axis we check ABC
+ for (size_t i = A_AXIS; i < homing_axis.size(); ++i) {
+ auto &p= homing_axis[i];
+ if(p.pin_info == nullptr) continue;
+ if(!axis_speced || gcode->has_letter(p.axis)) haxis.set(p.axis_index);
+ }
+
+ if(home_z){
+ // Only Z axis homes (even though all actuators move this is handled by arm solution)
+ haxis.set(Z_AXIS);
+ // we also set the kinematics to a known good position, this is necessary for a rotary delta, but doesn't hurt for linear delta
+ THEROBOT->reset_axis_position(0, 0, 0);
+ }
+ }
+
+ if(haxis.none()) {
+ THEKERNEL->streams->printf("WARNING: Nothing to home\n");
+ return;
}
// do the actual homing
// check if on_halt (eg kill or fail)
if(THEKERNEL->is_halted()) {
if(!THEKERNEL->is_grbl_mode()) {
- THEKERNEL->streams->printf("ERROR: Homing cycle failed\n");
+ THEKERNEL->streams->printf("ERROR: Homing cycle failed - check the max_travel settings\n");
}else{
THEKERNEL->streams->printf("ALARM: Homing fail\n");
}
return;
}
- if(home_in_z || is_scara) { // deltas and scaras only
+ if(home_in_z_only || is_scara) { // deltas and scaras only
// Here's where we would have been if the endstops were perfectly trimmed
// NOTE on a rotary delta home_offset is actuator position in degrees when homed and
// home_offset is the theta offset for each actuator, so M206 is used to set theta offset for each actuator in degrees
}
}
- // for deltas we say all axis are homed even though it was only Z
- for (auto &p : homing_axis) p.homed= true;
+ // for deltas we say all 3 axis are homed even though it was only Z
+ homing_axis[X_AXIS].homed= true;
+ homing_axis[Y_AXIS].homed= true;
+ homing_axis[Z_AXIS].homed= true;
+
+ // if we also homed ABC then we need to reset them
+ for (size_t i = A_AXIS; i < homing_axis.size(); ++i) {
+ auto &p= homing_axis[i];
+ if (haxis[p.axis_index]) { // if we requested this axis to home
+ THEROBOT->reset_axis_position(p.homing_position + p.home_offset, p.axis_index);
+ // set flag indicating axis was homed, it stays set once set until H/W reset or unhomed
+ p.homed= true;
+ }
+ }
} else {
// Zero the ax(i/e)s position, add in the home offset
// if limit switches are enabled we must back off endstop after setting home
back_off_home(haxis);
- } else if(this->move_to_origin_after_home || homing_axis[X_AXIS].pin_info->limit_enable) {
+ } else if(haxis[Z_AXIS] && (this->move_to_origin_after_home || homing_axis[X_AXIS].pin_info->limit_enable)) {
// deltas are not left at 0,0 because of the trim settings, so move to 0,0 if requested, but we need to back off endstops first
// also need to back off endstops if limits are enabled
back_off_home(haxis);
bool *homing = static_cast<bool *>(pdr->get_data_ptr());
*homing = this->status != NOT_HOMING;
pdr->set_taken();
+
+ } else if(pdr->second_element_is(get_homed_status_checksum)) {
+ bool *homed = static_cast<bool *>(pdr->get_data_ptr());
+ for (int i = 0; i < 3; ++i) {
+ homed[i]= homing_axis[i].homed;
+ }
+ pdr->set_taken();
}
}