G38.2 probe feature rough draft installed. Working but needs testing.
- G38.2 straight probe now supported. Rough draft. May be tweaked more as testing ramps up. - G38.2 requires at least one axis word. Multiple axis words work too. When commanded, the probe cycle will move at the last ‘F’ feed rate specified in a straight line. - During a probe cycle: If the probe pin goes low (normal high), Grbl will record that immediate position and engage a feed hold. Meaning that the CNC machine will move a little past the probe switch point, so keep federates low to stop sooner. Once stopped, Grbl will issue a move to go back to the recorded probe trigger point. - During a probe cycle: If the probe switch does not engage by the time the machine has traveled to its target coordinates, Grbl will issue an ALARM and the user will be forced to reset Grbl. (Currently G38.3 probe without error isn’t supported, but would be easy to implement later.) - After a successful probe, Grbl will send a feedback message containing the recorded probe coordinates in the machine coordinate system. This is as the g-code standard on probe parameters specifies. - The recorded probe parameters are retained in Grbl memory and can be viewed with the ‘$#’ print parameters command. Upon a power-cycle, not a soft-reset, Grbl will re-zero these values. - Moved ‘$#’ command to require IDLE or ALARM mode, because it accesses EEPROM to fetch the coordinate system offsets. - Updated the Grbl version to v0.9d. - The probe cycle is subject to change upon testing or user-feedback.
This commit is contained in:
@ -30,6 +30,7 @@
|
||||
#include "spindle_control.h"
|
||||
#include "coolant_control.h"
|
||||
#include "limits.h"
|
||||
#include "probe.h"
|
||||
#include "report.h"
|
||||
|
||||
|
||||
@ -270,75 +271,39 @@ void mc_homing_cycle()
|
||||
}
|
||||
|
||||
|
||||
// Perform tool length probe cycle. Requires probe switch.
|
||||
// NOTE: Upon probe failure, the program will be stopped and placed into ALARM state.
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
uint8_t mc_probe_cycle(float *t, float feed_rate, uint8_t invert_feed_rate, int32_t line_number)
|
||||
void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number)
|
||||
#else
|
||||
uint8_t mc_probe_cycle(float *t, float feed_rate, uint8_t invert_feed_rate)
|
||||
void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate)
|
||||
#endif
|
||||
{
|
||||
protocol_buffer_synchronize(); //finish all queued commands
|
||||
protocol_buffer_synchronize(); // Finish all queued commands
|
||||
if (sys.abort) { return; } // Return if system reset has been issued.
|
||||
|
||||
if (sys.abort) { return STATUS_OK; } // Return if system reset has been issued.
|
||||
|
||||
uint8_t i;
|
||||
float target[N_AXIS];
|
||||
|
||||
//copy target position since we'll be modifying it with the probe position on a successful move
|
||||
//The gc_sync_position() at the end may elimiante the need for this. Not sure though.
|
||||
for(i=0; i<N_AXIS; ++i){
|
||||
target[i] = t[i];
|
||||
}
|
||||
|
||||
plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions.
|
||||
|
||||
// Perform probing cycle. Planner buffer should be empty at this point.
|
||||
// An empty buffer is needed because we need to enable the probe pin along the same move that we're about to execute.
|
||||
|
||||
sys.state = STATE_CYCLE;
|
||||
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate, line_number); // Bypass mc_line(). Directly plan homing motion.
|
||||
mc_line(target, feed_rate, invert_feed_rate, line_number);
|
||||
#else
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate); // Bypass mc_line(). Directly plan homing motion.
|
||||
mc_line(target, feed_rate, invert_feed_rate);
|
||||
#endif
|
||||
st_prep_buffer(); // Prep and fill segment buffer from newly planned block.
|
||||
st_wake_up(); // Initiate motion
|
||||
|
||||
sys.probe_state = PROBE_ACTIVE;
|
||||
|
||||
//TODO - make sure the probe isn't already closed
|
||||
sys.probe_state = PROBE_ACTIVE;
|
||||
|
||||
sys.execute |= EXEC_CYCLE_START;
|
||||
do {
|
||||
|
||||
if( sys.probe_state == PROBE_OFF ){
|
||||
sys.execute |= EXEC_FEED_HOLD;
|
||||
protocol_execute_runtime();
|
||||
break;
|
||||
}
|
||||
protocol_execute_runtime();
|
||||
st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us.
|
||||
|
||||
if (sys.execute & EXEC_RESET) {
|
||||
sys.probe_state = PROBE_OFF;
|
||||
protocol_execute_runtime();
|
||||
return STATUS_OK;
|
||||
}
|
||||
protocol_execute_runtime();
|
||||
if (sys.abort) { return; } // Check for system abort
|
||||
} while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED));
|
||||
|
||||
//Check for motion ended because switch never triggered
|
||||
if(sys.state != STATE_CYCLE && sys.state != STATE_HOLD){
|
||||
sys.probe_state = PROBE_OFF;
|
||||
report_realtime_status_probe();
|
||||
return STATUS_PROBE_ERROR;
|
||||
}
|
||||
|
||||
} while (1);
|
||||
|
||||
//report_realtime_status(); //debug
|
||||
|
||||
while((sys.execute & EXEC_CYCLE_STOP) == 0 && (sys.state == STATE_CYCLE || sys.state == STATE_HOLD)){
|
||||
protocol_execute_runtime();
|
||||
if (sys.abort) { return STATUS_OK; } // Check for system abort
|
||||
}
|
||||
if (sys.probe_state == PROBE_ACTIVE) { sys.execute |= EXEC_CRIT_EVENT; }
|
||||
protocol_execute_runtime(); // Check and execute run-time commands
|
||||
if (sys.abort) { return; } // Check for system abort
|
||||
|
||||
//Prep the new target based on the position that the probe triggered
|
||||
uint8_t i;
|
||||
for(i=0; i<N_AXIS; ++i){
|
||||
target[i] = (float)sys.probe_position[i]/settings.steps_per_mm[i];
|
||||
}
|
||||
@ -349,37 +314,24 @@ uint8_t mc_probe_cycle(float *t, float feed_rate, uint8_t invert_feed_rate)
|
||||
plan_reset(); // Reset planner buffer. Zero planner positions. Ensure homing motion is cleared.
|
||||
plan_sync_position(); // Sync planner position to current machine position for pull-off move.
|
||||
|
||||
//report_realtime_status(); //debug
|
||||
|
||||
#ifdef USE_LINE_NUMBERS
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate, line_number); // Bypass mc_line(). Directly plan homing motion.
|
||||
mc_line(target, feed_rate, invert_feed_rate, line_number); // Bypass mc_line(). Directly plan homing motion.
|
||||
#else
|
||||
plan_buffer_line(target, feed_rate, invert_feed_rate); // Bypass mc_line(). Directly plan homing motion.
|
||||
mc_line(target, feed_rate, invert_feed_rate); // 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
|
||||
|
||||
protocol_execute_runtime();
|
||||
sys.execute |= EXEC_CYCLE_START;
|
||||
protocol_buffer_synchronize(); // Complete pull-off motion.
|
||||
|
||||
//report_realtime_status(); //debug
|
||||
|
||||
protocol_execute_runtime(); // Check for reset and set system abort.
|
||||
if (sys.abort) { return STATUS_OK; } // Did not complete. Alarm state set by mc_alarm.
|
||||
if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm.
|
||||
|
||||
// Gcode parser position was circumvented by the this routine, so sync position now.
|
||||
gc_sync_position();
|
||||
|
||||
// Set idle state after probing completes and before returning to main program.
|
||||
sys.state = STATE_IDLE;
|
||||
st_go_idle();
|
||||
|
||||
//TODO - ouput a mandatory status update with the probe position. What if another was recently sent?
|
||||
report_realtime_status_probe();
|
||||
return STATUS_OK;
|
||||
report_probe_parameters();
|
||||
}
|
||||
|
||||
|
||||
// Method to ready the system to reset by setting the runtime reset command and killing any
|
||||
// active processes in the system. This also checks if a system reset is issued while Grbl
|
||||
// is in a motion state. If so, kills the steppers and sets the system alarm to flag position
|
||||
|
Reference in New Issue
Block a user