static stat_t _homing_error_exit(int8_t axis) { // Generate the warning message. Since the error exit returns via the homing callback // - and not the main controller - it requires its own display processing cmd_reset_list(); if (axis == -2) { cmd_add_conditional_message((const char_t *)"*** WARNING *** Homing error: Specified axis(es) cannot be homed");; } else { char message[CMD_MESSAGE_LEN]; sprintf_P(message, PSTR("*** WARNING *** Homing error: %c axis settings misconfigured"), cm_get_axis_char(axis)); cmd_add_conditional_message((char_t *)message); } cmd_print_list(STAT_HOMING_CYCLE_FAILED, TEXT_INLINE_VALUES, JSON_RESPONSE_FORMAT); // clean up and exit mp_flush_planner(); // should be stopped, but in case of switch closure // don't use cm_request_queue_flush() here cm_set_coord_system(hm.saved_coord_system); // restore to work coordinate system cm_set_units_mode(hm.saved_units_mode); cm_set_distance_mode(hm.saved_distance_mode); cm_set_feed_rate(hm.saved_feed_rate); cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); cm.cycle_state = CYCLE_OFF; cm_cycle_end(); return (STAT_HOMING_CYCLE_FAILED); // homing state remains HOMING_NOT_HOMED }
static stat_t _homing_axis_start(int8_t axis) { // get the first or next axis if ((axis = _get_next_axis(axis)) < 0) { // axes are done or error if (axis == -1) { // -1 is done return (_set_homing_func(_homing_finalize_exit)); } else if (axis == -2) { // -2 is error cm_set_units_mode(hm.saved_units_mode); cm_set_distance_mode(hm.saved_distance_mode); cm.cycle_state = CYCLE_OFF; cm_cycle_end(); return (_homing_error_exit(-2)); } } // trap gross mis-configurations if ((fp_ZERO(cm.a[axis].search_velocity)) || (fp_ZERO(cm.a[axis].latch_velocity))) { return (_homing_error_exit(axis)); } if ((cm.a[axis].travel_max <= 0) || (cm.a[axis].latch_backoff <= 0)) { return (_homing_error_exit(axis)); } // determine the switch setup and that config is OK hm.min_mode = get_switch_mode(MIN_SWITCH(axis)); hm.max_mode = get_switch_mode(MAX_SWITCH(axis)); if ( ((hm.min_mode & SW_HOMING_BIT) ^ (hm.max_mode & SW_HOMING_BIT)) == 0) {// one or the other must be homing return (_homing_error_exit(axis)); // axis cannot be homed } hm.axis = axis; // persist the axis hm.search_velocity = fabs(cm.a[axis].search_velocity); // search velocity is always positive hm.latch_velocity = fabs(cm.a[axis].latch_velocity); // latch velocity is always positive // setup parameters homing to the minimum switch if (hm.min_mode & SW_HOMING_BIT) { hm.homing_switch = MIN_SWITCH(axis); // the min is the homing switch hm.limit_switch = MAX_SWITCH(axis); // the max would be the limit switch hm.search_travel = -cm.a[axis].travel_max; // search travels in negative direction hm.latch_backoff = cm.a[axis].latch_backoff; // latch travels in positive direction hm.zero_backoff = cm.a[axis].zero_backoff; // setup parameters for positive travel (homing to the maximum switch) } else { hm.homing_switch = MAX_SWITCH(axis); // the max is the homing switch hm.limit_switch = MIN_SWITCH(axis); // the min would be the limit switch hm.search_travel = cm.a[axis].travel_max; // search travels in positive direction hm.latch_backoff = -cm.a[axis].latch_backoff; // latch travels in negative direction hm.zero_backoff = -cm.a[axis].zero_backoff; } // if homing is disabled for the axis then skip to the next axis uint8_t sw_mode = get_switch_mode(hm.homing_switch); if ((sw_mode != SW_MODE_HOMING) && (sw_mode != SW_MODE_HOMING_LIMIT)) { return (_set_homing_func(_homing_axis_start)); } // disable the limit switch parameter if there is no limit switch if (get_switch_mode(hm.limit_switch) == SW_MODE_DISABLED) { hm.limit_switch = -1;} hm.saved_jerk = cm.a[axis].jerk_max; // save the max jerk value return (_set_homing_func(_homing_axis_clear)); // start the clear }
void cm_init() { memset(&cm, 0, sizeof(cm)); // reset canonicalMachineSingleton memset(&gn, 0, sizeof(gn)); // clear all values, pointers and status memset(&gf, 0, sizeof(gf)); memset(&gm, 0, sizeof(gm)); // set gcode defaults cm_set_units_mode(cfg.units_mode); cm_set_coord_system(cfg.coord_system); cm_select_plane(cfg.select_plane); cm_set_path_control(cfg.path_control); cm_set_distance_mode(cfg.distance_mode); }
static stat_t _homing_finalize_exit(int8_t axis) // third part of return to home { mp_flush_planner(); // should be stopped, but in case of switch closure. // don't use cm_request_queue_flush() here cm_set_coord_system(hm.saved_coord_system); // restore to work coordinate system cm_set_units_mode(hm.saved_units_mode); cm_set_distance_mode(hm.saved_distance_mode); cm_set_feed_rate(hm.saved_feed_rate); cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); cm.cycle_state = CYCLE_OFF; // required cm_cycle_end(); return (STAT_OK); }
static uint8_t _probing_init() { float start_position[AXES]; // so optimistic... ;) // NOTE: it is *not* an error condition for the probe not to trigger. // it is an error for the limit or homing switches to fire, or for some other configuration error. cm.probe_state = PROBE_FAILED; cm.machine_state = MACHINE_CYCLE; cm.cycle_state = CYCLE_PROBE; // save relevant non-axis parameters from Gcode model pb.saved_coord_system = cm_get_coord_system(ACTIVE_MODEL); pb.saved_distance_mode = cm_get_distance_mode(ACTIVE_MODEL); // set working values cm_set_distance_mode(ABSOLUTE_MODE); cm_set_coord_system(ABSOLUTE_COORDS); // probing is done in machine coordinates // initialize the axes - save the jerk settings & switch to the jerk_homing settings for( uint8_t axis=0; axis<AXES; axis++ ) { pb.saved_jerk[axis] = cm_get_axis_jerk(axis); // save the max jerk value cm_set_axis_jerk(axis, cm.a[axis].jerk_high); // use the high-speed jerk for probe start_position[axis] = cm_get_absolute_position(ACTIVE_MODEL, axis); } // error if the probe target is too close to the current position if (get_axis_vector_length(start_position, pb.target) < MINIMUM_PROBE_TRAVEL) { _probing_error_exit(-2); } // error if the probe target requires a move along the A/B/C axes for ( uint8_t axis=AXIS_A; axis<AXES; axis++ ) { // if (fp_NE(start_position[axis], pb.target[axis])) { // old style if (fp_TRUE(pb.flags[axis])) { // if (pb.flags[axis]) { // will reduce to this once flags are booleans _probing_error_exit(axis); } } // initialize the probe switch pb.probe_input = 5; // TODO -- for now we hard code it to zmin gpio_set_probing_mode(pb.probe_input, true); // turn off spindle and start the move cm_spindle_optional_pause(true); // pause the spindle if it's on return (_set_pb_func(_probing_start)); // start the probe move }
static stat_t _homing_finalize_exit(int8_t axis) // third part of return to home { mp_flush_planner(); // should be stopped, but in case of switch closure. // don't use cm_request_queue_flush() here cm_set_coord_system(hm.saved_coord_system); // restore to work coordinate system cm_set_units_mode(hm.saved_units_mode); cm_set_distance_mode(hm.saved_distance_mode); cm_set_feed_rate(hm.saved_feed_rate); cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); cm.homing_state = HOMING_HOMED; cm.cycle_state = CYCLE_OFF; // required cm_cycle_end(); //+++++ DIAGNOSTIC +++++ // printf("Homed: posX: %6.3f, posY: %6.3f\n", (double)gm.position[AXIS_X], (double)gm.target[AXIS_Y]); return (STAT_OK); }
stat_t cm_homing_cycle_start(void) { // save relevant non-axis parameters from Gcode model hm.saved_units_mode = gm.units_mode; hm.saved_coord_system = gm.coord_system; hm.saved_distance_mode = gm.distance_mode; hm.saved_feed_rate = gm.feed_rate; // set working values cm_set_units_mode(MILLIMETERS); cm_set_distance_mode(INCREMENTAL_MODE); cm_set_coord_system(ABSOLUTE_COORDS); // homing is done in machine coordinates hm.set_coordinates = true; hm.axis = -1; // set to retrieve initial axis hm.func = _homing_axis_start; // bind initial processing function cm.cycle_state = CYCLE_HOMING; cm.homing_state = HOMING_NOT_HOMED; return (STAT_OK); }
static void _probe_restore_settings() { mp_flush_planner(); // if (cm.hold_state == FEEDHOLD_HOLD); // cm_end_hold(); cm_end_hold(); // ends hold if on is in effect gpio_set_probing_mode(pb.probe_input, false); // restore axis jerk for (uint8_t axis=0; axis<AXES; axis++) { cm.a[axis].jerk_max = pb.saved_jerk[axis]; } // restore coordinate system and distance mode cm_set_coord_system(pb.saved_coord_system); cm_set_distance_mode(pb.saved_distance_mode); // update the model with actual position cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); cm_canned_cycle_end(); }
static void _probe_restore_settings() { // flush queue and end feedhold (if any) cm_queue_flush(); // set input back to normal operation gpio_set_probing_mode(pb.probe_input, false); // restore axis jerk for (uint8_t axis=0; axis<AXES; axis++) { cm.a[axis].jerk_max = pb.saved_jerk[axis]; } // restore coordinate system and distance mode cm_set_coord_system(pb.saved_coord_system); cm_set_distance_mode(pb.saved_distance_mode); // restart spindle if it was paused cm_spindle_resume(spindle.dwell_seconds); // cancel the feed modes used during probing cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE); cm_canned_cycle_end(); }