Improved homing cycle. New settings: homing enable/rates, debounce and step idle lock time.

- Homing cycle will now cycle twice (spec more/less in config) to
improve repeatability and accuracy by decreasing overshoot.

- New Grbl settings added: Enable/disable homing cycles, homing seek
and feed rates, switch debounce delay, and stepper idle lock time.

- Please note that these settings may change upon the next push, since
there will be more added soon. Grbl *should* not re-write your old
settings, just re-write the new ones. So, make sure you keep these
written down somewhere in case they get lost from a code bug.

- Refactored settings migration to be a little smaller and managable
going forward.
This commit is contained in:
Sonny Jeon 2012-10-09 22:01:10 -06:00
parent 6506b7a338
commit 4c6f5bec48
8 changed files with 146 additions and 64 deletions

View File

@ -84,15 +84,6 @@
// This parameter must be one or greater, currently supporting up to a value of 6. // This parameter must be one or greater, currently supporting up to a value of 6.
#define N_COORDINATE_SYSTEM 1 #define N_COORDINATE_SYSTEM 1
// 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
// CNC axes don't cause the axes to drift off position. This is particularly important when manually
// entering g-code into grbl, i.e. locating part zero or simple manual machining. If the axes drift,
// grbl has no way to know this has happened, since stepper motors are open-loop control. Depending
// on the machine, this parameter may need to be larger or smaller than the default time.
// NOTE: If the define commented, the stepper lock will be disabled upon compiling.
#define STEPPER_IDLE_LOCK_TIME 25 // (milliseconds) - Integer > 0
// The temporal resolution of the acceleration management subsystem. Higher number give smoother // The temporal resolution of the acceleration management subsystem. Higher number give smoother
// acceleration but may impact performance. // acceleration but may impact performance.
// NOTE: Increasing this parameter will help any resolution related issues, especially with machines // NOTE: Increasing this parameter will help any resolution related issues, especially with machines
@ -102,7 +93,7 @@
// round-off can be great enough to cause problems and/or it's too fast for the Arduino. The correct // round-off can be great enough to cause problems and/or it's too fast for the Arduino. The correct
// value for this parameter is machine dependent, so it's advised to set this only as high as needed. // value for this parameter is machine dependent, so it's advised to set this only as high as needed.
// Approximate successful values can range from 30L to 100L or more. // Approximate successful values can range from 30L to 100L or more.
#define ACCELERATION_TICKS_PER_SECOND 50L #define ACCELERATION_TICKS_PER_SECOND 60L
// Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end // Minimum planner junction speed. Sets the default minimum speed the planner plans for at the end
// of the buffer and all stops. This should not be much greater than zero and should only be changed // of the buffer and all stops. This should not be much greater than zero and should only be changed
@ -129,6 +120,11 @@
// time step. Also, keep in mind that the Arduino delay timer is not very accurate for long delays. // time step. Also, keep in mind that the Arduino delay timer is not very accurate for long delays.
#define DWELL_TIME_STEP 50 // Integer (1-255) (milliseconds) #define DWELL_TIME_STEP 50 // Integer (1-255) (milliseconds)
// Number of homing cycles performed after when the machine initially jogs to limit switches.
// This help in preventing overshoot and should improve repeatability. This value should be one or
// greater.
#define N_HOMING_CYCLE 2 // Integer (1-128)
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// FOR ADVANCED USERS ONLY: // FOR ADVANCED USERS ONLY:
@ -174,7 +170,14 @@
#define DECIMAL_MULTIPLIER 100 #define DECIMAL_MULTIPLIER 100
#endif #endif
// Limit step rate for homing // This parameter sets the delay time before disabling the steppers after the final block of movement.
#define LIMIT_DEBOUNCE 50 // Limit switch debounce delay (in ms) // A short delay ensures the steppers come to a complete stop and the residual inertial force in the
// CNC axes don't cause the axes to drift off position. This is particularly important when manually
// entering g-code into grbl, i.e. locating part zero or simple manual machining. If the axes drift,
// grbl has no way to know this has happened, since stepper motors are open-loop control. Depending
// on the machine, this parameter may need to be larger or smaller than the default time.
// NOTE: If the define commented, the stepper lock will be disabled upon compiling.
// -> NOW INSTALLED IN SETTINGS #define STEPPER_IDLE_LOCK_TIME 25 // (milliseconds) - Integer > 0
#endif #endif

View File

@ -179,7 +179,13 @@ uint8_t gc_execute_line(char *line)
case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break; case 19: select_plane(Y_AXIS, Z_AXIS, X_AXIS); break;
case 20: gc.inches_mode = true; break; case 20: gc.inches_mode = true; break;
case 21: gc.inches_mode = false; break; case 21: gc.inches_mode = false; break;
case 28: case 30: non_modal_action = NON_MODAL_GO_HOME; break; case 28: case 30:
if (bit_istrue(settings.flags,FLAG_BIT_HOMING_ENABLE)) {
non_modal_action = NON_MODAL_GO_HOME;
} else {
FAIL(STATUS_SETTING_DISABLED);
}
break;
case 53: absolute_override = true; break; case 53: absolute_override = true; break;
case 54: case 55: case 56: case 57: case 58: case 59: case 54: case 55: case 56: case 57: case 58: case 59:
int_value -= 54; // Compute coordinate system row index (0=G54,1=G55,...) int_value -= 54; // Compute coordinate system row index (0=G54,1=G55,...)

View File

@ -156,26 +156,28 @@ static void homing_cycle(bool x_axis, bool y_axis, bool z_axis, int8_t pos_dir,
} }
} }
static void approach_limit_switch(bool x, bool y, bool z)
{
homing_cycle(x, y, z, true, false, settings.default_seek_rate);
}
static void leave_limit_switch(bool x, bool y, bool z) {
homing_cycle(x, y, z, false, true, settings.default_feed_rate);
}
void limits_go_home() void limits_go_home()
{ {
plan_synchronize(); // Empty all motions in buffer. plan_synchronize(); // Empty all motions in buffer.
// Jog all axes toward home to engage their limit switches. // Jog all axes toward home to engage their limit switches at faster homing seek rate.
approach_limit_switch(false, false, true); // First home the z axis homing_cycle(false, false, true, true, false, settings.homing_seek_rate); // First jog the z axis
approach_limit_switch(true, true, false); // Then home the x and y axis homing_cycle(true, true, false, true, false, settings.homing_seek_rate); // Then jog the x and y axis
delay_ms(LIMIT_DEBOUNCE); // Delay to debounce signal before leaving limit switches delay_ms(settings.homing_debounce_delay); // Delay to debounce signal
// Now carefully leave the limit switches // Now in proximity of all limits. Carefully leave and approach switches in multiple cycles
leave_limit_switch(true,true,true); // to precisely hone in on the machine zero location. Moves at slower homing feed rate.
delay_ms(LIMIT_DEBOUNCE); // Delay to debounce signal before exiting routine int8_t n_cycle = N_HOMING_CYCLE;
while (n_cycle--) {
// Leave all switches to release them. After cycles complete, this is machine zero.
homing_cycle(true, true, true, false, true, settings.homing_feed_rate);
delay_ms(settings.homing_debounce_delay);
if (n_cycle > 0) {
// Re-approach all switches to re-engage them.
homing_cycle(true, true, true, true, false, settings.homing_feed_rate);
delay_ms(settings.homing_debounce_delay);
}
}
} }

View File

@ -57,6 +57,8 @@ static void status_message(int status_code)
printPgmString(PSTR("Modal group violation\r\n")); break; printPgmString(PSTR("Modal group violation\r\n")); break;
case STATUS_INVALID_COMMAND: case STATUS_INVALID_COMMAND:
printPgmString(PSTR("Invalid command\r\n")); break; printPgmString(PSTR("Invalid command\r\n")); break;
case STATUS_SETTING_DISABLED:
printPgmString(PSTR("Grbl setting disabled\r\n")); break;
default: default:
printInteger(status_code); printInteger(status_code);
printPgmString(PSTR("\r\n")); printPgmString(PSTR("\r\n"));

View File

@ -28,6 +28,7 @@
#define STATUS_FLOATING_POINT_ERROR 4 #define STATUS_FLOATING_POINT_ERROR 4
#define STATUS_MODAL_GROUP_VIOLATION 5 #define STATUS_MODAL_GROUP_VIOLATION 5
#define STATUS_INVALID_COMMAND 6 #define STATUS_INVALID_COMMAND 6
#define STATUS_SETTING_DISABLED 7
// Initialize the serial protocol // Initialize the serial protocol
void protocol_init(); void protocol_init();

View File

@ -3,7 +3,7 @@
Part of Grbl Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Sungeun K. Jeon Copyright (c) 2011-2012 Sungeun K. Jeon
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -42,6 +42,19 @@ typedef struct {
float mm_per_arc_segment; float mm_per_arc_segment;
} settings_v1_t; } settings_v1_t;
// Version 2,3,4 outdated settings record
typedef struct {
float steps_per_mm[3];
uint8_t microsteps;
uint8_t pulse_microseconds;
float default_feed_rate;
float default_seek_rate;
uint8_t invert_mask;
float mm_per_arc_segment;
float acceleration;
float junction_deviation;
} settings_v2_v4_t;
// Default settings (used when resetting eeprom-settings) // Default settings (used when resetting eeprom-settings)
#define MICROSTEPS 8 #define MICROSTEPS 8
#define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS) #define DEFAULT_X_STEPS_PER_MM (94.488188976378*MICROSTEPS)
@ -54,7 +67,15 @@ typedef struct {
#define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2 #define DEFAULT_ACCELERATION (DEFAULT_FEEDRATE*60*60/10.0) // mm/min^2
#define DEFAULT_JUNCTION_DEVIATION 0.05 // mm #define DEFAULT_JUNCTION_DEVIATION 0.05 // mm
#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))
// #define DEFAULT_AUTO_START 1 // Boolean
// Developmental default settings
#define DEFAULT_HOMING_ENABLE 0 // false
#define DEFAULT_HOMING_RAPID_FEEDRATE 250.0 // mm/min
#define DEFAULT_HOMING_FEEDRATE 50 // mm/min
#define DEFAULT_HOMING_DEBOUNCE_DELAY 100 // msec (0-65k)
#define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255)
// #define DEFAULT_AUTO_START 1 // true
// #define DEFAULT_BLOCK_DELETE 0 // false
void settings_reset() { void settings_reset() {
settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM; settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM;
@ -81,8 +102,12 @@ void settings_dump() {
printPgmString(PSTR(" (step port invert mask. binary = ")); print_uint8_base2(settings.invert_mask); printPgmString(PSTR(" (step port invert mask. 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 in mm/sec^2)\r\n$9 = ")); printFloat(settings.junction_deviation);
printPgmString(PSTR(" (cornering junction deviation in mm)"));//\r\n$10 = ")); // printInteger(settings.auto_start); printPgmString(PSTR(" (cornering junction deviation in mm)\r\n$10 = ")); printInteger(bit_istrue(settings.flags,FLAG_BIT_HOMING_ENABLE));
// printPgmString(PSTR(" (auto-start boolean)")); printPgmString(PSTR(" (boolean homing enable)\r\n$11 = ")); printFloat(settings.homing_feed_rate);
printPgmString(PSTR(" (mm/min homing feed rate)\r\n$12 = ")); printFloat(settings.homing_seek_rate);
printPgmString(PSTR(" (mm/min homing seek rate)\r\n$13 = ")); printInteger(settings.homing_debounce_delay);
printPgmString(PSTR(" (milliseconds homing debounce delay)\r\n$14 = ")); printInteger(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (milliseconds stepper idle lock time)\r\n"));
printPgmString(PSTR("\r\n'$x=value' to set parameter or just '$' to dump current settings\r\n")); printPgmString(PSTR("\r\n'$x=value' to set parameter or just '$' to dump current settings\r\n"));
} }
@ -126,33 +151,60 @@ int read_settings() {
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t)))) { if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t)))) {
return(false); return(false);
} }
} else if (version == 1) {
// Migrate from settings version 1
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v1_t)))) {
return(false);
}
settings.acceleration = DEFAULT_ACCELERATION;
settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;
// settings.auto_start = DEFAULT_AUTO_START;
write_settings();
} else if ((version == 2) || (version == 3)) {
// Migrate from settings version 2 and 3
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t)))) {
return(false);
}
if (version == 2) { settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION; }
settings.acceleration *= 3600; // Convert to mm/min^2 from mm/sec^2
// settings.auto_start = DEFAULT_AUTO_START;
write_settings();
// } else if (version == 4) {
// // Migrate from settings version 4
// if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t)))) {
// return(false);
// }
// settings.auto_start = DEFAULT_AUTO_START;
// write_settings();
} else { } else {
return(false); // Incrementally update the old versions until up-to-date.
if (version == 1) {
// Migrate from settings version 1 to version 4.
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v1_t)))) {
return(false);
}
settings.acceleration = DEFAULT_ACCELERATION;
settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION;
} else if ((version == 2) || (version == 3)) {
// Migrate from settings version 2 and 3 to version 4.
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v2_v4_t)))) {
return(false);
}
if (version == 2) { settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION; }
settings.acceleration *= 3600; // Convert to mm/min^2 from mm/sec^2
}
if (version <= 4) {
// Migrate from settings version 4 to current version.
if (!(memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_v2_v4_t)))) {
return(false);
}
settings.flags = 0;
// if (DEFAULT_AUTO_START) { settings.flags |= FLAG_BIT_AUTO_START; }
if (DEFAULT_HOMING_ENABLE) { settings.flags |= FLAG_BIT_HOMING_ENABLE; }
settings.homing_feed_rate = DEFAULT_HOMING_FEEDRATE;
settings.homing_seek_rate = DEFAULT_HOMING_RAPID_FEEDRATE;
settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
write_settings();
} else if (version >= 50) {
// Developmental settings. Version numbers greater than or equal to 50 are temporary.
// Currently, this will update the user settings to v4 and the remainder of the settings
// should be re-written to the default value, if the developmental version number changed.
// Grab settings regardless of error.
memcpy_from_eeprom_with_checksum((char*)&settings, 1, sizeof(settings_t));
settings.flags = 0;
// if (DEFAULT_AUTO_START) { settings.flags |= FLAG_BIT_AUTO_START; }
if (DEFAULT_HOMING_ENABLE) { settings.flags |= FLAG_BIT_HOMING_ENABLE; }
settings.homing_feed_rate = DEFAULT_HOMING_FEEDRATE;
settings.homing_seek_rate = DEFAULT_HOMING_RAPID_FEEDRATE;
settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY;
settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME;
write_settings();
} else {
return(false);
}
} }
return(true); return(true);
} }
@ -178,7 +230,16 @@ void settings_store_setting(int parameter, float value) {
case 7: settings.invert_mask = trunc(value); break; case 7: settings.invert_mask = trunc(value); break;
case 8: settings.acceleration = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 8: settings.acceleration = value*60*60; break; // Convert to mm/min^2 for grbl internal use.
case 9: settings.junction_deviation = fabs(value); break; case 9: settings.junction_deviation = fabs(value); break;
// case 10: settings.auto_start = value; break; case 10:
if (value) {
settings.flags |= FLAG_BIT_HOMING_ENABLE;
printPgmString(PSTR("Install all axes limit switches before use\r\n"));
} else { settings.flags &= ~FLAG_BIT_HOMING_ENABLE; }
break;
case 11: settings.homing_feed_rate = value; break;
case 12: settings.homing_seek_rate = value; break;
case 13: settings.homing_debounce_delay = round(value); break;
case 14: settings.stepper_idle_lock_time = round(value); break;
default: default:
printPgmString(PSTR("Unknown parameter\r\n")); printPgmString(PSTR("Unknown parameter\r\n"));
return; return;

View File

@ -3,7 +3,7 @@
Part of Grbl Part of Grbl
Copyright (c) 2009-2011 Simen Svale Skogsrud Copyright (c) 2009-2011 Simen Svale Skogsrud
Copyright (c) 2011 Sungeun K. Jeon Copyright (c) 2011-2012 Sungeun K. Jeon
Grbl is free software: you can redistribute it and/or modify Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -29,7 +29,11 @@
// 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 4 #define SETTINGS_VERSION 50
// Define bit flag masks in settings.flag.
#define FLAG_BIT_HOMING_ENABLE bit(0)
//#define FLAG_BIT_AUTO_START bit(1)
// Current global settings (persisted in EEPROM from byte 1 onwards) // Current global settings (persisted in EEPROM from byte 1 onwards)
typedef struct { typedef struct {
@ -42,6 +46,11 @@ typedef struct {
float mm_per_arc_segment; float mm_per_arc_segment;
float acceleration; float acceleration;
float junction_deviation; float junction_deviation;
uint8_t flags; // Contains default toggles
float homing_feed_rate;
float homing_seek_rate;
uint16_t homing_debounce_delay;
uint8_t stepper_idle_lock_time;
} settings_t; } settings_t;
extern settings_t settings; extern settings_t settings;

View File

@ -112,9 +112,7 @@ void st_go_idle()
TIMSK1 &= ~(1<<OCIE1A); TIMSK1 &= ~(1<<OCIE1A);
// 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.
#ifdef STEPPER_IDLE_LOCK_TIME delay_ms(settings.stepper_idle_lock_time);
_delay_ms(STEPPER_IDLE_LOCK_TIME);
#endif
// Disable steppers by setting stepper disable // Disable steppers by setting stepper disable
STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT); STEPPERS_DISABLE_PORT |= (1<<STEPPERS_DISABLE_BIT);
} }