Hard limits, homing direction, pull-off limits after homing, status reports in mm or inches, system alarm, and more.
- Thank you statement added for Alden Hart of Synthetos. - Hard limits option added, which also works with homing by pulling off the switches to help prevent unintended triggering. Hard limits use a interrupt to sense a falling edge pin change and immediately go into alarm mode, which stops everything and forces the user to issue a reset (Ctrl-x) or reboot. - Auto cycle start now a configuration option. - Alarm mode: A new method to kill all Grbl processes in the event of something catastrophic or potentially catastropic. Just works with hard limits for now, but will be expanded to include g-code errors (most likely) and other events. - Updated status reports to be configurable in inches or mm mode. Much more to do here, but this is the first step. - New settings: auto cycle start, hard limit enable, homing direction mask (which works the same as the stepper mask), homing pulloff distance (or distance traveled from homed machine zero to prevent accidental limit trip). - Minor memory liberation and calculation speed ups.
This commit is contained in:
parent
34f6d2eb4b
commit
df5bb70b25
8
config.h
8
config.h
@ -46,9 +46,9 @@
|
|||||||
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
|
#define X_LIMIT_BIT 1 // Uno Digital Pin 9
|
||||||
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
|
#define Y_LIMIT_BIT 2 // Uno Digital Pin 10
|
||||||
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
|
#define Z_LIMIT_BIT 3 // Uno Digital Pin 11
|
||||||
// #define LIMIT_INT PCIE0 // Pin change interrupt settings
|
#define LIMIT_INT PCIE0 // Pin change interrupt settings
|
||||||
// #define LIMIT_INT_vect PCINT0_vect
|
#define LIMIT_INT_vect PCINT0_vect
|
||||||
// #define LIMIT_PCMSK PCMSK0
|
#define LIMIT_PCMSK PCMSK0
|
||||||
|
|
||||||
#define SPINDLE_ENABLE_DDR DDRB
|
#define SPINDLE_ENABLE_DDR DDRB
|
||||||
#define SPINDLE_ENABLE_PORT PORTB
|
#define SPINDLE_ENABLE_PORT PORTB
|
||||||
@ -159,9 +159,7 @@
|
|||||||
// TODO: The following options are set as compile-time options for now, until the next EEPROM
|
// TODO: The following options are set as compile-time options for now, until the next EEPROM
|
||||||
// settings version has solidified. This is to prevent having to support dozens of different
|
// settings version has solidified. This is to prevent having to support dozens of different
|
||||||
// incremental settings versions.
|
// incremental settings versions.
|
||||||
#define CYCLE_AUTO_START 1 // Cycle auto-start boolean flag for the planner.
|
|
||||||
#define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
|
#define BLOCK_DELETE_ENABLE 0 // Block delete enable/disable flag during g-code parsing
|
||||||
#define REPORT_INCH_MODE 0 // Status reporting unit mode (1 = inch, 0 = mm)
|
|
||||||
|
|
||||||
// This parameter sets the delay time before disabling the steppers after the final block of movement.
|
// This parameter sets the delay time before disabling the steppers after the final block of movement.
|
||||||
// A short delay ensures the steppers come to a complete stop and the residual inertial force in the
|
// A short delay ensures the steppers come to a complete stop and the residual inertial force in the
|
||||||
|
5
gcode.c
5
gcode.c
@ -108,7 +108,8 @@ void gc_init()
|
|||||||
// protocol_status_message(settings_execute_startup());
|
// protocol_status_message(settings_execute_startup());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets g-code parser position in mm. Input in steps. Called by the system abort routine.
|
// Sets g-code parser position in mm. Input in steps. Called by the system abort and hard
|
||||||
|
// limit pull-off routines.
|
||||||
void gc_set_current_position(int32_t x, int32_t y, int32_t z)
|
void gc_set_current_position(int32_t x, int32_t y, int32_t z)
|
||||||
{
|
{
|
||||||
gc.position[X_AXIS] = x/settings.steps_per_mm[X_AXIS];
|
gc.position[X_AXIS] = x/settings.steps_per_mm[X_AXIS];
|
||||||
@ -183,7 +184,7 @@ uint8_t gc_execute_line(char *line)
|
|||||||
case 21: gc.inches_mode = false; break;
|
case 21: gc.inches_mode = false; break;
|
||||||
case 28: case 30:
|
case 28: case 30:
|
||||||
// NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
|
// NOTE: G28.1, G30.1 sets home position parameters. Not currently supported.
|
||||||
if (bit_istrue(settings.flags,FLAG_BIT_HOMING_ENABLE)) {
|
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) {
|
||||||
non_modal_action = NON_MODAL_GO_HOME;
|
non_modal_action = NON_MODAL_GO_HOME;
|
||||||
} else {
|
} else {
|
||||||
FAIL(STATUS_SETTING_DISABLED);
|
FAIL(STATUS_SETTING_DISABLED);
|
||||||
|
35
limits.c
35
limits.c
@ -38,8 +38,31 @@ void limits_init()
|
|||||||
{
|
{
|
||||||
LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins
|
LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins
|
||||||
LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation.
|
LIMIT_PORT |= (LIMIT_MASK); // Enable internal pull-up resistors. Normal high operation.
|
||||||
|
|
||||||
|
if bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE) {
|
||||||
|
MCUCR = (1<<ISC01) | (0<<ISC00); //1 0 triggers at a falling edge.
|
||||||
|
LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt
|
||||||
|
PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is the Limit Pin Change Interrupt, which handles the hard limit feature. This is
|
||||||
|
// called when Grbl detects a falling edge on a limit pin.
|
||||||
|
// NOTE: Do not attach an e-stop to the limit pins, because this interrupt is disabled during
|
||||||
|
// homing cycles and will not respond correctly. Upon user request or need, there may be a
|
||||||
|
// special pinout for an e-stop, but it is generally recommended to just directly connect
|
||||||
|
// your e-stop switch to the Arduino reset pin, since it is the most correct way to do this.
|
||||||
|
ISR(LIMIT_INT_vect)
|
||||||
|
{
|
||||||
|
// Kill all processes upon hard limit event.
|
||||||
|
st_go_idle(); // Immediately stop stepper motion
|
||||||
|
spindle_stop(); // Stop spindle
|
||||||
|
sys.auto_start = false; // Disable auto cycle start.
|
||||||
|
sys.execute |= EXEC_ALARM;
|
||||||
|
// TODO: When Grbl system status is installed, update here to indicate loss of position.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Moves all specified axes in same specified direction (positive=true, negative=false)
|
// Moves all specified axes in same specified direction (positive=true, negative=false)
|
||||||
// and at the homing rate. Homing is a special motion case, where there is only an
|
// and at the homing rate. Homing is a special motion case, where there is only an
|
||||||
// acceleration followed by abrupt asynchronous stops by each axes reaching their limit
|
// acceleration followed by abrupt asynchronous stops by each axes reaching their limit
|
||||||
@ -85,6 +108,7 @@ static void homing_cycle(bool x_axis, bool y_axis, bool z_axis, int8_t pos_dir,
|
|||||||
|
|
||||||
// Set default out_bits.
|
// Set default out_bits.
|
||||||
uint8_t out_bits0 = settings.invert_mask;
|
uint8_t out_bits0 = settings.invert_mask;
|
||||||
|
out_bits0 ^= (settings.homing_dir_mask & DIRECTION_MASK); // Apply homing direction settings
|
||||||
if (!pos_dir) { out_bits0 ^= DIRECTION_MASK; } // Invert bits, if negative dir.
|
if (!pos_dir) { out_bits0 ^= DIRECTION_MASK; } // Invert bits, if negative dir.
|
||||||
|
|
||||||
// Initialize stepping variables
|
// Initialize stepping variables
|
||||||
@ -161,10 +185,7 @@ static void homing_cycle(bool x_axis, bool y_axis, bool z_axis, int8_t pos_dir,
|
|||||||
|
|
||||||
void limits_go_home()
|
void limits_go_home()
|
||||||
{
|
{
|
||||||
plan_synchronize(); // Empty all motions in buffer.
|
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT); // Enable steppers, but not the cycle.
|
||||||
|
|
||||||
// Enable steppers by resetting the stepper disable port
|
|
||||||
STEPPERS_DISABLE_PORT &= ~(1<<STEPPERS_DISABLE_BIT);
|
|
||||||
|
|
||||||
// Jog all axes toward home to engage their limit switches at faster homing seek rate.
|
// Jog all axes toward home to engage their limit switches at faster homing seek rate.
|
||||||
homing_cycle(false, false, true, true, false, settings.homing_seek_rate); // First jog the z axis
|
homing_cycle(false, false, true, true, false, settings.homing_seek_rate); // First jog the z axis
|
||||||
@ -186,9 +207,5 @@ void limits_go_home()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delay_ms(settings.stepper_idle_lock_time);
|
st_go_idle(); // Call main stepper shutdown routine.
|
||||||
// Disable steppers by setting stepper disable
|
|
||||||
if (settings.stepper_idle_lock_time != 0xff) {
|
|
||||||
STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
10
main.c
10
main.c
@ -19,6 +19,10 @@
|
|||||||
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* A big thanks to Alden Hart of Synthetos, supplier of grblshield and TinyG, who has
|
||||||
|
been integral throughout the development of the higher level details of Grbl, as well
|
||||||
|
as being a consistent sounding board for the future of accessible and free CNC. */
|
||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -47,6 +51,8 @@ int main(void)
|
|||||||
memset(&sys, 0, sizeof(sys)); // Clear all system variables
|
memset(&sys, 0, sizeof(sys)); // Clear all system variables
|
||||||
sys.abort = true; // Set abort to complete initialization
|
sys.abort = true; // Set abort to complete initialization
|
||||||
|
|
||||||
|
// TODO: When Grbl system status is installed, need to set position lost state upon startup.
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
// Execute system reset upon a system abort, where the main program will return to this loop.
|
// Execute system reset upon a system abort, where the main program will return to this loop.
|
||||||
@ -87,9 +93,9 @@ int main(void)
|
|||||||
// Set system runtime defaults
|
// Set system runtime defaults
|
||||||
// TODO: Eventual move to EEPROM from config.h when all of the new settings are worked out.
|
// TODO: Eventual move to EEPROM from config.h when all of the new settings are worked out.
|
||||||
// Mainly to avoid having to maintain several different versions.
|
// Mainly to avoid having to maintain several different versions.
|
||||||
#ifdef CYCLE_AUTO_START
|
if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) {
|
||||||
sys.auto_start = true;
|
sys.auto_start = true;
|
||||||
#endif
|
}
|
||||||
// TODO: Install G20/G21 unit default into settings and load appropriate settings.
|
// TODO: Install G20/G21 unit default into settings and load appropriate settings.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,9 +196,30 @@ void mc_dwell(float seconds)
|
|||||||
// Execute homing cycle to locate and set machine zero.
|
// Execute homing cycle to locate and set machine zero.
|
||||||
void mc_go_home()
|
void mc_go_home()
|
||||||
{
|
{
|
||||||
limits_go_home();
|
plan_synchronize(); // Empty all motions in buffer before homing.
|
||||||
|
PCICR &= ~(1 << LIMIT_INT); // Disable hard limits pin change interrupt
|
||||||
|
|
||||||
|
limits_go_home(); // Perform homing routine.
|
||||||
|
|
||||||
// Upon completion, reset all internal position vectors (g-code parser, planner, system)
|
// Upon completion, reset all internal position vectors (g-code parser, planner, system)
|
||||||
gc_clear_position();
|
gc_clear_position();
|
||||||
plan_clear_position();
|
plan_clear_position();
|
||||||
clear_vector_float(sys.position);
|
clear_vector_float(sys.position);
|
||||||
|
|
||||||
|
// If hard limits enabled, move all axes off limit switches before enabling the hard limit
|
||||||
|
// pin change interrupt. This should help prevent the switches from falsely tripping.
|
||||||
|
// NOTE: G-code parser was circumvented so its position needs to be updated explicitly.
|
||||||
|
if (bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)) {
|
||||||
|
int8_t x_dir, y_dir, z_dir;
|
||||||
|
x_dir = y_dir = z_dir = 1;
|
||||||
|
if (bit_istrue(settings.homing_dir_mask,bit(X_DIRECTION_BIT))) { x_dir = -1; }
|
||||||
|
if (bit_istrue(settings.homing_dir_mask,bit(Y_DIRECTION_BIT))) { y_dir = -1; }
|
||||||
|
if (bit_istrue(settings.homing_dir_mask,bit(Z_DIRECTION_BIT))) { z_dir = -1; }
|
||||||
|
mc_line(x_dir*settings.homing_pulloff, y_dir*settings.homing_pulloff,
|
||||||
|
z_dir*settings.homing_pulloff, settings.homing_feed_rate, false);
|
||||||
|
st_cycle_start(); // Nothing should be in the buffer except this motion.
|
||||||
|
plan_synchronize(); // Make sure the motion completes.
|
||||||
|
gc_set_current_position(sys.position[X_AXIS],sys.position[Y_AXIS],sys.position[Z_AXIS]);
|
||||||
|
PCICR |= (1 << LIMIT_INT); // Re-enable hard limits.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
17
nuts_bolts.h
17
nuts_bolts.h
@ -35,6 +35,7 @@
|
|||||||
#define Z_AXIS 2
|
#define Z_AXIS 2
|
||||||
|
|
||||||
#define MM_PER_INCH (25.4)
|
#define MM_PER_INCH (25.4)
|
||||||
|
#define INCH_PER_MM (0.03937)
|
||||||
|
|
||||||
// Useful macros
|
// Useful macros
|
||||||
#define clear_vector(a) memset(a, 0, sizeof(a))
|
#define clear_vector(a) memset(a, 0, sizeof(a))
|
||||||
@ -60,15 +61,28 @@
|
|||||||
#define EXEC_CYCLE_STOP bit(2) // bitmask 00000100
|
#define EXEC_CYCLE_STOP bit(2) // bitmask 00000100
|
||||||
#define EXEC_FEED_HOLD bit(3) // bitmask 00001000
|
#define EXEC_FEED_HOLD bit(3) // bitmask 00001000
|
||||||
#define EXEC_RESET bit(4) // bitmask 00010000
|
#define EXEC_RESET bit(4) // bitmask 00010000
|
||||||
// #define bit(5) // bitmask 00100000
|
#define EXEC_ALARM bit(5) // bitmask 00100000
|
||||||
// #define bit(6) // bitmask 01000000
|
// #define bit(6) // bitmask 01000000
|
||||||
// #define bit(7) // bitmask 10000000
|
// #define bit(7) // bitmask 10000000
|
||||||
|
|
||||||
|
// Define bit flag masks for sys.switches. (8 flag limit)
|
||||||
|
#define BITFLAG_BLOCK_DELETE bit(0)
|
||||||
|
#define BITFLAG_SINGLE_BLOCK bit(1)
|
||||||
|
#define BITFLAG_OPT_STOP bit(2)
|
||||||
|
// #define bit(3)
|
||||||
|
// #define bit(4)
|
||||||
|
// #define bit(5)
|
||||||
|
// #define bit(6)
|
||||||
|
// #define bit(7)
|
||||||
|
|
||||||
// Define global system variables
|
// Define global system variables
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
|
uint8_t abort; // System abort flag. Forces exit back to main loop for reset.
|
||||||
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
|
uint8_t feed_hold; // Feed hold flag. Held true during feed hold. Released when ready to resume.
|
||||||
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
|
uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings.
|
||||||
|
uint8_t alarm; // Alarm mode. Causes all functions to immediately cease until a system abort
|
||||||
|
// is issued by the user.
|
||||||
|
// uint8_t switches; // Switches state bitflag variable. For settings not governed by g-code.
|
||||||
|
|
||||||
int32_t position[3]; // Real-time machine (aka home) position vector in steps.
|
int32_t position[3]; // Real-time machine (aka home) position vector in steps.
|
||||||
// NOTE: This may need to be a volatile variable, if problems arise.
|
// NOTE: This may need to be a volatile variable, if problems arise.
|
||||||
@ -82,6 +96,7 @@ typedef struct {
|
|||||||
|
|
||||||
volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
|
volatile uint8_t cycle_start; // Cycle start flag. Set by stepper subsystem or main program.
|
||||||
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
|
volatile uint8_t execute; // Global system runtime executor bitflag variable. See EXEC bitmasks.
|
||||||
|
|
||||||
} system_t;
|
} system_t;
|
||||||
extern system_t sys;
|
extern system_t sys;
|
||||||
|
|
||||||
|
57
protocol.c
57
protocol.c
@ -73,7 +73,7 @@ void protocol_status_report()
|
|||||||
// may be distance to go on block, processed block id, and feed rate. A secondary, non-critical
|
// may be distance to go on block, processed block id, and feed rate. A secondary, non-critical
|
||||||
// status report may include g-code state, i.e. inch mode, plane mode, absolute mode, etc.
|
// status report may include g-code state, i.e. inch mode, plane mode, absolute mode, etc.
|
||||||
// The report generated must be as short as possible, yet still provide the user easily readable
|
// The report generated must be as short as possible, yet still provide the user easily readable
|
||||||
// information, i.e. 'x0.23,y120.4,z2.4'. This is necessary as it minimizes the computational
|
// information, i.e. '[0.23,120.4,2.4]'. This is necessary as it minimizes the computational
|
||||||
// overhead and allows grbl to keep running smoothly, especially with g-code programs with fast,
|
// overhead and allows grbl to keep running smoothly, especially with g-code programs with fast,
|
||||||
// short line segments and interface setups that require real-time status reports (5-20Hz).
|
// short line segments and interface setups that require real-time status reports (5-20Hz).
|
||||||
|
|
||||||
@ -85,24 +85,33 @@ void protocol_status_report()
|
|||||||
// home position by the user (likely through '$' setting interface).
|
// home position by the user (likely through '$' setting interface).
|
||||||
// Successfully tested at a query rate of 10-20Hz while running a gauntlet of programs at various
|
// Successfully tested at a query rate of 10-20Hz while running a gauntlet of programs at various
|
||||||
// speeds.
|
// speeds.
|
||||||
int32_t print_position[3];
|
uint8_t i;
|
||||||
memcpy(print_position,sys.position,sizeof(sys.position));
|
int32_t current_position[3]; // Copy current state of the system position variable
|
||||||
#if REPORT_INCH_MODE
|
memcpy(current_position,sys.position,sizeof(sys.position));
|
||||||
printString("MPos:["); printFloat(print_position[X_AXIS]/(settings.steps_per_mm[X_AXIS]*MM_PER_INCH));
|
float print_position[3];
|
||||||
printString(","); printFloat(print_position[Y_AXIS]/(settings.steps_per_mm[Y_AXIS]*MM_PER_INCH));
|
|
||||||
printString(","); printFloat(print_position[Z_AXIS]/(settings.steps_per_mm[Z_AXIS]*MM_PER_INCH));
|
// Report machine position
|
||||||
printString("],WPos:["); printFloat((print_position[X_AXIS]/settings.steps_per_mm[X_AXIS]-sys.coord_system[sys.coord_select][X_AXIS]-sys.coord_offset[X_AXIS])/MM_PER_INCH);
|
printPgmString(PSTR("MPos:["));
|
||||||
printString(","); printFloat((print_position[Y_AXIS]/settings.steps_per_mm[Y_AXIS]-sys.coord_system[sys.coord_select][Y_AXIS]-sys.coord_offset[Y_AXIS])/MM_PER_INCH);
|
for (i=0; i<= 2; i++) {
|
||||||
printString(","); printFloat((print_position[Z_AXIS]/settings.steps_per_mm[Z_AXIS]-sys.coord_system[sys.coord_select][Z_AXIS]-sys.coord_offset[Z_AXIS])/MM_PER_INCH);
|
print_position[i] = current_position[i]/settings.steps_per_mm[i];
|
||||||
#else
|
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) { print_position[i] *= INCH_PER_MM; }
|
||||||
printString("MPos:["); printFloat(print_position[X_AXIS]/(settings.steps_per_mm[X_AXIS]));
|
printFloat(print_position[i]);
|
||||||
printString(","); printFloat(print_position[Y_AXIS]/(settings.steps_per_mm[Y_AXIS]));
|
if (i < 2) { printPgmString(PSTR(",")); }
|
||||||
printString(","); printFloat(print_position[Z_AXIS]/(settings.steps_per_mm[Z_AXIS]));
|
}
|
||||||
printString("],WPos:["); printFloat(print_position[X_AXIS]/settings.steps_per_mm[X_AXIS]-sys.coord_system[sys.coord_select][X_AXIS]-sys.coord_offset[X_AXIS]);
|
|
||||||
printString(","); printFloat(print_position[Y_AXIS]/settings.steps_per_mm[Y_AXIS]-sys.coord_system[sys.coord_select][Y_AXIS]-sys.coord_offset[Y_AXIS]);
|
// Report work position
|
||||||
printString(","); printFloat(print_position[Z_AXIS]/settings.steps_per_mm[Z_AXIS]-sys.coord_system[sys.coord_select][Z_AXIS]-sys.coord_offset[Z_AXIS]);
|
printPgmString(PSTR("],WPos:["));
|
||||||
#endif
|
for (i=0; i<= 2; i++) {
|
||||||
printString("]\r\n");
|
if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
|
||||||
|
print_position[i] -= (sys.coord_system[sys.coord_select][i]+sys.coord_offset[i])*INCH_PER_MM;
|
||||||
|
} else {
|
||||||
|
print_position[i] -= sys.coord_system[sys.coord_select][i]+sys.coord_offset[i];
|
||||||
|
}
|
||||||
|
printFloat(print_position[i]);
|
||||||
|
if (i < 2) { printPgmString(PSTR(",")); }
|
||||||
|
}
|
||||||
|
|
||||||
|
printPgmString(PSTR("]\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -130,6 +139,12 @@ void protocol_execute_runtime()
|
|||||||
if (sys.execute) { // Enter only if any bit flag is true
|
if (sys.execute) { // Enter only if any bit flag is true
|
||||||
uint8_t rt_exec = sys.execute; // Avoid calling volatile multiple times
|
uint8_t rt_exec = sys.execute; // Avoid calling volatile multiple times
|
||||||
|
|
||||||
|
// System alarm. Something has gone wrong. Disable everything until system reset.
|
||||||
|
if (rt_exec & EXEC_ALARM) {
|
||||||
|
while (bit_isfalse(sys.execute,EXEC_RESET)) { sleep_mode(); }
|
||||||
|
bit_false(sys.execute,EXEC_ALARM);
|
||||||
|
}
|
||||||
|
|
||||||
// System abort. Steppers have already been force stopped.
|
// System abort. Steppers have already been force stopped.
|
||||||
if (rt_exec & EXEC_RESET) {
|
if (rt_exec & EXEC_RESET) {
|
||||||
sys.abort = true;
|
sys.abort = true;
|
||||||
@ -157,9 +172,9 @@ void protocol_execute_runtime()
|
|||||||
|
|
||||||
if (rt_exec & EXEC_CYCLE_START) {
|
if (rt_exec & EXEC_CYCLE_START) {
|
||||||
st_cycle_start(); // Issue cycle start command to stepper subsystem
|
st_cycle_start(); // Issue cycle start command to stepper subsystem
|
||||||
#ifdef CYCLE_AUTO_START
|
if (bit_istrue(settings.flags,BITFLAG_AUTO_START)) {
|
||||||
sys.auto_start = true; // Re-enable auto start after feed hold.
|
sys.auto_start = true; // Re-enable auto start after feed hold.
|
||||||
#endif
|
}
|
||||||
bit_false(sys.execute,EXEC_CYCLE_START);
|
bit_false(sys.execute,EXEC_CYCLE_START);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
serial.c
4
serial.c
@ -166,6 +166,10 @@ ISR(USART_RX_vect)
|
|||||||
case CMD_CYCLE_START: sys.execute |= EXEC_CYCLE_START; break; // Set as true
|
case CMD_CYCLE_START: sys.execute |= EXEC_CYCLE_START; break; // Set as true
|
||||||
case CMD_FEED_HOLD: sys.execute |= EXEC_FEED_HOLD; break; // Set as true
|
case CMD_FEED_HOLD: sys.execute |= EXEC_FEED_HOLD; break; // Set as true
|
||||||
case CMD_RESET:
|
case CMD_RESET:
|
||||||
|
sys.alarm |= EXEC_ALARM; // Set alarm to allow subsystem disable for certain settings.
|
||||||
|
|
||||||
|
// TODO: When Grbl system status is installed, set position lost state if the cycle is active.
|
||||||
|
|
||||||
// Immediately force stepper and spindle subsystem idle at an interrupt level.
|
// Immediately force stepper and spindle subsystem idle at an interrupt level.
|
||||||
if (!(sys.execute & EXEC_RESET)) { // Force stop only first time.
|
if (!(sys.execute & EXEC_RESET)) { // Force stop only first time.
|
||||||
st_go_idle();
|
st_go_idle();
|
||||||
|
90
settings.c
90
settings.c
@ -69,14 +69,16 @@ typedef struct {
|
|||||||
#define DEFAULT_STEPPING_INVERT_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT))
|
#define DEFAULT_STEPPING_INVERT_MASK ((1<<X_STEP_BIT)|(1<<Y_STEP_BIT)|(1<<Z_STEP_BIT))
|
||||||
|
|
||||||
// Developmental default settings
|
// Developmental default settings
|
||||||
|
#define DEFAULT_REPORT_INCHES 0 // false
|
||||||
|
#define DEFAULT_AUTO_START 1 // true
|
||||||
|
#define DEFAULT_HARD_LIMIT_ENABLE 0 // false
|
||||||
#define DEFAULT_HOMING_ENABLE 0 // false
|
#define DEFAULT_HOMING_ENABLE 0 // false
|
||||||
|
#define DEFAULT_HOMING_DIR_MASK 0 // move positive dir
|
||||||
#define DEFAULT_HOMING_RAPID_FEEDRATE 250.0 // mm/min
|
#define DEFAULT_HOMING_RAPID_FEEDRATE 250.0 // mm/min
|
||||||
#define DEFAULT_HOMING_FEEDRATE 50 // mm/min
|
#define DEFAULT_HOMING_FEEDRATE 50 // mm/min
|
||||||
#define DEFAULT_HOMING_DEBOUNCE_DELAY 100 // msec (0-65k)
|
#define DEFAULT_HOMING_DEBOUNCE_DELAY 100 // msec (0-65k)
|
||||||
|
#define DEFAULT_HOMING_PULLOFF 1 // mm
|
||||||
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255)
|
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255)
|
||||||
// #define DEFAULT_AUTO_START 1 // true
|
|
||||||
// #define DEFAULT_INCHES_MODE 1 // true
|
|
||||||
// #define DEFAULT_BLOCK_DELETE 0 // false
|
|
||||||
#define DEFAULT_DECIMAL_PLACES 3
|
#define DEFAULT_DECIMAL_PLACES 3
|
||||||
|
|
||||||
void settings_reset(bool reset_all) {
|
void settings_reset(bool reset_all) {
|
||||||
@ -95,12 +97,14 @@ void settings_reset(bool reset_all) {
|
|||||||
}
|
}
|
||||||
// New settings since last version
|
// New settings since last version
|
||||||
settings.flags = 0;
|
settings.flags = 0;
|
||||||
// if (DEFAULT_AUTO_START) { settings.flags |= FLAG_BIT_AUTO_START; }
|
if (DEFAULT_AUTO_START) { settings.flags |= BITFLAG_AUTO_START; }
|
||||||
// if (DEFAULT_INCHES_MODE) { settings.flags |= FLAG_BIT_INCHES_MODE; }
|
if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; }
|
||||||
if (DEFAULT_HOMING_ENABLE) { settings.flags |= FLAG_BIT_HOMING_ENABLE; }
|
if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; }
|
||||||
|
settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK;
|
||||||
settings.homing_feed_rate = DEFAULT_HOMING_FEEDRATE;
|
settings.homing_feed_rate = DEFAULT_HOMING_FEEDRATE;
|
||||||
settings.homing_seek_rate = DEFAULT_HOMING_RAPID_FEEDRATE;
|
settings.homing_seek_rate = DEFAULT_HOMING_RAPID_FEEDRATE;
|
||||||
settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
|
settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
|
||||||
|
settings.homing_pulloff = DEFAULT_HOMING_PULLOFF;
|
||||||
settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
|
settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
|
||||||
settings.decimal_places = DEFAULT_DECIMAL_PLACES;
|
settings.decimal_places = DEFAULT_DECIMAL_PLACES;
|
||||||
}
|
}
|
||||||
@ -111,23 +115,29 @@ void settings_reset(bool reset_all) {
|
|||||||
|
|
||||||
void settings_dump() {
|
void settings_dump() {
|
||||||
printPgmString(PSTR("$0 = ")); printFloat(settings.steps_per_mm[X_AXIS]);
|
printPgmString(PSTR("$0 = ")); printFloat(settings.steps_per_mm[X_AXIS]);
|
||||||
printPgmString(PSTR(" (steps/mm x)\r\n$1 = ")); printFloat(settings.steps_per_mm[Y_AXIS]);
|
printPgmString(PSTR(" (x axis, steps/mm)\r\n$1 = ")); printFloat(settings.steps_per_mm[Y_AXIS]);
|
||||||
printPgmString(PSTR(" (steps/mm y)\r\n$2 = ")); printFloat(settings.steps_per_mm[Z_AXIS]);
|
printPgmString(PSTR(" (y axis, steps/mm)\r\n$2 = ")); printFloat(settings.steps_per_mm[Z_AXIS]);
|
||||||
printPgmString(PSTR(" (steps/mm z)\r\n$3 = ")); printInteger(settings.pulse_microseconds);
|
printPgmString(PSTR(" (z axis, steps/mm)\r\n$3 = ")); printInteger(settings.pulse_microseconds);
|
||||||
printPgmString(PSTR(" (microseconds step pulse)\r\n$4 = ")); printFloat(settings.default_feed_rate);
|
printPgmString(PSTR(" (step pulse, usec)\r\n$4 = ")); printFloat(settings.default_feed_rate);
|
||||||
printPgmString(PSTR(" (mm/min default feed rate)\r\n$5 = ")); printFloat(settings.default_seek_rate);
|
printPgmString(PSTR(" (default feed rate, mm/min)\r\n$5 = ")); printFloat(settings.default_seek_rate);
|
||||||
printPgmString(PSTR(" (mm/min default seek rate)\r\n$6 = ")); printFloat(settings.mm_per_arc_segment);
|
printPgmString(PSTR(" (default seek rate, mm/min)\r\n$6 = ")); printFloat(settings.mm_per_arc_segment);
|
||||||
printPgmString(PSTR(" (mm/arc segment)\r\n$7 = ")); printInteger(settings.invert_mask);
|
printPgmString(PSTR(" (arc resolution, mm/segment)\r\n$7 = ")); printInteger(settings.invert_mask);
|
||||||
printPgmString(PSTR(" (step port invert mask. binary = ")); print_uint8_base2(settings.invert_mask);
|
printPgmString(PSTR(" (step port invert mask, int:binary = ")); print_uint8_base2(settings.invert_mask);
|
||||||
printPgmString(PSTR(")\r\n$8 = ")); printFloat(settings.acceleration/(60*60)); // Convert from mm/min^2 for human readability
|
printPgmString(PSTR(")\r\n$8 = ")); printFloat(settings.acceleration/(60*60)); // Convert from mm/min^2 for human readability
|
||||||
printPgmString(PSTR(" (acceleration in mm/sec^2)\r\n$9 = ")); printFloat(settings.junction_deviation);
|
printPgmString(PSTR(" (acceleration, mm/sec^2)\r\n$9 = ")); printFloat(settings.junction_deviation);
|
||||||
printPgmString(PSTR(" (cornering junction deviation in mm)\r\n$10 = ")); printInteger(bit_istrue(settings.flags,FLAG_BIT_HOMING_ENABLE));
|
printPgmString(PSTR(" (cornering junction deviation, mm)\r\n$10 = ")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
|
||||||
printPgmString(PSTR(" (boolean homing enable)\r\n$11 = ")); printFloat(settings.homing_feed_rate);
|
printPgmString(PSTR(" (status report inches, bool)\r\n$11 = ")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START));
|
||||||
printPgmString(PSTR(" (mm/min homing feed rate)\r\n$12 = ")); printFloat(settings.homing_seek_rate);
|
printPgmString(PSTR(" (auto start enable, bool)\r\n$12 = ")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
|
||||||
printPgmString(PSTR(" (mm/min homing seek rate)\r\n$13 = ")); printInteger(settings.homing_debounce_delay);
|
printPgmString(PSTR(" (hard limit enable, bool)\r\n$13 = ")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
|
||||||
printPgmString(PSTR(" (milliseconds homing debounce delay)\r\n$14 = ")); printInteger(settings.stepper_idle_lock_time);
|
printPgmString(PSTR(" (homing enable, bool)\r\n$14 = ")); printInteger(settings.homing_dir_mask);
|
||||||
printPgmString(PSTR(" (milliseconds stepper idle lock time)\r\n$15 = ")); printInteger(settings.decimal_places);
|
printPgmString(PSTR(" (homing direction mask, int:binary = ")); print_uint8_base2(settings.homing_dir_mask);
|
||||||
printPgmString(PSTR(" (float decimal places)"));
|
printPgmString(PSTR(")\r\n$15 = ")); printFloat(settings.homing_feed_rate);
|
||||||
|
printPgmString(PSTR(" (homing feed rate, mm/min)\r\n$16 = ")); printFloat(settings.homing_seek_rate);
|
||||||
|
printPgmString(PSTR(" (homing seek rate, mm/min)\r\n$17 = ")); printInteger(settings.homing_debounce_delay);
|
||||||
|
printPgmString(PSTR(" (homing debounce delay, msec)\r\n$18 = ")); printFloat(settings.homing_pulloff);
|
||||||
|
printPgmString(PSTR(" (homing pull-off travel, mm)\r\n$19 = ")); printInteger(settings.stepper_idle_lock_time);
|
||||||
|
printPgmString(PSTR(" (stepper idle lock time, msec)\r\n$20 = ")); printInteger(settings.decimal_places);
|
||||||
|
printPgmString(PSTR(" (decimal places, int)"));
|
||||||
|
|
||||||
// char buf[4];
|
// char buf[4];
|
||||||
// settings_startup_string((char *)buf);
|
// settings_startup_string((char *)buf);
|
||||||
@ -262,15 +272,35 @@ void settings_store_setting(int parameter, float value) {
|
|||||||
case 9: settings.junction_deviation = fabs(value); break;
|
case 9: settings.junction_deviation = fabs(value); break;
|
||||||
case 10:
|
case 10:
|
||||||
if (value) {
|
if (value) {
|
||||||
settings.flags |= FLAG_BIT_HOMING_ENABLE;
|
settings.flags |= BITFLAG_REPORT_INCHES;
|
||||||
printPgmString(PSTR("Install all axes limit switches before use\r\n"));
|
} else { settings.flags &= ~BITFLAG_REPORT_INCHES; }
|
||||||
} else { settings.flags &= ~FLAG_BIT_HOMING_ENABLE; }
|
|
||||||
break;
|
break;
|
||||||
case 11: settings.homing_feed_rate = value; break;
|
case 11:
|
||||||
case 12: settings.homing_seek_rate = value; break;
|
if (value) {
|
||||||
case 13: settings.homing_debounce_delay = round(value); break;
|
settings.flags |= BITFLAG_AUTO_START;
|
||||||
case 14: settings.stepper_idle_lock_time = round(value); break;
|
} else { settings.flags &= ~BITFLAG_AUTO_START; }
|
||||||
case 15: settings.decimal_places = round(value); break;
|
break;
|
||||||
|
case 12:
|
||||||
|
if (value) {
|
||||||
|
settings.flags |= BITFLAG_HARD_LIMIT_ENABLE;
|
||||||
|
} else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; }
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if (value) {
|
||||||
|
settings.flags |= BITFLAG_HOMING_ENABLE;
|
||||||
|
printPgmString(PSTR("Install all axes limit switches before use\r\n"));
|
||||||
|
} else { settings.flags &= ~BITFLAG_HOMING_ENABLE; }
|
||||||
|
break;
|
||||||
|
case 14: settings.homing_dir_mask = trunc(value); break;
|
||||||
|
case 15: settings.homing_feed_rate = value; break;
|
||||||
|
case 16: settings.homing_seek_rate = value; break;
|
||||||
|
case 17: settings.homing_debounce_delay = round(value); break;
|
||||||
|
case 18: settings.homing_pulloff = value; break;
|
||||||
|
case 19:
|
||||||
|
settings.stepper_idle_lock_time = round(value);
|
||||||
|
// TODO: Immediately check and toggle steppers from always enable or disable?
|
||||||
|
break;
|
||||||
|
case 20: settings.decimal_places = round(value); break;
|
||||||
default:
|
default:
|
||||||
printPgmString(PSTR("Unknown parameter\r\n"));
|
printPgmString(PSTR("Unknown parameter\r\n"));
|
||||||
return;
|
return;
|
||||||
|
11
settings.h
11
settings.h
@ -29,12 +29,13 @@
|
|||||||
|
|
||||||
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
|
// Version of the EEPROM data. Will be used to migrate existing data from older versions of Grbl
|
||||||
// when firmware is upgraded. Always stored in byte 0 of eeprom
|
// when firmware is upgraded. Always stored in byte 0 of eeprom
|
||||||
#define SETTINGS_VERSION 53
|
#define SETTINGS_VERSION 55
|
||||||
|
|
||||||
// Define bit flag masks in settings.flag.
|
// Define bit flag masks in settings.flag.
|
||||||
#define FLAG_BIT_HOMING_ENABLE bit(0)
|
#define BITFLAG_REPORT_INCHES bit(0)
|
||||||
//#define FLAG_BIT_AUTO_START bit(1)
|
#define BITFLAG_AUTO_START bit(1)
|
||||||
//#define FLAG_BIT_INCHES_MODE bit(2)
|
#define BITFLAG_HARD_LIMIT_ENABLE bit(2)
|
||||||
|
#define BITFLAG_HOMING_ENABLE bit(3)
|
||||||
|
|
||||||
// Current global settings (persisted in EEPROM from byte 1 onwards)
|
// Current global settings (persisted in EEPROM from byte 1 onwards)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -48,9 +49,11 @@ typedef struct {
|
|||||||
float acceleration;
|
float acceleration;
|
||||||
float junction_deviation;
|
float junction_deviation;
|
||||||
uint8_t flags; // Contains default toggles
|
uint8_t flags; // Contains default toggles
|
||||||
|
uint8_t homing_dir_mask;
|
||||||
float homing_feed_rate;
|
float homing_feed_rate;
|
||||||
float homing_seek_rate;
|
float homing_seek_rate;
|
||||||
uint16_t homing_debounce_delay;
|
uint16_t homing_debounce_delay;
|
||||||
|
float homing_pulloff;
|
||||||
uint8_t stepper_idle_lock_time;
|
uint8_t stepper_idle_lock_time;
|
||||||
uint8_t decimal_places;
|
uint8_t decimal_places;
|
||||||
} settings_t;
|
} settings_t;
|
||||||
|
@ -113,8 +113,8 @@ void st_go_idle()
|
|||||||
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
|
// Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete
|
||||||
// stop and not drift from residual inertial forces at the end of the last movement.
|
// stop and not drift from residual inertial forces at the end of the last movement.
|
||||||
delay_ms(settings.stepper_idle_lock_time);
|
delay_ms(settings.stepper_idle_lock_time);
|
||||||
// Disable steppers by setting stepper disable
|
// Disable steppers only upon system alarm activated or by user setting to keep enabled.
|
||||||
if (settings.stepper_idle_lock_time != 0xff) {
|
if ((settings.stepper_idle_lock_time != 0xff) || bit_istrue(sys.execute,EXEC_ALARM)) {
|
||||||
STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
|
STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user