1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-08 21:30:54 +02:00
This commit is contained in:
bdring
2020-11-09 09:36:36 -06:00
parent 5376c4b75a
commit d3468b8c06
11 changed files with 161 additions and 89 deletions

View File

@@ -49,7 +49,7 @@ static float last_cartesian[MAX_N_AXIS] = {};
// prototypes for helper functions
float three_axis_dist(float* point1, float* point2);
void machine_init() {
void user_machine_init() {
// print a startup message to show the kinematics are enable
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "CoreXY Kinematics Init");
}
@@ -231,7 +231,7 @@ void inverse_kinematics(float* position) {
motors[X_AXIS] = geometry_factor * position[X_AXIS] + position[Y_AXIS];
motors[Y_AXIS] = geometry_factor * position[X_AXIS] - position[Y_AXIS];
motors[Z_AXIS] = position[Z_AXIS];
motors[Z_AXIS] = position[Z_AXIS];
position[0] = motors[0];
position[1] = motors[1];

View File

@@ -41,7 +41,7 @@ bool atari_homing = false;
uint8_t homing_phase = HOMING_PHASE_FULL_APPROACH;
uint8_t current_tool;
void machine_init() {
void user_machine_init() {
solenoid_pull_count = 0; // initialize
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Atari 1020 Solenoid");
// setup PWM channel

View File

@@ -1,6 +1,10 @@
/*
Testing the readiness of Grbl for ATC
When the M6 command is received, it will wait until all previous moves have completed, then
inject normal gcode commands to complete the tool change and return to the point where the
tool change occured.
This uses a 5 position rack. The first position is a tool setter. The other 4 are
ATC collets.
@@ -10,44 +14,52 @@
To release a tool you go to the grab height, open the chuck, drop the tool, raise
to the top and close the checks
The spindle must not be spinning when the chuck is open.
The spindle must not be spinning when the chuck is open or the ATC seals will be destroyed. If
the spindle was on,it will turn as soon as the M6 command is received and set a spin down time.
It will do some moves to get to the tool. If the spin down time is not down it will wait,
before activating the chuck. Same on spin up. It will wait before releasing control to the file.
Each tool will touch off on the tool setter. This save the Z Mpos of that position
Each tool will touch off on the tool setter. This saves the Z Mpos of that position
for each tool.
If you zero a tool on the work piece, all tools will use the delta determined by the
toolsetter to.
toolsetter to set the tool length offset.
*/
const int TOOL_COUNT = 4;
const float TOOL_GRAB_TIME = 0.75; // seconds. How long it takes to grab a tool
const int TOOL_COUNT = 4;
const int TOOL_SETTER_INDEX = 0;
const float TOOL_GRAB_TIME = 0.25; // seconds. How long it takes to grab a tool
const float RACK_SAFE_DIST = 25.0; // how far in front of rack is safe to move in X
// temporary struct....should maybe be a class
typedef struct {
float mpos[MAX_N_AXIS]; // the pickup location in machine coords
float offset[MAX_N_AXIS]; // the offset from the zero'd tool
float offset[MAX_N_AXIS]; // TLO from the zero'd tool
} tool_t;
tool_t tool[TOOL_COUNT + 1]; // one setter, plus 4 tools
void go_above_tool(uint8_t tool_num);
void return_tool(uint8_t tool_num);
void atc_tool_setter();
bool set_ATC_open(bool open);
void gc_exec_linef(const char* format, bool sync_after, ...);
float top_of_z; // The highest Z position we can move around on
bool tool_setter_probing = false; // used to determine if current probe cycle is for the setter
int zeroed_tool_index = 0; // Which tool was zero'd on the work piece
uint8_t current_tool = 0;
void machine_init() {
void go_above_tool(uint8_t tool_num);
void return_tool(uint8_t tool_num);
bool atc_tool_setter();
bool set_ATC_open(bool open);
void gc_exec_linef(bool sync_after, const char* format, ...);
void user_machine_init() {
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC Machine Init");
pinMode(ATC_RELEASE_PIN, OUTPUT);
// the tool setter
tool[0].mpos[X_AXIS] = 5.0;
tool[0].mpos[Y_AXIS] = 130.0;
tool[0].mpos[Z_AXIS] = -12.0;
tool[TOOL_SETTER_INDEX].mpos[X_AXIS] = 5.0;
tool[TOOL_SETTER_INDEX].mpos[Y_AXIS] = 130.0;
tool[TOOL_SETTER_INDEX].mpos[Z_AXIS] = -25.0; // Mpos before collet face triggers probe
tool[1].mpos[X_AXIS] = 35.0;
tool[1].mpos[Y_AXIS] = 130.0;
@@ -64,14 +76,17 @@ void machine_init() {
tool[4].mpos[X_AXIS] = 125.0;
tool[4].mpos[Y_AXIS] = 130.0;
tool[4].mpos[Z_AXIS] = -20.0;
top_of_z = limitsMaxPosition(Z_AXIS) - homing_pulloff->get();
}
bool user_tool_change(uint8_t new_tool) {
bool spindle_was_on = false;
uint64_t spindle_spin_delay; // milliseconds
float saved_mpos[MAX_N_AXIS] = {};
bool spindle_was_on = false;
bool was_incremental = false; // started in G91 mode
uint64_t spindle_spin_delay; // used to make sure spindle has fully spun down and up.
float saved_mpos[MAX_N_AXIS] = {}; // the position before the tool change
if (new_tool == current_tool)
if (new_tool == current_tool) // if no change, we are done
return true;
if (new_tool > TOOL_COUNT) {
@@ -80,28 +95,64 @@ bool user_tool_change(uint8_t new_tool) {
}
protocol_buffer_synchronize(); // wait for all previous moves to complete
system_convert_array_steps_to_mpos(saved_mpos, sys_position); // save current position so we can return
system_convert_array_steps_to_mpos(saved_mpos, sys_position); // save current position so we can return to it
// see if we need to switch out of incremental mode
if (gc_state.modal.distance == Distance::Incremental) {
gc_exec_linef(false, "G90");
was_incremental = true;
}
// is spindle on? Turn it off and determine when the spin down should be done.
if (gc_state.modal.spindle != SpindleState::Disable) {
spindle_was_on = true;
gc_exec_linef("M5", false);
spindle_spin_delay = esp_timer_get_time() + (spindle_delay_spindown->get() * 1000.0); // When has spindle stopped
gc_exec_linef(false, "M5");
}
// spindle could have been turned off in gcode before M6
spindle_spin_delay = esp_timer_get_time() + (spindle_delay_spindown->get() * 1000.0); // When will spindle spindown be done.
return_tool(current_tool); // does nothing if current tool is 0
return_tool(current_tool);
// if changing to tool 0...we are done.
if (new_tool == 0) {
if (new_tool == TOOL_SETTER_INDEX) { // if changing to tool 0...we are done.
current_tool = new_tool;
return true;
}
// TODO Check for G91...might not matter in G53
go_above_tool(new_tool);
// if spindle was on has the spindle down period completed? If not wait.
uint64_t current_time = esp_timer_get_time();
if (current_time < spindle_spin_delay) {
vTaskDelay(spindle_spin_delay - current_time);
}
set_ATC_open(true); // open ATC
gc_exec_linef(true, "G53G0Z%0.3f", tool[new_tool].mpos[Z_AXIS]); // drop down to tool
set_ATC_open(false); // Close ATC
gc_exec_linef(true, "G4P%0.2f", TOOL_GRAB_TIME); // wait for grab to complete and settle
gc_exec_linef(false, "G53G0Z%0.3f", top_of_z); // Go to top of Z travel
// move in front of tool
gc_exec_linef(false, "G53G0X%0.3fY%0.3f", tool[new_tool].mpos[X_AXIS], tool[new_tool].mpos[Y_AXIS] - RACK_SAFE_DIST);
current_tool = new_tool;
if (!atc_tool_setter()) { // check the length of the tool
return false;
}
// If the spindle was on before we started, we need to turn it back on.
if (spindle_was_on) {
gc_exec_linef(false, "M3");
spindle_spin_delay = esp_timer_get_time() + (spindle_delay_spinup->get() * 1000.0); // When will spindle spindown be done
}
gc_exec_linef(false, "G53G0X%0.3fY%0.3fZ%0.3f", saved_mpos[X_AXIS], saved_mpos[Y_AXIS], saved_mpos[Z_AXIS]); // return to saved mpos
// was was_incremental on? If so, return to that state
if (was_incremental) {
gc_exec_linef(false, "G91");
}
// Wait for spinup
if (spindle_was_on) {
uint64_t current_time = esp_timer_get_time();
if (current_time < spindle_spin_delay) {
@@ -109,38 +160,32 @@ bool user_tool_change(uint8_t new_tool) {
}
}
set_ATC_open(true); // open ATC
gc_exec_linef("G53G0Z%0.3f", true, tool[new_tool].mpos[Z_AXIS]); // drop down to tool
set_ATC_open(false); // Close ATC
gc_exec_linef("G4P%0.2f", true, TOOL_GRAB_TIME); // wait for grab to complete and settle
gc_exec_linef("G53G0Z-1", false); // raise to top of Z
gc_exec_linef("G53G0X%0.3fY%0.3f", false, tool[new_tool].mpos[X_AXIS], tool[new_tool].mpos[Y_AXIS] - 20.0); // move to X Y in front of tool
current_tool = new_tool;
atc_tool_setter();
// was spindle on?
if (spindle_was_on) {
gc_exec_linef("M3", false);
}
gc_exec_linef("G53G0X%0.3fY%0.3fZ%0.3f", false, , saved_mpos[X_AXIS], saved_mpos[Y_AXIS], saved_mpos[Z_AXIS]); // return to saved mpos
// TODO wait for spinup
return true;
}
void user_probe_notification() {
float probe_position[MAX_N_AXIS];
// https://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G43_1
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Probe complete. Setter:%d", tool_setter_probing);
if (sys.state == State::Alarm) {
return; // probe failed
}
if (tool_setter_probing) {
return; // ignore these probes. They are handled elsewhere.
}
zeroed_tool_index = current_tool;
}
// ============= Local functions ==================
void go_above_tool(uint8_t tool_num) {
gc_exec_linef("G53G0Z-1", false); // raise up
gc_exec_linef("G53G0X%0.3fY%0.3f", false, tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - 20.0); // move in front of tool
gc_exec_linef("G53G0Y%0.3f", true, tool[tool_num].mpos[Y_AXIS]); // Move over tool
gc_exec_linef(false, "G53G0Z%0.3f", top_of_z); // Go to top of Z travel
// move in front of tool
gc_exec_linef(false, "G53G0X%0.3fY%0.3f", tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - RACK_SAFE_DIST);
gc_exec_linef(true, "G53G0Y%0.3f", tool[tool_num].mpos[Y_AXIS]); // Move over tool
}
void return_tool(uint8_t tool_num) {
@@ -148,34 +193,47 @@ void return_tool(uint8_t tool_num) {
return;
go_above_tool(tool_num);
gc_exec_linef("G53G0Z%0.3f", true, tool[tool_num].mpos[Z_AXIS]); // drop down to tool
gc_exec_linef(true, "G53G0Z%0.3f", tool[tool_num].mpos[Z_AXIS]); // drop down to tool
set_ATC_open(true); // open ATC
gc_exec_linef("G4P0.5", false); // wait
gc_exec_linef("G53G0Z-1", true); // raise up
gc_exec_linef(false, "G4P0.5"); // wait
gc_exec_linef(false, "G53G0Z%0.3f", top_of_z); // Go to top of Z travel
set_ATC_open(false); // close ATC
gc_exec_linef("G53G0X%0.3fY%0.3f", true, tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - 20.0); // move forward
gc_exec_linef(true, "G53G0X%0.3fY%0.3f", tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - RACK_SAFE_DIST); // move forward
}
void atc_tool_setter() {
float print_position[MAX_N_AXIS];
bool atc_tool_setter() {
float probe_to; // Calculated work position
float probe_position[MAX_N_AXIS];
go_above_tool(0);
// TODO Fast Probe...Slow Probe?
float wco = gc_state.coord_system[Z_AXIS] + gc_state.coord_offset[Z_AXIS] + gc_state.tool_length_offset;
probe_to = tool[TOOL_SETTER_INDEX].mpos[Z_AXIS] - wco;
gc_exec_linef("G38.2F%0.3fZ%0.3f", true, 300.0, -15); // probe
// https://linuxcnc.org/docs/2.6/html/gcode/gcode.html#sec:G38-probe
tool_setter_probing = true;
gc_exec_linef(true, "G38.2F%0.3fZ%0.3f", 300.0, probe_to); // probe
tool_setter_probing = false;
// TODO was probe successful?
// Was probe successful?
if (sys.state == State::Alarm) {
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC Missing Tool?");
return false; // fail
}
system_convert_array_steps_to_mpos(print_position, sys_probe_position);
tool[current_tool].offset[Z_AXIS] = print_position[Z_AXIS]; // Get the Z height ...
system_convert_array_steps_to_mpos(probe_position, sys_probe_position);
tool[current_tool].offset[Z_AXIS] = probe_position[Z_AXIS]; // Get the Z height ...
gc_exec_linef("G53G0Z-1", false); // raise up
if (zeroed_tool_index != 0) {
float tlo = tool[zeroed_tool_index].offset[Z_AXIS] - tool[current_tool].offset[Z_AXIS];
gc_exec_linef(false, "G43.1Z%0.3f", top_of_z); // raise up
}
gc_exec_linef(false, "G53G0Z%0.3f", top_of_z); // raise up
// move forward
gc_exec_linef("G53G0X%0.3fY%0.3f", false, tool[0].mpos[X_AXIS], tool[0].mpos[Y_AXIS] - 20.0);
gc_exec_linef(false, "G53G0X%0.3fY%0.3f", tool[TOOL_SETTER_INDEX].mpos[X_AXIS], tool[TOOL_SETTER_INDEX].mpos[Y_AXIS] - RACK_SAFE_DIST);
return true;
}
bool set_ATC_open(bool open) {
@@ -189,11 +247,12 @@ bool set_ATC_open(bool open) {
}
/*
Formats and sends a gcode line
char* format = a printf style string like "G0X%0.3fY0.3f"
Format and send gcode line with optional synchronization
sync_after: Forces all buffered lines to be completed for line send
format: a printf style string
*/
void gc_exec_linef(const char* format, bool sync_after, ...) {
void gc_exec_linef(bool sync_after, const char* format, ...) {
char loc_buf[100];
char* temp = loc_buf;
va_list arg;

View File

@@ -47,10 +47,10 @@ enabled with USE_ defines in Machines/my_machine.h
*/
/*
machine_init() is called when Grbl_ESP32 first starts. You can use it to do any
user_machine_init() is called when Grbl_ESP32 first starts. You can use it to do any
special things your machine needs at startup.
*/
void machine_init() {}
void user_machine_init() {}
#ifdef USE_CUSTOM_HOMING
/*

View File

@@ -22,12 +22,12 @@
*/
/*
machine_init() is called when Grbl_ESP32 first starts. You can use it to do any
user_machine_init() is called when Grbl_ESP32 first starts. You can use it to do any
special things your machine needs at startup.
*/
void machine_init() {
void user_machine_init() {
// force this on all the time
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Custom machine_init() Level Shift Enabled");
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Custom user_machine_init() Level Shift Enabled");
pinMode(LVL_SHIFT_ENABLE, OUTPUT);
digitalWrite(LVL_SHIFT_ENABLE, HIGH);
}

View File

@@ -97,7 +97,7 @@ KinematicError delta_calcAngleYZ(float x0, float y0, float z0, float& theta);
float three_axis_dist(float* point1, float* point2);
void read_settings();
void machine_init() {
void user_machine_init() {
float angles[N_AXIS] = { 0.0, 0.0, 0.0 };
float cartesian[N_AXIS] = { 0.0, 0.0, 0.0 };
@@ -151,7 +151,7 @@ void inverse_kinematics(float* target, plan_line_data_t* pl_data, float* positio
float dx, dy, dz; // distances in each cartesian axis
float motor_angles[3];
float seg_target[3]; // The target of the current segment
float seg_target[3]; // The target of the current segment
float feed_rate = pl_data->feed_rate; // save original feed rate
bool show_error = true; // shows error once

View File

@@ -96,11 +96,11 @@ const int MAX_N_AXIS = 6;
//#define CONNECT_TO_SSID "your SSID"
//#define SSID_PASSWORD "your SSID password"
//CONFIGURE_EYECATCH_BEGIN (DO NOT MODIFY THIS LINE)
//#define ENABLE_BLUETOOTH // enable bluetooth
#define ENABLE_BLUETOOTH // enable bluetooth
//#define ENABLE_SD_CARD // enable use of SD Card to run jobs
//#define ENABLE_WIFI //enable wifi
#define ENABLE_WIFI //enable wifi
#if defined(ENABLE_WIFI) || defined(ENABLE_BLUETOOTH)
# define WIFI_OR_BLUETOOTH

View File

@@ -1601,7 +1601,9 @@ Error gc_execute_line(char* line, uint8_t client) {
return Error::Ok;
}
__attribute__((weak)) bool user_tool_change(uint8_t new_tool) {}
__attribute__((weak)) bool user_tool_change(uint8_t new_tool) {
return true;
}
/*
Not supported:

View File

@@ -43,7 +43,7 @@ void grbl_init() {
system_ini(); // Configure pinout pins and pin-change interrupt (Renamed due to conflict with esp32 files)
memset(sys_position, 0, sizeof(sys_position)); // Clear machine position.
machine_init(); // (weak) should be user defined
user_machine_init(); // (weak) should be user defined
// Initialize system state.
#ifdef FORCE_INITIALIZATION_ALARM
@@ -116,7 +116,7 @@ void run_once() {
protocol_main_loop();
}
__attribute__((weak)) void machine_init() {}
__attribute__((weak)) void user_machine_init() {}
/*
setup() and loop() in the Arduino .ino implements this control flow:

View File

@@ -92,7 +92,7 @@ const char* const GRBL_VERSION_BUILD = "20201101";
void grbl_init();
void run_once();
void machine_init();
void user_machine_init();
// Called if USE_CUSTOM_HOMING is defined
bool user_defined_homing(uint8_t cycle_mask);

View File

@@ -78,6 +78,17 @@
#define Z_LIMIT_PIN GPIO_NUM_35
#define PROBE_PIN GPIO_NUM_34
// 4x Switch Input module in socket #2
#define PROBE2_PIN GPIO_NUM_2
//#define CONTROL_CYCLE_START_PIN GPIO_NUM_25
//#define CONTROL_FEED_HOLD_PIN GPIO_NUM_39
//#define CONTROL_SAFETY_DOOR_PIN GPIO_NUM_36
#ifdef INVERT_CONTROL_PIN_MASK
#undef INVERT_CONTROL_PIN_MASK
#endif
#define INVERT_CONTROL_PIN_MASK B0101 // Cycle Start | Feed Hold | Reset | Safety Door
// 5V output CNC module in socket #4
// https://github.com/bdring/6-Pack_CNC_Controller/wiki/4x-5V-Buffered-Output-Module
#define SPINDLE_TYPE SpindleType::PWM