1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-01 18:32:37 +02:00

Basic functionality

TODO
- Deal with tool length offset
- Deal with manual probe cycle
This commit is contained in:
bdring
2020-11-06 20:01:06 -06:00
parent 420657fa55
commit 7ee6b1062e
10 changed files with 211 additions and 258 deletions

View File

@@ -4,40 +4,222 @@
*/
#define TOOL_GRAB_TIME 0.75 // seconds
// temporary struct....should 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
} tool_t;
tool_t tool[5]; // 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);
uint8_t current_tool = 0;
void 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[1].mpos[X_AXIS] = 35.0;
tool[1].mpos[Y_AXIS] = 130.0;
tool[1].mpos[Z_AXIS] = -20.0;
tool[2].mpos[X_AXIS] = 65.0;
tool[2].mpos[Y_AXIS] = 130.0;
tool[2].mpos[Z_AXIS] = -20.0;
tool[3].mpos[X_AXIS] = 95.0;
tool[3].mpos[Y_AXIS] = 130.0;
tool[3].mpos[Z_AXIS] = -20.0;
}
/*
*/
void user_tool_change(uint8_t new_tool) {
char gcode_line[20];
char gcode_line[80];
bool spindle_on = false;
uint64_t spindle_delay;
float saved_mpos[MAX_N_AXIS] = {};
// save current position
system_convert_array_steps_to_mpos(saved_mpos, sys_position);
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC use tool %d", new_tool);
protocol_buffer_synchronize(); // wait for all previous moves to complete
// is spindle on? Turn it off and determine when the spin down should be done.
if (gc_state.modal.spindle != SpindleState::Disable) {
spindle_on = true;
sprintf(gcode_line, "M5\r"); //
gc_execute_line(gcode_line, CLIENT_INPUT);
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC: %s", gcode_line);
spindle_delay = esp_timer_get_time() + (spindle_delay_spinup->get() * 1000.0); // When has spindle stopped
}
return_tool(current_tool); // does nothing if current tool is 0
// if changing to tool 0...we are done.
if (new_tool == 0) {
current_tool = new_tool;
return;
}
// TODO Check for G91...might not matter in G53
go_above_tool(new_tool);
protocol_buffer_synchronize(); // wait for motion to complete
// if spindle was on has the spindle down period completed? If not wait.
if (spindle_on) {
uint64_t current_time = esp_timer_get_time();
if (current_time < spindle_delay) {
vTaskDelay(spindle_delay - current_time);
}
}
// open ATC
set_ATC_open(true);
// drop down to tool
sprintf(gcode_line, "G53G0Z%0.3f\r", tool[new_tool].mpos[Z_AXIS]); //
gc_execute_line(gcode_line, CLIENT_INPUT);
protocol_buffer_synchronize(); // wait for it
// Close ATC
set_ATC_open(false);
// wait for grab to complete and settle
sprintf(gcode_line, "G4P%0.2f\r", TOOL_GRAB_TIME); //
gc_execute_line(gcode_line, CLIENT_INPUT);
// raise to top of Z
sprintf(gcode_line, "G53G0Z-1\r"); //
gc_execute_line(gcode_line, CLIENT_INPUT);
sprintf(gcode_line, "G4P3.0"); //
gc_execute_line(gcode_line, CLIENT_INPUT);
sprintf(gcode_line, "G0G0Z0"); //
// move to X Y in front of tool
sprintf(gcode_line, "G53G0X%0.3fY%0.3f\r", tool[new_tool].mpos[X_AXIS], tool[new_tool].mpos[Y_AXIS] - 20.0); //
gc_execute_line(gcode_line, CLIENT_INPUT);
current_tool = new_tool;
atc_tool_setter();
// is spindle on?
if (spindle_on) {
sprintf(gcode_line, "M3\r"); //
gc_execute_line(gcode_line, CLIENT_INPUT);
}
// return to saved mpos
sprintf(gcode_line, "G53G0X%0.3fY%0.3fZ%0.3f\r", saved_mpos[X_AXIS], saved_mpos[Y_AXIS], saved_mpos[Z_AXIS]); //
gc_execute_line(gcode_line, CLIENT_INPUT);
// TODO wait for spinup
}
// Polar coaster has macro buttons, this handles those button pushes.
void user_defined_macro(uint8_t index) {
}
void user_defined_macro(uint8_t index) {}
void user_m30() {
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC M30");
}
// ============= Local functions ==================
void go_above_tool(uint8_t tool_num) {
char gcode_line[80];
// raise up
sprintf(gcode_line, "G53G0Z-1");
gc_execute_line(gcode_line, CLIENT_INPUT);
// move in front
sprintf(gcode_line, "G53G0X%0.3fY%0.3f\r", tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - 20.0); //
gc_execute_line(gcode_line, CLIENT_INPUT);
// Move over tool
sprintf(gcode_line, "G53G0Y%0.3f\r", tool[tool_num].mpos[Y_AXIS]); //
gc_execute_line(gcode_line, CLIENT_INPUT);
}
void return_tool(uint8_t tool_num) {
char gcode_line[80];
if (tool_num == 0)
return;
go_above_tool(tool_num);
// drop down to tool
sprintf(gcode_line, "G53G0Z%0.3f\r", tool[tool_num].mpos[Z_AXIS]); //
gc_execute_line(gcode_line, CLIENT_INPUT);
// release tool
// open ATC
protocol_buffer_synchronize(); // wait for it
set_ATC_open(true);
// wait
sprintf(gcode_line, "G4P0.5\r"); //
gc_execute_line(gcode_line, CLIENT_INPUT);
// raise up
sprintf(gcode_line, "G53G0Z-1");
gc_execute_line(gcode_line, CLIENT_INPUT);
// close ATC
protocol_buffer_synchronize(); // wait for it
set_ATC_open(false);
// move forward
sprintf(gcode_line, "G53G0X%0.3fY%0.3f\r", tool[tool_num].mpos[X_AXIS], tool[tool_num].mpos[Y_AXIS] - 20.0); //
gc_execute_line(gcode_line, CLIENT_INPUT);
}
void atc_tool_setter() {
char gcode_line[80];
float print_position[MAX_N_AXIS];
go_above_tool(0);
// probe
sprintf(gcode_line, "G38.2F%0.3fZ%0.3f\r", 300.0, -15); //
gc_execute_line(gcode_line, CLIENT_INPUT);
protocol_buffer_synchronize();
system_convert_array_steps_to_mpos(print_position, sys_probe_position);
// TODO was probe successful?
// Get the Z height ...
tool[current_tool].offset[Z_AXIS] = print_position[Z_AXIS];
// raise up
sprintf(gcode_line, "G53G0Z-1");
gc_execute_line(gcode_line, CLIENT_INPUT);
// move forward
sprintf(gcode_line, "G53G0X%0.3fY%0.3f\r", tool[0].mpos[X_AXIS], tool[0].mpos[Y_AXIS] - 20.0); //
gc_execute_line(gcode_line, CLIENT_INPUT);
}
bool set_ATC_open(bool open) {
// todo lots of safety checks
if (gc_state.modal.spindle != SpindleState::Disable) {
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "ATC Fail spindle on during change");
return false;
}
digitalWrite(ATC_RELEASE_PIN, open);
return true;
}

View File

@@ -121,13 +121,11 @@ void forward_kinematics(float* position) {
}
#endif
#ifdef USE_TOOL_CHANGE
/*
user_tool_change() is called when tool change gcode is received,
to perform appropriate actions for your machine.
*/
void user_tool_change(uint8_t new_tool) {}
#endif
#if defined(MACRO_BUTTON_0_PIN) || defined(MACRO_BUTTON_1_PIN) || defined(MACRO_BUTTON_2_PIN)
/*

View File

@@ -1,183 +0,0 @@
/*
esp32_printer_controller.cpp (copy and use your machine name)
Part of Grbl_ESP32
copyright (c) 2020 - Bart Dring. This file was intended for use on the ESP32
...add your date and name here.
CPU. Do not use this with Grbl for atMega328P
Grbl_ESP32 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_ESP32 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 <http://www.gnu.org/licenses/>.
=======================================================================
This is a template for user-defined C++ code functions. Grbl can be
configured to call some optional functions, enabled by #define statements
in the machine definition .h file. Implement the functions thus enabled
herein. The possible functions are listed and described below.
To use this file, copy it to a name of your own choosing, and also copy
Machines/template.h to a similar name.
Example:
Machines/my_machine.h
Custom/my_machine.cpp
Edit machine.h to include your Machines/my_machine.h file
Edit Machines/my_machine.h according to the instructions therein.
Fill in the function definitions below for the functions that you have
enabled with USE_ defines in Machines/my_machine.h
===============================================================================
*/
#ifdef USE_MACHINE_INIT
/*
machine_init() is called when Grbl_ESP32 first starts. You can use it to do any
special things your machine needs at startup.
*/
# define STEPPERS_DISABLE_PIN_X 138
# define STEPPERS_DISABLE_PIN_Y 134
# define STEPPERS_DISABLE_PIN_Z 131
# define STEPPERS_DISABLE_PIN_A 139
# define FAN1_PIN 13
# define FAN2_PIN 142
# define FAN3_PIN 143
# define BED_PIN 4
# define NOZZLE_PIN 2
void machine_init() {
// Enable steppers
digitalWrite(STEPPERS_DISABLE_PIN_X, LOW); // enable
digitalWrite(STEPPERS_DISABLE_PIN_Y, LOW); // enable
digitalWrite(STEPPERS_DISABLE_PIN_Z, LOW); // enable
digitalWrite(STEPPERS_DISABLE_PIN_A, LOW); // enable
// digitalWrite(FAN1_PIN, LOW); // comment out for JTAG debugging
digitalWrite(FAN2_PIN, LOW); // disable
digitalWrite(FAN3_PIN, LOW); // disable
digitalWrite(BED_PIN, LOW); // disable
digitalWrite(NOZZLE_PIN, LOW); // disable
}
#endif
#ifdef USE_CUSTOM_HOMING
/*
(user_defined_homing) is called at the begining of the normal Grbl_ESP32 homing
sequence. If user_defined_homing() returns false, the rest of normal Grbl_ESP32
homing is skipped if it returns false, other normal homing continues. For
example, if you need to manually prep the machine for homing, you could implement
user_defined_homing() to wait for some button to be pressed, then return true.
*/
bool user_defined_homing(uint8_t cycle_mask) {
// True = done with homing, false = continue with normal Grbl_ESP32 homing
return true;
}
#endif
#ifdef USE_KINEMATICS
/*
Inverse Kinematics converts X,Y,Z cartesian coordinate to the steps
on your "joint" motors. It requires the following three functions:
*/
/*
inverse_kinematics() looks at incoming move commands and modifies
them before Grbl_ESP32 puts them in the motion planner.
Grbl_ESP32 processes arcs by converting them into tiny little line segments.
Kinematics in Grbl_ESP32 works the same way. Search for this function across
Grbl_ESP32 for examples. You are basically converting cartesian X,Y,Z... targets to
target = an N_AXIS array of target positions (where the move is supposed to go)
pl_data = planner data (see the definition of this type to see what it is)
position = an N_AXIS array of where the machine is starting from for this move
*/
void inverse_kinematics(float* target, plan_line_data_t* pl_data, float* position) {
// this simply moves to the target. Replace with your kinematics.
mc_line(target, pl_data);
}
/*
kinematics_pre_homing() is called before normal homing
You can use it to do special homing or just to set stuff up
cycle_mask is a bit mask of the axes being homed this time.
*/
bool kinematics_pre_homing(uint8_t cycle_mask))
{
return false; // finish normal homing cycle
}
/*
kinematics_post_homing() is called at the end of normal homing
*/
void kinematics_post_homing() {}
#endif
#ifdef USE_FWD_KINEMATICS
/*
The status command uses forward_kinematics() to convert
your motor positions to cartesian X,Y,Z... coordinates.
Convert the N_AXIS array of motor positions to cartesian in your code.
*/
void forward_kinematics(float* position) {
// position[X_AXIS] =
// position[Y_AXIS] =
}
#endif
#ifdef USE_TOOL_CHANGE
/*
user_tool_change() is called when tool change gcode is received,
to perform appropriate actions for your machine.
*/
void user_tool_change(uint8_t new_tool) {}
#endif
#if defined(MACRO_BUTTON_0_PIN) || defined(MACRO_BUTTON_1_PIN) || defined(MACRO_BUTTON_2_PIN)
/*
options. user_defined_macro() is called with the button number to
perform whatever actions you choose.
*/
void user_defined_macro(uint8_t index) {}
#endif
#ifdef USE_M30
/*
user_m30() is called when an M30 gcode signals the end of a gcode file.
*/
void user_m30() {}
#endif
#ifdef USE_MACHINE_TRINAMIC_INIT
/*
machine_triaminic_setup() replaces the normal setup of trinamic
drivers with your own code. For example, you could setup StallGuard
*/
void machine_trinamic_setup() {}
#endif
// If you add any additional functions specific to your machine that
// require calls from common code, guard their calls in the common code with
// #ifdef USE_WHATEVER and add function prototypes (also guarded) to grbl.h

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_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

@@ -488,10 +488,7 @@ Error gc_execute_line(char* line, uint8_t client) {
break;
case 6: // tool change
gc_block.modal.tool_change = ToolChange::Enable;
#ifdef USE_TOOL_CHANGE
//user_tool_change(gc_state.tool);
#endif
mg_word_bit = ModalGroup::MM6;
mg_word_bit = ModalGroup::MM6;
break;
case 7:
case 8:
@@ -1355,9 +1352,7 @@ Error gc_execute_line(char* line, uint8_t client) {
// gc_state.tool = gc_block.values.t;
// [6. Change tool ]: NOT SUPPORTED
if (gc_block.modal.tool_change == ToolChange::Enable) {
#ifdef USE_TOOL_CHANGE
user_tool_change(gc_state.tool);
#endif
user_tool_change(gc_state.tool); // (weak) should be user defined
}
// [7. Spindle control ]:
if (gc_state.modal.spindle != gc_block.modal.spindle) {
@@ -1604,6 +1599,8 @@ Error gc_execute_line(char* line, uint8_t client) {
return Error::Ok;
}
__attribute__((weak)) void user_tool_change(uint8_t new_tool) {}
/*
Not supported:

View File

@@ -115,5 +115,4 @@ void user_defined_macro(uint8_t index);
// Called if USE_M30 is defined
void user_m30();
// Called if USE_TOOL_CHANGE is defined
void user_tool_change(uint8_t new_tool);
void user_tool_change(uint8_t new_tool); // weak

View File

@@ -29,7 +29,6 @@
#define N_AXIS 3
#define USE_MACHINE_INIT
#define USE_TOOL_CHANGE
#define USE_M30 // use the user defined end of program
// === Special Features
@@ -72,36 +71,6 @@
https://github.com/bdring/6-Pack_CNC_Controller/wiki/CNC-I-O-Module-List
Click on each module to get example for using the modules in the sockets
Socket #1
#1 GPIO_NUM_33
#2 GPIO_NUM_32
#3 GPIO_NUM_35 (input only)
#4 GPIO_NUM_34 (input only)
Socket #2
#1 GPIO_NUM_2
#2 GPIO_NUM_25
#3 GPIO_NUM_39 (input only)
#4 GPIO_NUM_36 (input only)
Socket #3
#1 GPIO_NUM_26
#2 GPIO_NUM_4
#3 GPIO_NUM_16
#4 GPIO_NUM_27
Socket #4
#1 GPIO_NUM_14
#2 GPIO_NUM_13
#3 GPIO_NUM_15
#4 GPIO_NUM_12
Socket #5
#1 I2SO(24) (output only)
#2 I2SO(25) (output only)
#3 I2SO26) (output only)
*/
@@ -110,21 +79,18 @@ Socket #5
#define X_LIMIT_PIN GPIO_NUM_33
#define Y_LIMIT_PIN GPIO_NUM_32
#define Z_LIMIT_PIN GPIO_NUM_35
#define PROBE_PIN GPIO_NUM_34
// 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
#define SPINDLE_OUTPUT_PIN GPIO_NUM_12
#define ATC_RELEASE_PIN GPIO_NUM_13 // optional
#define COOLANT_MIST_PIN GPIO_NUM_15 // optional
#define COOLANT_FLOOD_PIN GPIO_NUM_14
// // 4x Input Module in Socket #2
// // https://github.com/bdring/6-Pack_CNC_Controller/wiki/4x-Switch-Input-module
// #define X_LIMIT_PIN GPIO_NUM_2
// #define Y_LIMIT_PIN GPIO_NUM_25
// #define Z_LIMIT_PIN GPIO_NUM_39
// // 4x Input Module in Socket #3
// // https://github.com/bdring/6-Pack_CNC_Controller/wiki/4x-Switch-Input-module
// #define CONTROL_CYCLE_START_PIN GPIO_NUM_26
// #define CONTROL_FEED_HOLD_PIN GPIO_NUM_4
// #define CONTROL_RESET_PIN GPIO_NUM_16
// #define CONTROL_SAFETY_DOOR_PIN GPIO_NUM_27
// //#define INVERT_CONTROL_PIN_MASK B0000
#define DEFAULT_SPINDLE_DELAY_SPINUP 5.0
#define DEFAULT_SPINDLE_DELAY_SPINDOWN 5.0
// ================= Setting Defaults ==========================
#define DEFAULT_X_STEPS_PER_MM 800

View File

@@ -142,7 +142,6 @@
// tells grbl we have some special functions to call
#define USE_MACHINE_INIT
#define USE_CUSTOM_HOMING
#define USE_TOOL_CHANGE
#define ATARI_TOOL_CHANGE_Z 5.0
#define USE_M30 // use the user defined end of program

View File

@@ -196,10 +196,6 @@
// systems back to Cartesian form, for status reports.
//#define USE_FWD_KINEMATICS
// USE_TOOL_CHANGE enables the user_tool_change() function
// that implements custom tool change procedures.
// #define USE_TOOL_CHANGE
// Any one of MACRO_BUTTON_0_PIN, MACRO_BUTTON_1_PIN, and MACRO_BUTTON_2_PIN
// enables the user_defined_macro(number) function which
// implements custom behavior at the press of a button

View File

@@ -408,7 +408,6 @@ GCUpdatePos mc_probe_cycle(float* target, plan_line_data_t* pl_data, uint8_t par
return GCUpdatePos::None; // Nothing else to do but bail.
}
// Setup and queue probing motion. Auto cycle-start should not start the cycle.
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Found");
mc_line_kins(target, pl_data, gc_state.position);
// Activate the probing state monitor in the stepper module.
sys_probe_state = Probe::Active;