1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-02 02:42:36 +02:00

Handled all parking related defines

This commit is contained in:
Stefan de Bruijn
2021-06-19 21:56:36 +02:00
parent 9b5c01d2cb
commit 3ca344d62f
10 changed files with 71 additions and 100 deletions

View File

@@ -395,18 +395,6 @@ const int DEBOUNCE_PERIOD = 32; // in milliseconds default 32 microseconds
// repeatable. If needed, you can disable this behavior by uncommenting the define below.
// #define ALLOW_FEED_OVERRIDE_DURING_PROBE_CYCLES // Default disabled. Uncomment to enable.
// Enables and configures parking motion methods upon a safety door state. Primarily for OEMs
// that desire this feature for their integrated machines. At the moment, Grbl assumes that
// the parking motion only involves one axis, although the parking implementation was written
// to be easily refactored for any number of motions on different axes by altering the parking
// source code. At this time, Grbl only supports parking one axis (typically the Z-axis) that
// moves in the positive direction upon retracting and negative direction upon restoring position.
// The motion executes with a slow pull-out retraction motion, power-down, and a fast park.
// Restoring to the resume position follows these set motions in reverse: fast restore to
// pull-out position, power-up with a time-out, and plunge back to the original position at the
// slower pull-out rate.
#define PARKING_ENABLE // Default disabled. Uncomment to enable
// Configure options for the parking motion, if enabled.
#define PARKING_AXIS Z_AXIS // Define which axis that performs the parking motion
const double PARKING_TARGET = -5.0; // Parking axis target. In mm, as machine coordinate.
@@ -419,7 +407,8 @@ const double PARKING_PULLOUT_INCREMENT = 5.0; // Spindle pull-out and plunge
// These are controlled by `M56`, `M56 P1`, or `M56 Px` to enable and `M56 P0` to disable.
// The command is modal and will be set after a planner sync. Since it is GCode, it is
// executed in sync with GCode commands. It is not a real-time command.
// NOTE: PARKING_ENABLE is required. By default, M56 is active upon initialization. Use
//
// By default, M56 is active upon initialization. Use
// DEACTIVATE_PARKING_UPON_INIT to set M56 P0 as the power-up default.
// #define ENABLE_PARKING_OVERRIDE_CONTROL // Default disabled. Uncomment to enable
// #define DEACTIVATE_PARKING_UPON_INIT // Default disabled. Uncomment to enable.

View File

@@ -47,8 +47,14 @@ parser_block_t gc_block;
void gc_init() {
// Reset parser state:
memset(&gc_state, 0, sizeof(parser_state_t));
// Load default G54 coordinate system.
gc_state.modal.coord_select = CoordIndex::G54;
if (config->_deactivateParkingUponInit) {
gc_state.modal.override = Override::Disabled;
} else {
gc_state.modal.override = Override::ParkingMotion;
}
coords[gc_state.modal.coord_select]->get(gc_state.coord_system);
}
@@ -519,12 +525,14 @@ Error gc_execute_line(char* line, uint8_t client) {
}
mg_word_bit = ModalGroup::MM8;
break;
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
case 56:
gc_block.modal.override = Override::ParkingMotion;
mg_word_bit = ModalGroup::MM9;
if (config->_enableParkingOverrideControl) {
gc_block.modal.override = Override::ParkingMotion;
mg_word_bit = ModalGroup::MM9;
} else {
FAIL(Error::GcodeUnsupportedCommand); // [Unsupported M command]
}
break;
#endif
case 62:
gc_block.modal.io_control = IoControl::DigitalOnSync;
mg_word_bit = ModalGroup::MM10;
@@ -803,16 +811,17 @@ Error gc_execute_line(char* line, uint8_t client) {
// [8. Coolant control ]: N/A
// [9. Enable/disable feed rate or spindle overrides ]: NOT SUPPORTED.
}
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
if (bit_istrue(command_words, bit(ModalGroup::MM9))) { // Already set as enabled in parser.
if (bit_istrue(value_words, bit(GCodeWord::P))) {
if (gc_block.values.p == 0.0) {
gc_block.modal.override = Override::Disabled;
if (config->_enableParkingOverrideControl) {
if (bit_istrue(command_words, bit(ModalGroup::MM9))) { // Already set as enabled in parser.
if (bit_istrue(value_words, bit(GCodeWord::P))) {
if (gc_block.values.p == 0.0) {
gc_block.modal.override = Override::Disabled;
}
bit_false(value_words, bit(GCodeWord::P));
}
bit_false(value_words, bit(GCodeWord::P));
}
}
#endif
// [10. Dwell ]: P value missing. P is negative (done.) NOTE: See below.
if (gc_block.non_modal_command == NonModal::Dwell) {
if (bit_isfalse(value_words, bit(GCodeWord::P))) {
@@ -1427,12 +1436,13 @@ Error gc_execute_line(char* line, uint8_t client) {
}
// [9. Override control ]: NOT SUPPORTED. Always enabled. Except for a Grbl-only parking control.
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
if (gc_state.modal.override != gc_block.modal.override) {
gc_state.modal.override = gc_block.modal.override;
mc_override_ctrl_update(gc_state.modal.override);
if (config->_enableParkingOverrideControl) {
if (gc_state.modal.override != gc_block.modal.override) {
gc_state.modal.override = gc_block.modal.override;
mc_override_ctrl_update(gc_state.modal.override);
}
}
#endif
// [10. Dwell ]:
if (gc_block.non_modal_command == NonModal::Dwell) {
mc_dwell(int32_t(gc_block.values.p * 1000.0f));
@@ -1581,13 +1591,14 @@ Error gc_execute_line(char* line, uint8_t client) {
gc_state.modal.coord_select = CoordIndex::G54;
gc_state.modal.spindle = SpindleState::Disable;
gc_state.modal.coolant = {};
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
# ifdef DEACTIVATE_PARKING_UPON_INIT
gc_state.modal.override = Override::Disabled;
# else
gc_state.modal.override = Override::ParkingMotion;
# endif
#endif
if (config->_enableParkingOverrideControl) {
if (config->_deactivateParkingUponInit) {
gc_state.modal.override = Override::Disabled;
} else {
gc_state.modal.override = Override::ParkingMotion;
}
}
// gc_state.modal.override = OVERRIDE_DISABLE; // Not supported.
#ifdef RESTORE_OVERRIDES_AFTER_PROGRAM_END
sys.f_override = FeedOverride::Default;

View File

@@ -263,7 +263,7 @@ enum CoordIndex : uint8_t {
CoordIndex& operator++(CoordIndex& i);
// NOTE: When this struct is zeroed, the 0 values in the above types set the system defaults.
typedef struct {
struct gc_modal_t {
Motion motion; // {G0,G1,G2,G3,G38.2,G80}
FeedRate feed_rate; // {G93,G94}
Units units; // {G20,G21}
@@ -280,9 +280,9 @@ typedef struct {
ToolChange tool_change; // {M6}
IoControl io_control; // {M62, M63, M67}
Override override; // {M56}
} gc_modal_t;
};
typedef struct {
struct gc_values_t {
uint8_t e; // M67
float f; // Feed
float ijk[3]; // I,J,K Axis arc offsets - only 3 are possible
@@ -294,9 +294,9 @@ typedef struct {
float s; // Spindle speed
uint8_t t; // Tool selection
float xyz[MAX_N_AXIS]; // X,Y,Z Translational axes
} gc_values_t;
};
typedef struct {
struct parser_state_t {
gc_modal_t modal;
float spindle_speed; // RPM
@@ -311,15 +311,16 @@ typedef struct {
float coord_offset[MAX_N_AXIS]; // Retains the G92 coordinate offset (work coordinates) relative to
// machine zero in mm. Non-persistent. Cleared upon reset and boot.
float tool_length_offset; // Tracks tool length offset value when enabled.
} parser_state_t;
};
extern parser_state_t gc_state;
typedef struct {
struct parser_block_t {
NonModal non_modal_command;
gc_modal_t modal;
gc_values_t values;
GCodeCoolant coolant;
} parser_block_t;
};
enum class AxisCommand : uint8_t {
None = 0,

View File

@@ -417,6 +417,9 @@ void MachineConfig::group(Configuration::HandlerBase& handler) {
handler.item("verbose_errors", _verboseErrors);
handler.item("report_inches", _reportInches);
handler.item("homing_init_lock", _homingInitLock);
handler.item("enable_parking_override_control", _enableParkingOverrideControl);
handler.item("deactivate_parking_upon_init", _deactivateParkingUponInit);
Spindles::SpindleFactory::factory(handler, _spindle);
}

View File

@@ -362,6 +362,9 @@ public:
bool _homingInitLock = false;
int _stepType = ST_RMT;
bool _enableParkingOverrideControl = false;
bool _deactivateParkingUponInit = false;
String _board = "None";
String _name = "None";

View File

@@ -507,7 +507,6 @@ void mc_parking_motion(float* parking_target, plan_line_data_t* pl_data) {
}
}
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
void mc_override_ctrl_update(Override override_state) {
// Finish all queued commands before altering override control state
protocol_buffer_synchronize();
@@ -516,7 +515,6 @@ void mc_override_ctrl_update(Override override_state) {
}
sys.override_ctrl = override_state;
}
#endif
// Method to ready the system to reset by setting the realtime reset command and killing any
// active processes in the system. This also checks if a system reset is issued while Grbl

View File

@@ -94,11 +94,11 @@ Error execute_line(char* line, uint8_t client, WebUI::AuthenticationLevel auth_l
}
bool can_park() {
return
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
sys.override_ctrl == Override::ParkingMotion &&
#endif
homingAxes() && !config->_laserMode;
if (config->_enableParkingOverrideControl) {
return sys.override_ctrl == Override::ParkingMotion && homingAxes() && !config->_laserMode;
} else {
return homingAxes() && !config->_laserMode;
}
}
void protocol_reset() {
@@ -407,7 +407,6 @@ static void protocol_do_safety_door() {
break;
case State::SafetyDoor:
if (!sys.suspend.bit.jogCancel && sys.suspend.bit.initiateRestore) { // Actively restoring
#ifdef PARKING_ENABLE
// Set hold and reset appropriate control flags to restart parking sequence.
if (sys.step_control.executeSysMotion) {
st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.
@@ -416,7 +415,7 @@ static void protocol_do_safety_door() {
sys.step_control.executeSysMotion = true;
sys.suspend.bit.holdComplete = false;
} // else NO_MOTION is active.
#endif
sys.suspend.bit.retractComplete = false;
sys.suspend.bit.initiateRestore = false;
sys.suspend.bit.restoreComplete = false;
@@ -798,7 +797,6 @@ void protocol_exec_rt_system() {
// // already retracting, parked or in sleep state.
// if (sys.state == State::SafetyDoor) {
// if (sys.suspend.bit.initiateRestore) { // Actively restoring
//#ifdef PARKING_ENABLE
// // Set hold and reset appropriate control flags to restart parking sequence.
// if (sys.step_control.executeSysMotion) {
// st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.
@@ -807,7 +805,6 @@ void protocol_exec_rt_system() {
// sys.step_control.executeSysMotion = true;
// sys.suspend.bit.holdComplete = false;
// } // else NO_MOTION is active.
//#endif
// sys.suspend.bit.retractComplete = false;
// sys.suspend.bit.initiateRestore = false;
// sys.suspend.bit.restoreComplete = false;
@@ -991,7 +988,6 @@ void protocol_exec_rt_system() {
// This function is written in a way to promote custom parking motions. Simply use this as a
// template
static void protocol_exec_rt_suspend() {
#ifdef PARKING_ENABLE
// Declare and initialize parking local variables
float restore_target[MAX_N_AXIS];
float retract_waypoint = PARKING_PULLOUT_INCREMENT;
@@ -1001,10 +997,10 @@ static void protocol_exec_rt_suspend() {
pl_data->motion = {};
pl_data->motion.systemMotion = 1;
pl_data->motion.noFeedOverride = 1;
# ifdef USE_LINE_NUMBERS
#ifdef USE_LINE_NUMBERS
pl_data->line_number = PARKING_MOTION_LINE_NUMBER;
# endif
#endif
plan_block_t* block = plan_get_current_block();
CoolantState restore_coolant;
SpindleState restore_spindle;
@@ -1040,16 +1036,11 @@ static void protocol_exec_rt_suspend() {
// the safety door and sleep states.
if (sys.state == State::SafetyDoor || sys.state == State::Sleep) {
// Handles retraction motions and de-energizing.
#ifdef PARKING_ENABLE
float* parking_target = system_get_mpos();
#endif
if (!sys.suspend.bit.retractComplete) {
// Ensure any prior spindle stop override is disabled at start of safety door routine.
sys.spindle_stop_ovr.value = 0; // Disable override
#ifndef PARKING_ENABLE
config->_spindle->spinDown();
config->_coolant->off();
#else
// Get current position and store restore location and spindle retract waypoint.
if (!sys.suspend.bit.restartRetract) {
memcpy(restore_target, parking_target, sizeof(restore_target[0]) * config->_axes->_numberAxis);
@@ -1091,7 +1082,7 @@ static void protocol_exec_rt_suspend() {
config->_spindle->spinDown();
config->_coolant->off();
}
#endif
sys.suspend.bit.restartRetract = false;
sys.suspend.bit.retractComplete = true;
} else {
@@ -1114,7 +1105,6 @@ static void protocol_exec_rt_suspend() {
}
// Handles parking restore and safety door resume.
if (sys.suspend.bit.initiateRestore) {
#ifdef PARKING_ENABLE
// Execute fast restore motion to the pull-out position. Parking requires homing enabled.
// NOTE: State is will remain DOOR, until the de-energizing and retract is complete.
if (can_park()) {
@@ -1125,7 +1115,6 @@ static void protocol_exec_rt_suspend() {
mc_parking_motion(parking_target, pl_data);
}
}
#endif
// Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle.
if (gc_state.modal.spindle != SpindleState::Disable) {
// Block if safety door re-opened during prior restore actions.
@@ -1144,7 +1133,7 @@ static void protocol_exec_rt_suspend() {
config->_coolant->set_state(restore_coolant);
}
}
#ifdef PARKING_ENABLE
// Execute slow plunge motion from pull-out position to resume position.
if (can_park()) {
// Block if safety door re-opened during prior restore actions.
@@ -1159,7 +1148,6 @@ static void protocol_exec_rt_suspend() {
mc_parking_motion(restore_target, pl_data);
}
}
#endif
if (!sys.suspend.bit.restartRetract) {
sys.suspend.bit.restoreComplete = true;
rtCycleStart = true; // Set to resume program.

View File

@@ -503,11 +503,9 @@ void report_gcode_modes(uint8_t client) {
}
}
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
if (sys.override_ctrl == Override::ParkingMotion) {
if (config->_enableParkingOverrideControl && sys.override_ctrl == Override::ParkingMotion) {
strcat(modes_rpt, " M56");
}
#endif
sprintf(temp, " T%d", gc_state.tool);
strcat(modes_rpt, temp);
@@ -535,9 +533,7 @@ void report_build_info(const char* line, uint8_t client) {
if (config->_coolant->hasMist()) {
grbl_send(client, "M"); // TODO Need to deal with M8...it could be disabled
}
#ifdef PARKING_ENABLE
grbl_send(client, "P");
#endif
#ifdef HOMING_SINGLE_AXIS_COMMANDS
grbl_send(client, "H");
#endif
@@ -551,9 +547,9 @@ void report_build_info(const char* line, uint8_t client) {
grbl_send(client, "B");
}
grbl_send(client, "S");
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
grbl_send(client, "R");
#endif
if (config->_enableParkingOverrideControl) {
grbl_send(client, "R");
}
#ifdef ENABLE_WIFI
grbl_send(client, "W");
#endif

View File

@@ -103,12 +103,10 @@ typedef struct {
float step_per_mm;
float req_mm_increment;
#ifdef PARKING_ENABLE
uint8_t last_st_block_index;
float last_steps_remaining;
float last_step_per_mm;
float last_dt_remainder;
#endif
uint8_t ramp_type; // Current segment ramp state
float mm_complete; // End of velocity profile from end of current planner block in (mm).
@@ -441,7 +439,6 @@ void st_update_plan_block_parameters() {
}
}
#ifdef PARKING_ENABLE
// Changes the run state of the step segment buffer to execute the special parking motion.
void st_parking_setup_buffer() {
// Store step execution data of partially completed block, if necessary.
@@ -475,7 +472,6 @@ void st_parking_restore_buffer() {
pl_block = NULL; // Set to reload next block.
}
#endif
// Increments the step segment buffer block data ring buffer.
static uint8_t st_next_block_index(uint8_t block_index) {
@@ -518,15 +514,11 @@ void st_prep_buffer() {
// Check if we need to only recompute the velocity profile or load a new block.
if (prep.recalculate_flag.recalculate) {
#ifdef PARKING_ENABLE
if (prep.recalculate_flag.parking) {
prep.recalculate_flag.recalculate = 0;
} else {
prep.recalculate_flag = {};
}
#else
prep.recalculate_flag = {};
#endif
} else {
// Load the Bresenham stepping data for the block.
prep.st_block_index = st_next_block_index(prep.st_block_index);
@@ -816,11 +808,9 @@ void st_prep_buffer() {
// Less than one step to decelerate to zero speed, but already very close. AMASS
// requires full steps to execute. So, just bail.
sys.step_control.endMotion = true;
#ifdef PARKING_ENABLE
if (!(prep.recalculate_flag.parking)) {
prep.recalculate_flag.holdPartialBlock = 1;
}
#endif
return; // Segment not generated, but current step data still retained.
}
}
@@ -874,11 +864,9 @@ void st_prep_buffer() {
// the segment queue, where realtime protocol will set new state upon receiving the
// cycle stop flag from the ISR. Prep_segment is blocked until then.
sys.step_control.endMotion = true;
#ifdef PARKING_ENABLE
if (!(prep.recalculate_flag.parking)) {
prep.recalculate_flag.holdPartialBlock = 1;
}
#endif
return; // Bail!
} else { // End of planner block
// The planner block is complete. All steps are set to be executed in the segment buffer.

View File

@@ -74,13 +74,8 @@ typedef uint8_t Percent; // Integer percent
typedef uint8_t Counter; // Report interval
enum class Override : uint8_t {
#ifdef DEACTIVATE_PARKING_UPON_INIT
Disabled = 0, // (Default: Must be zero)
ParkingMotion = 1, // M56
#else
ParkingMotion = 0, // M56 (Default: Must be zero)
Disabled = 1, // Parking disabled.
#endif
};
// Spindle stop override control states.
@@ -96,7 +91,7 @@ union SpindleStop {
};
// Global system variables
typedef struct {
struct system_t {
volatile State state; // Tracks the current system state of Grbl.
bool abort; // System abort flag. Forces exit back to main loop for reset.
Suspend suspend; // System suspend bitflag variable that manages holds, cancels, and safety door.
@@ -110,11 +105,10 @@ typedef struct {
SpindleStop spindle_stop_ovr; // Tracks spindle stop override states
Counter report_ovr_counter; // Tracks when to add override data to status reports.
Counter report_wco_counter; // Tracks when to add work coordinate offset data to status reports.
#ifdef ENABLE_PARKING_OVERRIDE_CONTROL
Override override_ctrl; // Tracks override control states.
#endif
uint32_t spindle_speed;
} system_t;
Override override_ctrl; // Tracks override control states.
uint32_t spindle_speed;
};
extern system_t sys;
// NOTE: These position variables may need to be declared as volatiles, if problems arise.