/* limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl Copyright (c) 2012-2016 Sungeun K. Jeon for Gnea Research LLC Copyright (c) 2009-2011 Simen Svale Skogsrud 2018 - Bart Dring This file was modifed for use on the ESP32 CPU. Do not use this with Grbl for atMega328P 2018-12-29 - Wolfgang Lienbacher renamed file from limits.h to grbl_limits.h fixing ambiguation issues with limit.h in the esp32 Arduino Framework when compiling with VS-Code/PlatformIO. Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Grbl is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ #include "grbl.h" xQueueHandle limit_sw_queue; // used by limit switch debouncing // Homing axis search distance multiplier. Computed by this value times the cycle travel. #ifndef HOMING_AXIS_SEARCH_SCALAR #define HOMING_AXIS_SEARCH_SCALAR 1.1 // Must be > 1 to ensure limit switch will be engaged. #endif #ifndef HOMING_AXIS_LOCATE_SCALAR #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. #endif void IRAM_ATTR isr_limit_switches() { // Ignore limit switches if already in an alarm state or in-process of executing an alarm. // When in the alarm state, Grbl should have been reset or will force a reset, so any pending // moves in the planner and serial buffers are all cleared and newly sent blocks will be // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard // limit setting if their limits are constantly triggering after a reset and move their axes. if ( ( sys.state != STATE_ALARM) & (bit_isfalse(sys.state, STATE_HOMING)) ) { if (!(sys_rt_exec_alarm)) { #ifdef ENABLE_SOFTWARE_DEBOUNCE // we will start a task that will recheck the switches after a small delay int evt; xQueueSendFromISR(limit_sw_queue, &evt, NULL); #else #ifdef HARD_LIMIT_FORCE_STATE_CHECK // Check limit pin state. if (limits_get_state()) { mc_reset(); // Initiate system kill. system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event } #else mc_reset(); // Initiate system kill. system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event #endif #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 // 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 realtime command can interrupt this process. // TODO: Move limit pin-specific calls to a general function for portability. void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. // Initialize plan data struct for homing motion. Spindle and coolant are disabled. plan_line_data_t plan_data; plan_line_data_t *pl_data = &plan_data; memset(pl_data,0,sizeof(plan_line_data_t)); pl_data->condition = (PL_COND_FLAG_SYSTEM_MOTION|PL_COND_FLAG_NO_FEED_OVERRIDE); #ifdef USE_LINE_NUMBERS pl_data->line_number = HOMING_CYCLE_LINE_NUMBER; #endif // Initialize variables used for homing computations. uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); uint8_t step_pin[N_AXIS]; float target[N_AXIS]; float max_travel = 0.0; uint8_t idx; for (idx=0; idxfeed_rate = homing_rate; // Set current homing rate. plan_buffer_line(target, pl_data); // Bypass mc_line(). Directly plan homing motion. sys.step_control = STEP_CONTROL_EXECUTE_SYS_MOTION; // Set to execute homing motion and clear existing flags. st_prep_buffer(); // Prep and fill segment buffer from newly planned block. st_wake_up(); // Initiate motion do { if (approach) { // Check limit state. Lock out cycle axes when they change. limit_state = limits_get_state(); for (idx=0; idx 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. int32_t set_axis_position; // Set machine positions for homed limit switches. Don't update non-homed axes. for (idx=0; idx