From 4f68edbba2312c9a4b8f9fe28ef508dd50f3f35b Mon Sep 17 00:00:00 2001 From: ashelly Date: Mon, 8 Sep 2014 22:10:59 -0400 Subject: [PATCH 01/74] Alarm if limits engaged on homing --- motion_control.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/motion_control.c b/motion_control.c index 66633d156..3b0b171ac 100644 --- a/motion_control.c +++ b/motion_control.c @@ -240,6 +240,18 @@ void mc_dwell(float seconds) // executing the homing cycle. This prevents incorrect buffered plans after homing. void mc_homing_cycle() { + uint8_t limits_on; + if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { + limits_on = (LIMIT_PIN ^ LIMIT_MASK); + } else { + limits_on = (LIMIT_PIN & LIMIT_MASK); + } + if (limits_on) { + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. + bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event + return; + } + sys.state = STATE_HOMING; // Set system state variable limits_disable(); // Disable hard limits pin change register for cycle duration From f78eebcebf00319ac2901a6b54430e78d800e837 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 14:43:10 -0700 Subject: [PATCH 02/74] add MOTION_MODE_PROBE_NO_ERROR --- gcode.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcode.h b/gcode.h index 8a29aab1c..fc28d3216 100644 --- a/gcode.h +++ b/gcode.h @@ -71,8 +71,9 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2 -#define MOTION_MODE_NONE 5 // G80 +#define MOTION_MODE_PROBE 4 // G38.2, G38.4 +#define MOTION_MODE_PROBE_NO_ERROR 5 // G38.3, G38.5 +#define MOTION_MODE_NONE 6 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) From 0f7806938d0325da15faffc7c23fe1e5ed8d0319 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 15:36:25 -0700 Subject: [PATCH 03/74] install G38.{3,4,5} --- gcode.c | 22 +++++++++++++++++----- motion_control.c | 2 +- probe.c | 6 ++++-- system.h | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/gcode.c b/gcode.c index 1977d8344..f1f4e978a 100644 --- a/gcode.c +++ b/gcode.c @@ -210,11 +210,23 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: gc_block.modal.motion = MOTION_MODE_PROBE; break; // G38.2 - // NOTE: If G38.3+ are enabled, change mantissa variable type to uint16_t. - // case 30: gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; break; // G38.3 Not supported. - // case 40: // Not supported. - // case 50: // Not supported. + case 20: + sys.probe_away = false; + gc_block.modal.motion = MOTION_MODE_PROBE; + break; // G38.2 + case 30: + sys.probe_away = false; + gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; + break; // G38.3 + case 40: + sys.probe_away = true; + gc_block.modal.motion = MOTION_MODE_PROBE; + break; // G38.4 + case 50: + sys.probe_away = true; + gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; + break; // G38.5 + default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } mantissa = 0; // Set to zero to indicate valid non-integer G command. diff --git a/motion_control.c b/motion_control.c index 66633d156..01fa0f29f 100644 --- a/motion_control.c +++ b/motion_control.c @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state()) { + if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } diff --git a/probe.c b/probe.c index 00dde4766..581f9f1d2 100644 --- a/probe.c +++ b/probe.c @@ -37,6 +37,8 @@ void probe_init() PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. probe_invert_mask = PROBE_MASK; } + + sys.probe_away = false; } @@ -49,8 +51,8 @@ uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask) // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state == PROBE_ACTIVE) { - if (probe_get_state()) { + if (sys.probe_state == PROBE_ACTIVE) { + if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { sys.probe_state = PROBE_OFF; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); diff --git a/system.h b/system.h index 93ab2b96a..ddd7625b6 100644 --- a/system.h +++ b/system.h @@ -79,6 +79,7 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + uint8_t probe_away; // probe away from work by reversing the switch direction (G38.4, G38.5) } system_t; extern system_t sys; From b89d194466e7f69d7d184a5f8c0df794b8b41682 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Sun, 14 Sep 2014 15:42:31 -0700 Subject: [PATCH 04/74] utilize MOTION_MODE_PROBE_NO_ERROR --- gcode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gcode.c b/gcode.c index f1f4e978a..27ed4e4cc 100644 --- a/gcode.c +++ b/gcode.c @@ -982,6 +982,7 @@ uint8_t gc_execute_line(char *line) #endif break; case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_NO_ERROR: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS From fd0db24199738a0a0dfac9ddf03acee521f18896 Mon Sep 17 00:00:00 2001 From: Markus Schulz Date: Wed, 17 Sep 2014 18:56:25 -0400 Subject: [PATCH 05/74] If variable spindle is defined print S value via $G command. --- report.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/report.c b/report.c index 32720ebfb..92033b310 100644 --- a/report.c +++ b/report.c @@ -330,6 +330,11 @@ void report_gcode_modes() printPgmString(PSTR(" F")); printFloat_RateValue(gc_state.feed_rate); + + #ifdef VARIABLE_SPINDLE + printPgmString(PSTR(" S")); + printFloat_RateValue(gc_state.spindle_speed); + #endif printPgmString(PSTR("]\r\n")); } From 5b97a79b6d74fa99fe32246f20ce5f275e1279c4 Mon Sep 17 00:00:00 2001 From: ashelly Date: Wed, 17 Sep 2014 23:41:52 -0400 Subject: [PATCH 06/74] No false alarm if other bits in port are set. --- motion_control.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/motion_control.c b/motion_control.c index 3b0b171ac..2208a9302 100644 --- a/motion_control.c +++ b/motion_control.c @@ -242,7 +242,7 @@ void mc_homing_cycle() { uint8_t limits_on; if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { - limits_on = (LIMIT_PIN ^ LIMIT_MASK); + limits_on = ((~LIMIT_PIN) & LIMIT_MASK); } else { limits_on = (LIMIT_PIN & LIMIT_MASK); } From 322feba52feedd4600f4cde72ef10ea5aa235738 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 20 Sep 2014 08:50:27 -0600 Subject: [PATCH 07/74] Minor settings number overflow bug fix. - The `x` in `$x=val` would overflow when a value larger than 255 was entered and passed to Grbl. This resulted with unintended parameters being set by the overflow value. To fix, simply check for values larger than 255 and error out. --- system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system.c b/system.c index 9079820cf..b8e2f6bed 100644 --- a/system.c +++ b/system.c @@ -190,7 +190,7 @@ uint8_t system_execute_line(char *line) } } else { // Store global setting. if(!read_float(line, &char_counter, &value)) { return(STATUS_BAD_NUMBER_FORMAT); } - if(line[char_counter] != 0) { return(STATUS_INVALID_STATEMENT); } + if((line[char_counter] != 0) || (parameter > 255)) { return(STATUS_INVALID_STATEMENT); } return(settings_store_global_setting((uint8_t)parameter, value)); } } From 39cf82294439c7e7b1599b9f919d27290ed7a5cc Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 20 Sep 2014 10:41:31 -0600 Subject: [PATCH 08/74] Edit hard limit check at start of homing cycle --- gcode.h | 1 + limits.c | 1 + motion_control.c | 13 ++++++------- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/gcode.h b/gcode.h index 8a29aab1c..81ae4d947 100644 --- a/gcode.h +++ b/gcode.h @@ -164,6 +164,7 @@ typedef struct { float spindle_speed; // RPM float feed_rate; // Millimeters/min uint8_t tool; // Tracks tool number. NOT USED. +// int32_t line_number; // Last line number sent float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code diff --git a/limits.c b/limits.c index 12cc248a1..4538dcb3f 100644 --- a/limits.c +++ b/limits.c @@ -122,6 +122,7 @@ void limits_disable() // mask, which prevents the stepper algorithm from executing step pulses. Homing motions typically // circumvent the processes for executing motions in normal operation. // NOTE: Only the abort runtime command can interrupt this process. +// TODO: Move limit pin-specific calls to a general function for portability. void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. diff --git a/motion_control.c b/motion_control.c index 2208a9302..66e9701e9 100644 --- a/motion_control.c +++ b/motion_control.c @@ -240,13 +240,12 @@ void mc_dwell(float seconds) // executing the homing cycle. This prevents incorrect buffered plans after homing. void mc_homing_cycle() { - uint8_t limits_on; - if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { - limits_on = ((~LIMIT_PIN) & LIMIT_MASK); - } else { - limits_on = (LIMIT_PIN & LIMIT_MASK); - } - if (limits_on) { + // Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems + // with machines with limits wired on both ends of travel to one limit pin. + // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function. + uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } + if (limit_state) { mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event return; From 5406fa939a1fd669fd58b5509e7a9a46ee975d47 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 13:29:02 -0700 Subject: [PATCH 09/74] cleanup global var and push probe mode into probe_get_state --- gcode.c | 34 ++++++++++++++++------------------ gcode.h | 5 ++--- motion_control.c | 9 +++++---- motion_control.h | 4 ++-- probe.c | 12 ++++++------ probe.h | 8 +++++++- system.h | 1 - 7 files changed, 38 insertions(+), 35 deletions(-) diff --git a/gcode.c b/gcode.c index 27ed4e4cc..9d0f81dd3 100644 --- a/gcode.c +++ b/gcode.c @@ -124,7 +124,7 @@ uint8_t gc_execute_line(char *line) float value; uint8_t int_value = 0; uint8_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. - + uint8_t probe_mode = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. @@ -210,22 +210,21 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: - sys.probe_away = false; + case 20: // G38.2 + gc_block.modal.motion = MOTION_MODE_PROBE; + break; + case 30: // G38.3 + gc_block.modal.motion = MOTION_MODE_PROBE; + probe_mode = PROBE_NO_ERROR; + break; + case 40: // G38.4 gc_block.modal.motion = MOTION_MODE_PROBE; - break; // G38.2 - case 30: - sys.probe_away = false; - gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; - break; // G38.3 - case 40: - sys.probe_away = true; + probe_mode = PROBE_AWAY; + break; + case 50: // G38.5 gc_block.modal.motion = MOTION_MODE_PROBE; - break; // G38.4 - case 50: - sys.probe_away = true; - gc_block.modal.motion = MOTION_MODE_PROBE_NO_ERROR; - break; // G38.5 + probe_mode = PROBE_AWAY | PROBE_NO_ERROR; + break; default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } @@ -982,13 +981,12 @@ uint8_t gc_execute_line(char *line) #endif break; case MOTION_MODE_PROBE: - case MOTION_MODE_PROBE_NO_ERROR: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_block.values.n); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode, gc_block.values.n); #else - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode); #endif } diff --git a/gcode.h b/gcode.h index fc28d3216..98efe23dd 100644 --- a/gcode.h +++ b/gcode.h @@ -71,9 +71,8 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2, G38.4 -#define MOTION_MODE_PROBE_NO_ERROR 5 // G38.3, G38.5 -#define MOTION_MODE_NONE 6 // G80 +#define MOTION_MODE_PROBE 4 // G38.2, G38.3, G38.4, G38.5 +#define MOTION_MODE_NONE 5 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) diff --git a/motion_control.c b/motion_control.c index 01fa0f29f..b06926791 100644 --- a/motion_control.c +++ b/motion_control.c @@ -276,9 +276,9 @@ void mc_homing_cycle() // Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. #ifdef USE_LINE_NUMBERS - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode, int32_t line_number) #else - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { + if (probe_get_state(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -303,7 +303,7 @@ void mc_homing_cycle() #endif // Activate the probing monitor in the stepper module. - sys.probe_state = PROBE_ACTIVE; + sys.probe_state = PROBE_ACTIVE | mode; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); @@ -314,6 +314,7 @@ void mc_homing_cycle() // Probing motion complete. If the probe has not been triggered, error out. if (sys.probe_state == PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort diff --git a/motion_control.h b/motion_control.h index 5a1d8c91a..54aa1e576 100644 --- a/motion_control.h +++ b/motion_control.h @@ -58,9 +58,9 @@ void mc_homing_cycle(); // Perform tool length probe cycle. Requires probe switch. #ifdef USE_LINE_NUMBERS -void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, int32_t line_number); +void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t motion, int32_t line_number); #else -void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate); +void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t motion); #endif // Performs system reset. If in motion state, kills all motion and sets system alarm. diff --git a/probe.c b/probe.c index 581f9f1d2..5a6593975 100644 --- a/probe.c +++ b/probe.c @@ -37,22 +37,22 @@ void probe_init() PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. probe_invert_mask = PROBE_MASK; } - - sys.probe_away = false; } // Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor. -uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } - +uint8_t probe_get_state(uint8_t mode) { + mode = ((mode >> PROBE_AWAY_BIT) & 1) << PROBE_BIT; + return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); +} // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state == PROBE_ACTIVE) { - if ((sys.probe_away << PROBE_BIT) ^ probe_get_state()) { + if (sys.probe_state != PROBE_OFF) { + if (probe_get_state(sys.probe_state)) { sys.probe_state = PROBE_OFF; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); diff --git a/probe.h b/probe.h index 81fb55bf2..5986d8656 100644 --- a/probe.h +++ b/probe.h @@ -25,12 +25,18 @@ #define PROBE_OFF 0 // No probing. (Must be zero.) #define PROBE_ACTIVE 1 // Actively watching the input pin. +// Probe direction and error modes +#define PROBE_AWAY 2 // G38.4, G38.5 +#define PROBE_NO_ERROR 4 // G38.3, G38.5 + +#define PROBE_AWAY_BIT 1 +#define PROBE_NO_ERROR_BIT 2 // Probe pin initialization routine. void probe_init(); // Returns probe pin state. -uint8_t probe_get_state(); +uint8_t probe_get_state(uint8_t mode); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/system.h b/system.h index ddd7625b6..93ab2b96a 100644 --- a/system.h +++ b/system.h @@ -79,7 +79,6 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. - uint8_t probe_away; // probe away from work by reversing the switch direction (G38.4, G38.5) } system_t; extern system_t sys; From 5c07acd9fae3f231f59a363cd721f3b41c6bc34e Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 13:39:51 -0700 Subject: [PATCH 10/74] test only for & PROBE_ACTIVE --- motion_control.c | 1 - 1 file changed, 1 deletion(-) diff --git a/motion_control.c b/motion_control.c index b06926791..b74bb7c90 100644 --- a/motion_control.c +++ b/motion_control.c @@ -313,7 +313,6 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state == PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort From b920838109c89941776dd266d8a6e804a8634ea2 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:05:35 -0700 Subject: [PATCH 11/74] bump mantissa to uint16_t to enable G38.5 --- gcode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcode.c b/gcode.c index 9d0f81dd3..4afa02701 100644 --- a/gcode.c +++ b/gcode.c @@ -123,7 +123,7 @@ uint8_t gc_execute_line(char *line) char letter; float value; uint8_t int_value = 0; - uint8_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. + uint16_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. uint8_t probe_mode = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. From 3392a8b2c89ce28967af52ee365d38c97ef925c3 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:12:25 -0700 Subject: [PATCH 12/74] add/install probe_errors_enabled in mc_probe_cycle --- motion_control.c | 6 ++++-- probe.c | 4 ++++ probe.h | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/motion_control.c b/motion_control.c index b74bb7c90..66cb9acff 100644 --- a/motion_control.c +++ b/motion_control.c @@ -289,7 +289,7 @@ void mc_homing_cycle() uint8_t auto_start_state = sys.auto_start; // Store run state // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state(mode)) { + if (probe_get_state(mode) && probe_errors_enabled(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -313,7 +313,9 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + if (sys.probe_state & PROBE_ACTIVE && probe_errors_enabled(mode)) { + bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort diff --git a/probe.c b/probe.c index 5a6593975..7d45fe608 100644 --- a/probe.c +++ b/probe.c @@ -46,6 +46,10 @@ uint8_t probe_get_state(uint8_t mode) { return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } +uint8_t probe_errors_enabled(uint8_t mode) { + return !(mode & PROBE_NO_ERROR); +} + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. diff --git a/probe.h b/probe.h index 5986d8656..5a2006d65 100644 --- a/probe.h +++ b/probe.h @@ -38,6 +38,8 @@ void probe_init(); // Returns probe pin state. uint8_t probe_get_state(uint8_t mode); +uint8_t probe_errors_enabled(uint8_t mode); + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. void probe_state_monitor(); From 5f1eece67deeb06dc6cdbb969af575edda054066 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 14:35:12 -0700 Subject: [PATCH 13/74] hop over probe pull-off sequence after probe miss and while "no errors" is enabled (G38.3, G38.5) --- motion_control.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/motion_control.c b/motion_control.c index 66cb9acff..f4b66cb56 100644 --- a/motion_control.c +++ b/motion_control.c @@ -287,7 +287,8 @@ void mc_homing_cycle() // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); uint8_t auto_start_state = sys.auto_start; // Store run state - + uint8_t perform_pull_off = 1; + // After syncing, check if probe is already triggered. If so, halt and issue alarm. if (probe_get_state(mode) && probe_errors_enabled(mode)) { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); @@ -313,8 +314,13 @@ void mc_homing_cycle() } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE && probe_errors_enabled(mode)) { - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + if (sys.probe_state & PROBE_ACTIVE) { + + if (probe_errors_enabled(mode)) { + bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); + } else { + perform_pull_off = 0; + } } protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort @@ -323,24 +329,26 @@ void mc_homing_cycle() st_reset(); // Reest step segment buffer. plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. - - // Pull-off triggered probe to the trigger location since we had to decelerate a little beyond - // it to stop the machine in a controlled manner. - uint8_t idx; - for(idx=0; idx Date: Mon, 22 Sep 2014 14:40:21 -0700 Subject: [PATCH 14/74] add probe_finalize to keep things DRY this allows the PRB report to be valid when in "no errors" mode and the probe fails --- motion_control.c | 1 + probe.c | 10 +++++++--- probe.h | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/motion_control.c b/motion_control.c index f4b66cb56..f6b703745 100644 --- a/motion_control.c +++ b/motion_control.c @@ -320,6 +320,7 @@ void mc_homing_cycle() bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } else { perform_pull_off = 0; + probe_finalize(); } } protocol_execute_runtime(); // Check and execute run-time commands diff --git a/probe.c b/probe.c index 7d45fe608..3623f7bdb 100644 --- a/probe.c +++ b/probe.c @@ -50,6 +50,12 @@ uint8_t probe_errors_enabled(uint8_t mode) { return !(mode & PROBE_NO_ERROR); } +void probe_finalize() { + sys.probe_state = PROBE_OFF; + memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); + bit_true(sys.execute, EXEC_FEED_HOLD); +} + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. @@ -57,9 +63,7 @@ void probe_state_monitor() { if (sys.probe_state != PROBE_OFF) { if (probe_get_state(sys.probe_state)) { - sys.probe_state = PROBE_OFF; - memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); - bit_true(sys.execute, EXEC_FEED_HOLD); + probe_finalize(); } } } diff --git a/probe.h b/probe.h index 5a2006d65..194e56eac 100644 --- a/probe.h +++ b/probe.h @@ -40,6 +40,8 @@ uint8_t probe_get_state(uint8_t mode); uint8_t probe_errors_enabled(uint8_t mode); +void probe_finalize(); + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. void probe_state_monitor(); From 297f4d1dd6a3e89b3715b904a8e0209799aaa510 Mon Sep 17 00:00:00 2001 From: Elijah Insua Date: Mon, 22 Sep 2014 20:32:47 -0700 Subject: [PATCH 15/74] report probe_succeeded with probe status --- motion_control.c | 2 +- probe.c | 5 +++-- probe.h | 2 +- report.c | 4 +++- system.h | 1 + 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/motion_control.c b/motion_control.c index f6b703745..79fd30d71 100644 --- a/motion_control.c +++ b/motion_control.c @@ -320,7 +320,7 @@ void mc_homing_cycle() bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } else { perform_pull_off = 0; - probe_finalize(); + probe_finalize(0); } } protocol_execute_runtime(); // Check and execute run-time commands diff --git a/probe.c b/probe.c index 3623f7bdb..12fcc635b 100644 --- a/probe.c +++ b/probe.c @@ -50,8 +50,9 @@ uint8_t probe_errors_enabled(uint8_t mode) { return !(mode & PROBE_NO_ERROR); } -void probe_finalize() { +void probe_finalize(uint8_t probe_succeeded) { sys.probe_state = PROBE_OFF; + sys.probe_succeeded = probe_succeeded; memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); bit_true(sys.execute, EXEC_FEED_HOLD); } @@ -63,7 +64,7 @@ void probe_state_monitor() { if (sys.probe_state != PROBE_OFF) { if (probe_get_state(sys.probe_state)) { - probe_finalize(); + probe_finalize(1); } } } diff --git a/probe.h b/probe.h index 194e56eac..17028eb74 100644 --- a/probe.h +++ b/probe.h @@ -40,7 +40,7 @@ uint8_t probe_get_state(uint8_t mode); uint8_t probe_errors_enabled(uint8_t mode); -void probe_finalize(); +void probe_finalize(uint8_t probe_succeeded); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/report.c b/report.c index 32720ebfb..ca93efebc 100644 --- a/report.c +++ b/report.c @@ -235,7 +235,9 @@ void report_probe_parameters() print_position[i] = sys.probe_position[i]/settings.steps_per_mm[i]; printFloat_CoordValue(print_position[i]); if (i < (N_AXIS-1)) { printPgmString(PSTR(",")); } - } + } + printPgmString(PSTR(":")); + print_uint8_base10(sys.probe_succeeded); printPgmString(PSTR("]\r\n")); } diff --git a/system.h b/system.h index 93ab2b96a..3263af842 100644 --- a/system.h +++ b/system.h @@ -79,6 +79,7 @@ typedef struct { uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. int32_t probe_position[N_AXIS]; // Last probe position in machine coordinates and steps. + uint8_t probe_succeeded; } system_t; extern system_t sys; From 7e67395463b7fedbd0ac2e03aef2e84875d8dcbc Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 1 Oct 2014 20:22:16 -0600 Subject: [PATCH 16/74] Updated variable spindle and new probing. Minor bug fixes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Minor bug fix for variable spindle PWM output. Values smaller than the minimum RPM for the spindle would overflow the PWM value. Thanks Rob! - Created an optional minimum spindle PWM low-mark value as a compile-time option. This is for special circumstances when the PWM has to be at a certain level to be read by the spindle controller. - Refactored the new probing commands (G38.3, G38.4, G38.5) code to work better with the rest of Grbl’s systems. - Refactored mc_probe() and mc_arc() to accept the mode of the command, i.e. clockwise vs counter, toward vs away, etc. This is to make these functions independent of gcode state variables. - Removed the pull off motion in the probing cycle. This is not an official operation and was added for user simplicity, but wrongly did so. So bye bye. - Created a configure probe invert mask function to handle the different probe pin setting and probing cycle modes with a single mask. - Minor bug fix with reporting motion modes via $G. G38.2 wasn’t showing up. It now does, along with the other new probing commands. - Refactored some of the new pin configurations for the future of Grbl. - --- config.h | 8 ++++- cpu_map.h | 10 +++--- gcode.c | 81 +++++++++++++++++++++++++++++------------------ gcode.h | 9 ++++-- motion_control.c | 69 ++++++++++++++++++---------------------- motion_control.h | 13 +++++--- probe.c | 39 +++++++++++------------ probe.h | 20 ++++-------- report.c | 16 +++++++--- spindle_control.c | 12 +++++-- system.h | 6 ++-- 11 files changed, 158 insertions(+), 125 deletions(-) diff --git a/config.h b/config.h index b3dcbbda0..378ad6a16 100644 --- a/config.h +++ b/config.h @@ -156,7 +156,7 @@ // The hardware PWM output on pin D11 is required for variable spindle output voltages. // #define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. -// Use by the variable spindle output only. These parameters set the maximum and minimum spindle speed +// Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and // equally divided voltage bins between the maximum and minimum spindle speeds. So for a 5V pin, 1000 // max rpm, and 250 min rpm, the spindle output voltage would be set for the following "S" commands: @@ -164,6 +164,12 @@ #define SPINDLE_MAX_RPM 1000.0 // Max spindle RPM. This value is equal to 100% duty cycle on the PWM. #define SPINDLE_MIN_RPM 0.0 // Min spindle RPM. This value is equal to (1/256) duty cycle on the PWM. +// Used by variable spindle output only. This forces the PWM output to a minimum duty cycle when enabled. +// When disabled, the PWM pin will still read 0V. Most users will not need this option, but it may be +// useful in certain scenarios. This setting does not update the minimum spindle RPM calculations. Any +// spindle RPM output lower than this value will be set to this value. +// #define MINIMUM_SPINDLE_PWM 5 // Default disabled. Uncomment to enable. Integer (0-255) + // Minimum planner junction speed. Sets the default minimum junction speed the planner plans to at // every buffer block junction, except for starting from rest and end of the buffer, which are always // zero. This value controls how fast the machine moves through junctions with no regard for acceleration diff --git a/cpu_map.h b/cpu_map.h index e918fb2b0..72955136c 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -206,11 +206,11 @@ // a later date if flash and memory space allows. #define COOLANT_FLOOD_DDR DDRC #define COOLANT_FLOOD_PORT PORTC - #define COOLANT_FLOOD_BIT 4 // Uno Analog Pin 3 + #define COOLANT_FLOOD_BIT 1 // Uno Analog Pin 1 #ifdef ENABLE_M7 // Mist coolant disabled by default. See config.h to enable/disable. #define COOLANT_MIST_DDR DDRC #define COOLANT_MIST_PORT PORTC - #define COOLANT_MIST_BIT 5 // Uno Analog Pin 4 + #define COOLANT_MIST_BIT 2 // Uno Analog Pin 2 #endif // Define user-control pinouts (cycle start, reset, feed hold) input pins. @@ -218,9 +218,9 @@ #define PINOUT_DDR DDRC #define PINOUT_PIN PINC #define PINOUT_PORT PORTC - #define PIN_RESET 1 // Uno Analog Pin 1 - #define PIN_FEED_HOLD 2 // Uno Analog Pin 2 - #define PIN_CYCLE_START 3 // Uno Analog Pin 3 + #define PIN_RESET 3 // Uno Analog Pin 3 + #define PIN_FEED_HOLD 4 // Uno Analog Pin 4 + #define PIN_CYCLE_START 5 // Uno Analog Pin 5 #define PINOUT_INT PCIE1 // Pin change interrupt enable pin #define PINOUT_INT_vect PCINT1_vect #define PINOUT_PCMSK PCMSK1 // Pin change interrupt register diff --git a/gcode.c b/gcode.c index 4afa02701..6c482cd65 100644 --- a/gcode.c +++ b/gcode.c @@ -123,8 +123,7 @@ uint8_t gc_execute_line(char *line) char letter; float value; uint8_t int_value = 0; - uint16_t mantissa = 0; // NOTE: For mantissa values > 255, variable type must be changed to uint16_t. - uint8_t probe_mode = 0; + uint16_t mantissa = 0; while (line[char_counter] != 0) { // Loop until no more g-code words in line. @@ -210,22 +209,10 @@ uint8_t gc_execute_line(char *line) case 3: gc_block.modal.motion = MOTION_MODE_CCW_ARC; break; // G3 case 38: switch(mantissa) { - case 20: // G38.2 - gc_block.modal.motion = MOTION_MODE_PROBE; - break; - case 30: // G38.3 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_NO_ERROR; - break; - case 40: // G38.4 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_AWAY; - break; - case 50: // G38.5 - gc_block.modal.motion = MOTION_MODE_PROBE; - probe_mode = PROBE_AWAY | PROBE_NO_ERROR; - break; - + case 20: gc_block.modal.motion = MOTION_MODE_PROBE_TOWARD; break; // G38.2 + case 30: gc_block.modal.motion = MOTION_MODE_PROBE_TOWARD_NO_ERROR; break; // G38.3 + case 40: gc_block.modal.motion = MOTION_MODE_PROBE_AWAY; break; // G38.4 + case 50: gc_block.modal.motion = MOTION_MODE_PROBE_AWAY_NO_ERROR; break; // G38.5 default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G38.x command] } mantissa = 0; // Set to zero to indicate valid non-integer G command. @@ -811,7 +798,8 @@ uint8_t gc_execute_line(char *line) } } break; - case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_TOWARD: case MOTION_MODE_PROBE_TOWARD_NO_ERROR: + case MOTION_MODE_PROBE_AWAY: case MOTION_MODE_PROBE_AWAY_NO_ERROR: // [G38 Errors]: Target is same current. No axis words. Cutter compensation is enabled. Feed rate // is undefined. Probe is triggered. NOTE: Probe check moved to probe cycle. Instead of returning // an error, it issues an alarm to prevent further motion to the probe. It's also done there to @@ -838,6 +826,9 @@ uint8_t gc_execute_line(char *line) need to update the state and execute the block according to the order-of-execution. */ + // [0. Non-specific/common error-checks and miscellaneous setup]: + gc_state.line_number = gc_block.values.n; + // [1. Comments feedback ]: NOT SUPPORTED // [2. Set feed rate mode ]: @@ -923,13 +914,13 @@ uint8_t gc_execute_line(char *line) // and absolute and incremental modes. if (axis_command) { #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, -1.0, false, gc_block.values.n); + mc_line(gc_block.values.xyz, -1.0, false, gc_state.line_number); #else mc_line(gc_block.values.xyz, -1.0, false); #endif } #ifdef USE_LINE_NUMBERS - mc_line(parameter_data, -1.0, false, gc_block.values.n); + mc_line(parameter_data, -1.0, false, gc_state.line_number); #else mc_line(parameter_data, -1.0, false); #endif @@ -959,41 +950,71 @@ uint8_t gc_execute_line(char *line) switch (gc_state.modal.motion) { case MOTION_MODE_SEEK: #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, -1.0, false, gc_block.values.n); + mc_line(gc_block.values.xyz, -1.0, false, gc_state.line_number); #else mc_line(gc_block.values.xyz, -1.0, false); #endif break; case MOTION_MODE_LINEAR: #ifdef USE_LINE_NUMBERS - mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_block.values.n); + mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, gc_state.line_number); #else mc_line(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate); #endif break; - case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: + case MOTION_MODE_CW_ARC: + #ifdef USE_LINE_NUMBERS + mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, true, gc_state.line_number); + #else + mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, true); + #endif + break; + case MOTION_MODE_CCW_ARC: #ifdef USE_LINE_NUMBERS mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, - gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, gc_block.values.n); + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, false, gc_state.line_number); #else mc_arc(gc_state.position, gc_block.values.xyz, gc_block.values.ijk, gc_block.values.r, - gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear); + gc_state.feed_rate, gc_state.modal.feed_rate, axis_0, axis_1, axis_linear, false); #endif break; - case MOTION_MODE_PROBE: + case MOTION_MODE_PROBE_TOWARD: // NOTE: gc_block.values.xyz is returned from mc_probe_cycle with the updated position value. So // upon a successful probing cycle, the machine position and the returned value should be the same. #ifdef USE_LINE_NUMBERS - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode, gc_block.values.n); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, false, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, false); + #endif + break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, true, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, false, true); + #endif + break; + case MOTION_MODE_PROBE_AWAY: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, false, gc_state.line_number); #else - mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, probe_mode); + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, false); + #endif + break; + case MOTION_MODE_PROBE_AWAY_NO_ERROR: + #ifdef USE_LINE_NUMBERS + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, true, gc_state.line_number); + #else + mc_probe_cycle(gc_block.values.xyz, gc_state.feed_rate, gc_state.modal.feed_rate, true, true); #endif } // As far as the parser is concerned, the position is now == target. In reality the // motion control system might still be processing the action and the real tool position // in any intermediate location. - memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc.position[] = target[]; + memcpy(gc_state.position, gc_block.values.xyz, sizeof(gc_block.values.xyz)); // gc_state.position[] = gc_block.values.xyz[] } } diff --git a/gcode.h b/gcode.h index 0e196a958..88a538452 100644 --- a/gcode.h +++ b/gcode.h @@ -71,8 +71,11 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE 4 // G38.2, G38.3, G38.4, G38.5 -#define MOTION_MODE_NONE 5 // G80 +#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 +#define MOTION_MODE_PROBE_TOWARD_NO_ERROR 5 // G38.3 +#define MOTION_MODE_PROBE_AWAY 6 // G38.4 +#define MOTION_MODE_PROBE_AWAY_NO_ERROR 7 // G38.5 +#define MOTION_MODE_NONE 8 // G80 // Modal Group G2: Plane select #define PLANE_SELECT_XY 0 // G17 (Default: Must be zero) @@ -164,7 +167,7 @@ typedef struct { float spindle_speed; // RPM float feed_rate; // Millimeters/min uint8_t tool; // Tracks tool number. NOT USED. -// int32_t line_number; // Last line number sent + int32_t line_number; // Last line number sent float position[N_AXIS]; // Where the interpreter considers the tool to be at this point in the code diff --git a/motion_control.c b/motion_control.c index ed62d337e..dbefe892f 100644 --- a/motion_control.c +++ b/motion_control.c @@ -95,7 +95,7 @@ // Execute an arc in offset mode format. position == current xyz, target == target xyz, -// offset == offset from current xyz, axis_XXX defines circle plane in tool space, axis_linear is +// offset == offset from current xyz, axis_X defines circle plane in tool space, axis_linear is // the direction of helical travel, radius == circle radius, isclockwise boolean. Used // for vector transformation direction. // The arc is approximated by generating a huge number of tiny, linear segments. The chordal tolerance @@ -103,10 +103,10 @@ // distance from segment to the circle when the end points both lie on the circle. #ifdef USE_LINE_NUMBERS void mc_arc(float *position, float *target, float *offset, float radius, float feed_rate, - uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, int32_t line_number) + uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc, int32_t line_number) #else void mc_arc(float *position, float *target, float *offset, float radius, float feed_rate, - uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear) + uint8_t invert_feed_rate, uint8_t axis_0, uint8_t axis_1, uint8_t axis_linear, uint8_t is_clockwise_arc) #endif { float center_axis0 = position[axis_0] + offset[axis_0]; @@ -118,7 +118,7 @@ // CCW angle between position and target from circle center. Only one atan2() trig computation required. float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); - if (gc_state.modal.motion == MOTION_MODE_CW_ARC) { // Correct atan2 output per direction + if (is_clockwise_arc) { // Correct atan2 output per direction if (angular_travel >= 0) { angular_travel -= 2*M_PI; } } else { if (angular_travel <= 0) { angular_travel += 2*M_PI; } @@ -287,9 +287,11 @@ void mc_homing_cycle() // Perform tool length probe cycle. Requires probe switch. // NOTE: Upon probe failure, the program will be stopped and placed into ALARM state. #ifdef USE_LINE_NUMBERS - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode, int32_t line_number) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, + uint8_t is_no_error, int32_t line_number) #else - void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t mode) + void mc_probe_cycle(float *target, float feed_rate, uint8_t invert_feed_rate, uint8_t is_probe_away, + uint8_t is_no_error) #endif { // TODO: Need to update this cycle so it obeys a non-auto cycle start. @@ -298,10 +300,14 @@ void mc_homing_cycle() // Finish all queued commands and empty planner buffer before starting probe cycle. protocol_buffer_synchronize(); uint8_t auto_start_state = sys.auto_start; // Store run state - uint8_t perform_pull_off = 1; + // Initialize probing control variables + sys.probe_succeeded = false; // Re-initialize probe history before beginning cycle. + probe_configure_invert_mask(is_probe_away); + // After syncing, check if probe is already triggered. If so, halt and issue alarm. - if (probe_get_state(mode) && probe_errors_enabled(mode)) { + // NOTE: This probe initialization error applies to all probing cycles. + if ( probe_get_state() ) { // Check probe pin state. bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); protocol_execute_runtime(); } @@ -314,8 +320,8 @@ void mc_homing_cycle() mc_line(target, feed_rate, invert_feed_rate); #endif - // Activate the probing monitor in the stepper module. - sys.probe_state = PROBE_ACTIVE | mode; + // Activate the probing state monitor in the stepper module. + sys.probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. bit_true_atomic(sys.execute, EXEC_CYCLE_START); @@ -323,17 +329,17 @@ void mc_homing_cycle() protocol_execute_runtime(); if (sys.abort) { return; } // Check for system abort } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); - - // Probing motion complete. If the probe has not been triggered, error out. - if (sys.probe_state & PROBE_ACTIVE) { - - if (probe_errors_enabled(mode)) { - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); - } else { - perform_pull_off = 0; - probe_finalize(0); - } + + // Probing cycle complete! + + // Set state variables and error out, if the probe failed and cycle with error is enabled. + if (sys.probe_state == PROBE_ACTIVE) { + if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } + else { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + } else { + sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } + sys.probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. protocol_execute_runtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort @@ -342,24 +348,11 @@ void mc_homing_cycle() plan_reset(); // Reset planner buffer. Zero planner positions. Ensure probing motion is cleared. plan_sync_position(); // Sync planner position to current machine position. - if (perform_pull_off) { - // Pull-off triggered probe to the trigger location since we had to decelerate a little beyond - // it to stop the machine in a controlled manner. - uint8_t idx; - for(idx=0; idx> PROBE_AWAY_BIT) & 1) << PROBE_BIT; - return mode ^ ((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away) +{ + probe_invert_mask = 0; // Initialize as zero. + if (bit_isfalse(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { probe_invert_mask ^= PROBE_MASK; } + if (is_probe_away) { probe_invert_mask ^= PROBE_MASK; } } -uint8_t probe_errors_enabled(uint8_t mode) { - return !(mode & PROBE_NO_ERROR); -} -void probe_finalize(uint8_t probe_succeeded) { - sys.probe_state = PROBE_OFF; - sys.probe_succeeded = probe_succeeded; - memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); - bit_true(sys.execute, EXEC_FEED_HOLD); -} +// Returns the probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state() { return((PROBE_PIN & PROBE_MASK) ^ probe_invert_mask); } + // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. // NOTE: This function must be extremely efficient as to not bog down the stepper ISR. void probe_state_monitor() { - if (sys.probe_state != PROBE_OFF) { - if (probe_get_state(sys.probe_state)) { - probe_finalize(1); + if (sys.probe_state == PROBE_ACTIVE) { + if (probe_get_state()) { + sys.probe_state = PROBE_OFF; + memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); + bit_true(sys.execute, EXEC_FEED_HOLD); } } } diff --git a/probe.h b/probe.h index 17028eb74..968d7eca2 100644 --- a/probe.h +++ b/probe.h @@ -22,25 +22,19 @@ #define probe_h // Values that define the probing state machine. -#define PROBE_OFF 0 // No probing. (Must be zero.) +#define PROBE_OFF 0 // Probing disabled or not in use. (Must be zero.) #define PROBE_ACTIVE 1 // Actively watching the input pin. -// Probe direction and error modes -#define PROBE_AWAY 2 // G38.4, G38.5 -#define PROBE_NO_ERROR 4 // G38.3, G38.5 - -#define PROBE_AWAY_BIT 1 -#define PROBE_NO_ERROR_BIT 2 - // Probe pin initialization routine. void probe_init(); -// Returns probe pin state. -uint8_t probe_get_state(uint8_t mode); - -uint8_t probe_errors_enabled(uint8_t mode); +// Called by probe_init() and the mc_probe() routines. Sets up the probe pin invert mask to +// appropriately set the pin logic according to setting for normal-high/normal-low operation +// and the probing cycle modes for toward-workpiece/away-from-workpiece. +void probe_configure_invert_mask(uint8_t is_probe_away); -void probe_finalize(uint8_t probe_succeeded); +// Returns probe pin state. Triggered = true. Called by gcode parser and probe state monitor. +uint8_t probe_get_state(); // Monitors probe pin state and records the system position when detected. Called by the // stepper ISR per ISR tick. diff --git a/report.c b/report.c index 9235f3768..58f01d0f7 100644 --- a/report.c +++ b/report.c @@ -281,12 +281,18 @@ void report_ngc_parameters() // Print current gcode parser mode state void report_gcode_modes() { + printPgmString(PSTR("[")); + switch (gc_state.modal.motion) { - case MOTION_MODE_SEEK : printPgmString(PSTR("[G0")); break; - case MOTION_MODE_LINEAR : printPgmString(PSTR("[G1")); break; - case MOTION_MODE_CW_ARC : printPgmString(PSTR("[G2")); break; - case MOTION_MODE_CCW_ARC : printPgmString(PSTR("[G3")); break; - case MOTION_MODE_NONE : printPgmString(PSTR("[G80")); break; + case MOTION_MODE_SEEK : printPgmString(PSTR("G0")); break; + case MOTION_MODE_LINEAR : printPgmString(PSTR("G1")); break; + case MOTION_MODE_CW_ARC : printPgmString(PSTR("G2")); break; + case MOTION_MODE_CCW_ARC : printPgmString(PSTR("G3")); break; + case MOTION_MODE_PROBE_TOWARD : printPgmString(PSTR("G38.2")); break; + case MOTION_MODE_PROBE_TOWARD_NO_ERROR : printPgmString(PSTR("G38.3")); break; + case MOTION_MODE_PROBE_AWAY : printPgmString(PSTR("G38.4")); break; + case MOTION_MODE_PROBE_AWAY_NO_ERROR : printPgmString(PSTR("G38.5")); break; + case MOTION_MODE_NONE : printPgmString(PSTR("G80")); break; } printPgmString(PSTR(" G")); diff --git a/spindle_control.c b/spindle_control.c index b8410844e..de773eebe 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -86,10 +86,16 @@ void spindle_run(uint8_t direction, float rpm) #define SPINDLE_RPM_RANGE (SPINDLE_MAX_RPM-SPINDLE_MIN_RPM) TCCRA_REGISTER = (1< SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + if ( rpm < SPINDLE_MIN_RPM ) { rpm = 0; } + else { + rpm -= SPINDLE_MIN_RPM; + if ( rpm > SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + } uint8_t current_pwm = floor( rpm*(255.0/SPINDLE_RPM_RANGE) + 0.5); - OCR_REGISTER = current_pwm; + #ifdef MINIMUM_SPINDLE_PWM + if (current_pwm < MINIMUM_SPINDLE_PWM) { current_pwm = MINIMUM_SPINDLE_PWM; } + #endif + OCR_REGISTER = current_pwm; // Set PWM pin output #ifndef CPU_MAP_ATMEGA328P // On the Uno, spindle enable and PWM are shared. SPINDLE_ENABLE_PORT |= (1< Date: Wed, 14 Jan 2015 22:14:52 -0700 Subject: [PATCH 17/74] Lot of refactoring for the future. CoreXY support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rudimentary CoreXY kinematics support. Didn’t test, but homing and feed holds should work. See config.h. Please report successes and issues as we find bugs. - G40 (disable cutter comp) is now “supported”. Meaning that Grbl will no longer issue an error when typically sent in g-code program header. - Refactored coolant and spindle state setting into separate functions for future features. - Configuration option for fixing homing behavior when there are two limit switches on the same axis sharing an input pin. - Created a new “grbl.h” that will eventually be used as the main include file for Grbl. Also will help simply uploading through the Arduino IDE - Separated out the alarms execution flags from the realtime (used be called runtime) execution flag variable. Now reports exactly what caused the alarm. Expandable for new alarms later on. - Refactored the homing cycle to support CoreXY. - Applied @EliteEng updates to Mega2560 support. Some pins were reconfigured. - Created a central step to position and vice versa function. Needed for non-traditional cartesian machines. Should make it easier later. - Removed the new CPU map for the Uno. No longer going to used. There will be only one configuration to keep things uniform. --- config.h | 27 +- coolant_control.c | 16 +- coolant_control.h | 3 +- cpu_map.h | 176 +- defaults.h | 2 +- gcode.c | 34 +- gcode.h | 43 +- grbl.h | 49 + limits.c | 139 +- limits.h | 2 +- main.c | 5 +- motion_control.c | 66 +- motion_control.h | 2 +- nuts_bolts.c | 2 +- nuts_bolts.h | 14 +- planner.c | 53 +- planner.h | 2 +- print.c | 2 +- print.h | 2 +- probe.c | 4 +- probe.h | 2 +- protocol.c | 93 +- protocol.h | 6 +- report.c | 19 +- report.h | 9 +- serial.c | 14 +- serial.h | 2 +- settings.c | 4 +- settings.h | 6 +- spindle_control.c | 41 +- spindle_control.h | 4 +- stepper.c | 8 +- stepper.h | 8 +- system.c | 67 +- system.h | 36 +- test/gcode/8x_gear_test.nc | 4919 ------------------------------ test/gcode/HSM_test.nc | 1758 ----------- test/gcode/SO2_helloworld.nc | 773 ----- test/gcode/braid_cut2d.nc | 2517 --------------- test/matlab/grbl_sim.m | 437 --- test/matlab/matlab.gcode | 2362 -------------- test/matlab/matlab_convert.py | 270 -- test/matlab/test.gcode | 2363 -------------- test/settings/kikigey89.settings | 31 - test/test.py | 25 - 45 files changed, 530 insertions(+), 15887 deletions(-) create mode 100644 grbl.h delete mode 100644 test/gcode/8x_gear_test.nc delete mode 100644 test/gcode/HSM_test.nc delete mode 100644 test/gcode/SO2_helloworld.nc delete mode 100644 test/gcode/braid_cut2d.nc delete mode 100644 test/matlab/grbl_sim.m delete mode 100644 test/matlab/matlab.gcode delete mode 100755 test/matlab/matlab_convert.py delete mode 100644 test/matlab/test.gcode delete mode 100644 test/settings/kikigey89.settings delete mode 100644 test/test.py diff --git a/config.h b/config.h index 378ad6a16..60d240bd3 100644 --- a/config.h +++ b/config.h @@ -2,7 +2,7 @@ config.h - compile time configuration Part of Grbl v0.9 - Copyright (c) 2013-2014 Sungeun K. Jeon + Copyright (c) 2013-2015 Sungeun K. Jeon Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,9 +43,9 @@ // Default cpu mappings. Grbl officially supports the Arduino Uno only. Other processor types // may exist from user-supplied templates or directly user-defined in cpu_map.h -#define CPU_MAP_ATMEGA328P_TRADITIONAL // Arduino Uno CPU +#define CPU_MAP_ATMEGA328P // Arduino Uno CPU -// Define runtime command special characters. These characters are 'picked-off' directly from the +// Define realtime command special characters. These characters are 'picked-off' directly from the // serial read data stream and are not passed to the grbl line execution parser. Select characters // that do not and must not exist in the streamed g-code program. ASCII control characters may be // used, if they are available per user setup. Also, extended ASCII codes (>127), which are never in @@ -107,6 +107,14 @@ #define N_DECIMAL_RATEVALUE_MM 0 // Rate or velocity value in mm/min #define N_DECIMAL_SETTINGVALUE 3 // Decimals for floating point setting values +// If your machine has two limits switches wired in parallel to one axis, you will need to enable +// this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell +// which one is enabled. This option only effects homing, where if a limit is engaged, Grbl will +// alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one +// limit switch for each axis, don't enable this option. By keeping it disabled, you can homing while +// on the limit switch and not have to move the machine off of it. +// #define LIMITS_TWO_SWITCHES_ON_AXES + // Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer // goes from 18 or 16 to make room for the additional line number data in the plan_block_t struct // #define USE_LINE_NUMBERS // Disabled by default. Uncomment to enable. @@ -126,6 +134,15 @@ // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // #define ENABLE_M7 // Disabled by default. Uncomment to enable. +// Enable CoreXY kinematics. Use ONLY with CoreXY machines. +// IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to +// #define HOMING_CYCLE_0 (1< 255) -// #error Parameters ACCELERATION_TICKS / ISR_TICKS must be < 256 to prevent integer overflow. -// #endif + // --------------------------------------------------------------------------------------- diff --git a/coolant_control.c b/coolant_control.c index 9f629ce8c..d8336d5be 100644 --- a/coolant_control.c +++ b/coolant_control.c @@ -2,7 +2,7 @@ coolant_control.c - coolant control methods Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -43,12 +43,8 @@ void coolant_stop() } -void coolant_run(uint8_t mode) +void coolant_set_state(uint8_t mode) { - if (sys.state == STATE_CHECK_MODE) { return; } - - protocol_auto_cycle_start(); //temp fix for M8 lockup - protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. if (mode == COOLANT_FLOOD_ENABLE) { COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT); @@ -61,3 +57,11 @@ void coolant_run(uint8_t mode) coolant_stop(); } } + + +void coolant_run(uint8_t mode) +{ + if (sys.state == STATE_CHECK_MODE) { return; } + protocol_buffer_synchronize(); // Ensure coolant turns on when specified in program. + coolant_set_state(mode); +} diff --git a/coolant_control.h b/coolant_control.h index db3c71cd8..f093cee29 100644 --- a/coolant_control.h +++ b/coolant_control.h @@ -2,7 +2,7 @@ coolant_control.h - spindle control methods Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ void coolant_init(); void coolant_stop(); +void coolant_set_state(uint8_t mode); void coolant_run(uint8_t mode); #endif \ No newline at end of file diff --git a/cpu_map.h b/cpu_map.h index 72955136c..3e46c3092 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -2,7 +2,7 @@ cpu_map.h - CPU and pin mapping configuration file Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ //---------------------------------------------------------------------------------------- -#ifdef CPU_MAP_ATMEGA328P_TRADITIONAL // (Arduino Uno) Officially supported by Grbl. +#ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. // Define serial port pins and interrupt vectors. #define SERIAL_RX USART_RX_vect @@ -123,6 +123,7 @@ #ifdef VARIABLE_SPINDLE // Advanced Configuration Below You should not need to touch these variables + #define PWM_MAX_VALUE 255.0 #define TCCRA_REGISTER TCCR2A #define TCCRB_REGISTER TCCR2B #define OCR_REGISTER OCR2A @@ -142,118 +143,6 @@ #endif -//---------------------------------------------------------------------------------------- - -#ifdef CPU_MAP_ATMEGA328P_NEW // (Arduino Uno) New test pinout configuration. Still subject to change. Not finalized! - - // Define serial port pins and interrupt vectors. - #define SERIAL_RX USART_RX_vect - #define SERIAL_UDRE USART_UDRE_vect - - // Define step pulse output pins. NOTE: All step bit pins must be on the same port. - #define STEP_DDR DDRD - #define STEP_PORT PORTD - #define X_STEP_BIT 2 // Uno Digital Pin 2 - #define Y_STEP_BIT 3 // Uno Digital Pin 3 - #define Z_STEP_BIT 4 // Uno Digital Pin 4 - #define STEP_MASK ((1<. +*/ + +// NOTE: This is not used by the 'make' compiling method. This is currently only used for +// simplifying compiling through the Arduino IDE at the moment. However, it may eventually +// turn into a central include file for the overall system. + +#ifndef grbl_h +#define grbl_h + +// All of the Grbl system include files. +#include "config.h" +#include "coolant_control.h" +#include "cpu_map.h" +#include "defaults.h" +#include "eeprom.h" +#include "gcode.h" +#include "limits.h" +#include "motion_control.h" +#include "nuts_bolts.h" +#include "planner.h" +#include "print.h" +#include "probe.h" +#include "protocol.h" +#include "report.h" +#include "serial.h" +#include "settings.h" +#include "spindle_control.h" +#include "stepper.h" +#include "system.h" + +#endif diff --git a/limits.c b/limits.c index 4538dcb3f..9cb43c474 100644 --- a/limits.c +++ b/limits.c @@ -2,7 +2,7 @@ limits.c - code pertaining to limit-switches and performing the homing cycle Part of Grbl v0.9 - Copyright (c) 2012-2014 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -89,9 +89,9 @@ void limits_disable() // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard // limit setting if their limits are constantly triggering after a reset and move their axes. if (sys.state != STATE_ALARM) { - if (bit_isfalse(sys.execute,EXEC_ALARM)) { + if (!(sys.rt_exec_alarm)) { mc_reset(); // Initiate system kill. - bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate hard limit critical event + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event } } } @@ -102,13 +102,13 @@ void limits_disable() { WDTCSR &= ~(1< settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } @@ -148,6 +151,7 @@ void limits_go_home(uint8_t cycle_mask) max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. + plan_sync_position(); // Sync planner position to current machine position. do { // Initialize invert_pin boolean based on approach and invert pin user setting. @@ -157,20 +161,23 @@ void limits_go_home(uint8_t cycle_mask) // Initialize and declare variables needed for homing routine. uint8_t n_active_axis = 0; uint8_t axislock = 0; - + + system_convert_array_steps_to_mpos(target,sys.position); for (idx=0; idx 0.0) { + for (idx=0; idx 0) { - // NOTE: Check and execute runtime commands during dwell every <= DWELL_TIME_STEP milliseconds. - protocol_execute_runtime(); + // NOTE: Check and execute realtime commands during dwell every <= DWELL_TIME_STEP milliseconds. + protocol_execute_realtime(); if (sys.abort) { return; } _delay_ms(DWELL_TIME_STEP); // Delay DWELL_TIME_STEP increment } @@ -243,15 +244,16 @@ void mc_homing_cycle() // Check and abort homing cycle, if hard limits are already enabled. Helps prevent problems // with machines with limits wired on both ends of travel to one limit pin. // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function. - uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); - if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } - if (limit_state) { - mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. - bit_true_atomic(sys.execute, (EXEC_ALARM | EXEC_CRIT_EVENT)); // Indicate homing limit critical event - return; - } - - sys.state = STATE_HOMING; // Set system state variable + #ifdef LIMITS_TWO_SWITCHES_ON_AXES + uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } + if (limit_state) { + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); + return; + } + #endif + limits_disable(); // Disable hard limits pin change register for cycle duration // ------------------------------------------------------------------------------------- @@ -266,7 +268,7 @@ void mc_homing_cycle() limits_go_home(HOMING_CYCLE_2); // Homing cycle 2 #endif - protocol_execute_runtime(); // Check for reset and set system abort. + protocol_execute_realtime(); // Check for reset and set system abort. if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm. // Homing cycle complete! Setup system for normal operation. @@ -275,10 +277,6 @@ void mc_homing_cycle() // Gcode parser position was circumvented by the limits_go_home() routine, so sync position now. gc_sync_position(); - // Set idle state after homing completes and before returning to main program. - sys.state = STATE_IDLE; - st_go_idle(); // Set idle state after homing completes - // If hard limits feature enabled, re-enable hard limits pin change register after homing cycle. limits_init(); } @@ -308,8 +306,8 @@ void mc_homing_cycle() // After syncing, check if probe is already triggered. If so, halt and issue alarm. // NOTE: This probe initialization error applies to all probing cycles. if ( probe_get_state() ) { // Check probe pin state. - bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); - protocol_execute_runtime(); + bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); + protocol_execute_realtime(); } if (sys.abort) { return; } // Return if system reset has been issued. @@ -324,9 +322,9 @@ void mc_homing_cycle() sys.probe_state = PROBE_ACTIVE; // Perform probing cycle. Wait here until probe is triggered or motion completes. - bit_true_atomic(sys.execute, EXEC_CYCLE_START); + bit_true_atomic(sys.rt_exec_state, EXEC_CYCLE_START); do { - protocol_execute_runtime(); + protocol_execute_realtime(); if (sys.abort) { return; } // Check for system abort } while ((sys.state != STATE_IDLE) && (sys.state != STATE_QUEUED)); @@ -335,12 +333,12 @@ void mc_homing_cycle() // Set state variables and error out, if the probe failed and cycle with error is enabled. if (sys.probe_state == PROBE_ACTIVE) { if (is_no_error) { memcpy(sys.probe_position, sys.position, sizeof(float)*N_AXIS); } - else { bit_true_atomic(sys.execute, EXEC_CRIT_EVENT); } + else { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_PROBE_FAIL); } } else { sys.probe_succeeded = true; // Indicate to system the probing cycle completed successfully. } sys.probe_state = PROBE_OFF; // Ensure probe state monitor is disabled. - protocol_execute_runtime(); // Check and execute run-time commands + protocol_execute_realtime(); // Check and execute run-time commands if (sys.abort) { return; } // Check for system abort // Reset the stepper and planner buffers to remove the remainder of the probe motion. @@ -349,13 +347,11 @@ void mc_homing_cycle() plan_sync_position(); // Sync planner position to current machine position. // TODO: Update the g-code parser code to not require this target calculation but uses a gc_sync_position() call. - uint8_t idx; - for(idx=0; idxsteps[A_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + #endif + for (idx=0; idxsteps[idx] = labs(target_steps[idx]-pl.position[idx]); - block->step_event_count = max(block->step_event_count, block->steps[idx]); - - // Compute individual axes distance for move and prep unit vector calculations. + // Calculate target position in absolute steps, number of steps for each axis, and determine max step events. + // Also, compute individual axes distance for move and prep unit vector calculations. // NOTE: Computes true distance from converted step values. - delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + #ifdef COREXY + if ( !(idx == A_MOTOR) && !(idx == B_MOTOR) ) { + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-pl.position[idx]); + } + block->step_event_count = max(block->step_event_count, block->steps[idx]); + if (idx == A_MOTOR) { + delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; + } else if (idx == B_MOTOR) { + delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; + } else { + delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + } + #else + target_steps[idx] = lround(target[idx]*settings.steps_per_mm[idx]); + block->steps[idx] = labs(target_steps[idx]-pl.position[idx]); + block->step_event_count = max(block->step_event_count, block->steps[idx]); + delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; + #endif unit_vec[idx] = delta_mm; // Store unit vector numerator. Denominator computed later. // Set direction bits. Bit enabled always means direction is negative. @@ -403,9 +422,21 @@ uint8_t plan_check_full_buffer() // Reset the planner position vectors. Called by the system abort/initialization routine. void plan_sync_position() { + // TODO: For motor configurations not in the same coordinate frame as the machine position, + // this function needs to be updated to accomodate the difference. uint8_t idx; for (idx=0; idx SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent uint8 overflow + if ( rpm > SPINDLE_RPM_RANGE ) { rpm = SPINDLE_RPM_RANGE; } // Prevent integer overflow } - uint8_t current_pwm = floor( rpm*(255.0/SPINDLE_RPM_RANGE) + 0.5); + current_pwm = floor( rpm*(PWM_MAX_VALUE/SPINDLE_RPM_RANGE) + 0.5); #ifdef MINIMUM_SPINDLE_PWM if (current_pwm < MINIMUM_SPINDLE_PWM) { current_pwm = MINIMUM_SPINDLE_PWM; } #endif OCR_REGISTER = current_pwm; // Set PWM pin output - #ifndef CPU_MAP_ATMEGA328P // On the Uno, spindle enable and PWM are shared. + #ifdef CPU_MAP_ATMEGA2560 // On the Uno, spindle enable and PWM are shared. SPINDLE_ENABLE_PORT |= (1<, this feeds the simulator planner one line motion -% block. The left side is the first block in the buffer and the one that will be executed -% by the stepper module first. The right side is the end of the planner buffer, where the -% most recent streamed block is appended onto the planner buffer. Grbl's planner -% optimizes the velocity profiles between the beginning and end of the buffer based on -% the acceleration limits, intended velocity/feedrate, and line motion junction angles -% with their corresponding velocity limits (i.e. junctions with acute angles needs to come -% to a complete stop vs straight junctions can continue through at full speed.) - -% ---------------------------------------------------------------------------------------- - - -% Main function -% NOTE: This is just a way to keep all functions in one place, but all non-global variables -% are cleared as soon as this script completes. -function main() - -% Load pre-parsed gcode moves. -close all; -warning off; -clearvars -global -fid = fopen('matlab.gcode','r'); -gcode = textscan(fid,'%d8%f32%f32%f32%f32'); -nblock = length(gcode{1}); - -% Plot all g-code moves. -figure -line(gcode{3},gcode{4},gcode{5}); -axis equal; -% axis([min(gcode{3}) max(gcode{3}) min(gcode{4}) max(gcode{4}) min(gcode{5}) max(gcode{5})]); -title('G-code programming line motions'); -view(3); - -% Set up figure for planner queue -figure - -% Print help. -disp(''); -disp(' BLUE line indicates completed planner blocks that require no recalculation.'); -disp(' RED line indicates planner blocks that have been recalculated.'); -disp(' GREEN line indicates the location of the BPLANNED pointer. Always a recalculated block.'); -disp(' BLACK dotted-line and ''x'' indicates block nominal speed and max junction velocity, respectively.'); -disp(' CYAN ''.'' indicates block initial entry speed.'); - -% Define Grbl settings. -BUFFER_SIZE = 18; % Number of planner blocks in its ring buffer. -steps_per_mm = 200; -seekrate = 2500; % mm/min -acceleration = [100 100 100]; % mm/sec^2 [ X Y Z ] axes -junction_deviation = 0.1; % mm. See Grbl documentation on this parameter. -inch_2_mm = 25.4; -ACCELERATION_TICKS_PER_SECOND = 100; - -gcode{2} = gcode{2}; -gcode{2} = inch_2_mm*gcode{2}; -gcode{3} = inch_2_mm*gcode{3}; -gcode{4} = inch_2_mm*gcode{4}; -gcode{5} = inch_2_mm*gcode{5}; - -% Initialize blocks -block.steps = []; -block.step_event_count = []; -block.delta_mm = []; -block.millimeters = []; -block.acceleration = []; -block.speed = []; -block.nominal_speed = []; -block.max_entry_speed = []; -block.entry_speed = []; -block.recalculate_flag = false; -for i = 2:BUFFER_SIZE - block(i) = block(1); -end - -% Initialize planner -position = [0 0 0]; -prev_unit_vec = [0 0 0]; -previous_nominal_speed = 0; -pos = 0; - -% BHEAD and BTAIL act as pointers to the block head and tail. -% BPLANNED acts as a pointer of the location of the end of a completed/optimized plan. -bhead = 1; -btail = 1; -bplanned = 1; - -global block bhead btail bplanned nind acceleration BUFFER_SIZE pos ACCELERATION_TICKS_PER_SECOND - -% Main loop. Simulates plan_buffer_line(). All of the precalculations for the newest incoming -% block occurs here. Anything independent of the planner changes. -for i = 1:nblock - - target = round([gcode{3}(i) gcode{4}(i) gcode{5}(i)].*steps_per_mm); - if gcode{1}(i) == 1 - feedrate = gcode{2}(i); - else - feedrate = seekrate; - end - - nind = next_block_index(bhead); - if nind == btail - % Simulate a constantly full buffer. Move buffer tail. - bind = next_block_index(btail); - % Push planned pointer if encountered. Prevents it from looping back around the ring buffer. - if btail == bplanned; bplanned = bind; end - btail = bind; - end - - block(bhead).steps = abs(target-position); - block(bhead).step_event_count = max(block(bhead).steps); - - % Bail if this is a zero-length block - if block(bhead).step_event_count == 0 - disp(['Zero-length block in line ',int2str(i)]); - else - - % Compute path vector in terms of absolute step target and current positions - delta_mm = single((target-position)./steps_per_mm); - block(bhead).millimeters = single(norm(delta_mm)); - inverse_millimeters = single(1/block(bhead).millimeters); - - % Compute path unit vector - unit_vec = delta_mm/block(bhead).millimeters; - - % Calculate speed in mm/minute for each axis - inverse_minute = single(feedrate * inverse_millimeters); - block(bhead).speed = delta_mm*inverse_minute; - block(bhead).nominal_speed = block(bhead).millimeters*inverse_minute; - - % Calculate block acceleration. Operates on absolute value of unit vector. - [max_acc,ind] = max(abs(unit_vec)./acceleration); % Determine limiting acceleration - block(bhead).acceleration = acceleration(ind)/abs(unit_vec(ind)); - - % Compute maximum junction speed - block(bhead).max_entry_speed = 0.0; - if previous_nominal_speed > 0.0 - cos_theta = dot(-previous_unit_vec,unit_vec); - if (cos_theta < 0.95) - block(bhead).max_entry_speed = min([block(bhead).nominal_speed,previous_nominal_speed]); - if (cos_theta > -0.95) - sin_theta_d2 = sqrt(0.5*(1.0-cos_theta)); - block(bhead).max_entry_speed = min([block(bhead).max_entry_speed,sqrt(block(bhead).acceleration*3600*junction_deviation*sin_theta_d2/(1.0-sin_theta_d2))]); - end - end - end - - block(bhead).entry_speed = 0; % Just initialize. Set accurately in the replanning function. - block(bhead).recalculate_flag = true; % Plotting flag to indicate this block has been updated. - - previous_unit_vec = unit_vec; - previous_nominal_speed = block(bhead).nominal_speed; - position = target; - - bhead = nind; % Block complete. Push buffer pointer. - planner_recalculate(); - - plot_buffer_velocities(); - end -end -return - -% Computes the next block index in the planner ring buffer -function block_index = next_block_index(block_index) -global BUFFER_SIZE - block_index = block_index + 1; - if block_index > BUFFER_SIZE - block_index = 1; - end -return - -% Computes the previous block index in the planner ring buffer -function block_index = prev_block_index(block_index) -global BUFFER_SIZE - block_index = block_index-1; - if block_index < 1 - block_index = BUFFER_SIZE; - end -return - - -% Planner recalculate function. The magic happens here. -function planner_recalculate(block) - - global block bhead btail bplanned acceleration - - bind = prev_block_index(bhead); - if bind == bplanned; return; end % Bail, if only one block in buffer. Can't be operated on. - - % Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last - % block in buffer. Cease planning when the last optimal planned or tail pointer is reached. - % NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan. - next = []; - curr = bind; % Last block in buffer. - - % Calculate maximum entry speed for last block in buffer, where the exit speed is always zero. - block(curr).entry_speed = min([block(curr).max_entry_speed,sqrt(2*block(curr).acceleration*60*60*block(curr).millimeters)]); - - bind = prev_block_index(bind); % Btail or second to last block - if (bind == bplanned) - % Only two plannable blocks in buffer. Reverse pass complete. - % Check if the first block is the tail. If so, notify stepper module to update its current parameters. - % if bind == btail; update_tail_block; end - else - % Three or more plannable blocks in buffer. Loop it. - while bind ~= bplanned % Loop until bplanned point hits. Replans to last plan point. - next = curr; - curr = bind; - bind = prev_block_index( bind ); % Previous block pointer. - - % Check if the first block is the tail. If so, notify stepper module to update its current parameters. - % if bind == btail; update_tail_block; end - - % Compute maximum entry speed decelerating over the current block from its exit speed. - if block(curr).entry_speed ~= block(curr).max_entry_speed - block(curr).recalculate_flag = true; % Plotting flag to indicate this block has been updated. - block(curr).entry_speed = min([ block(curr).max_entry_speed,... - sqrt(block(next).entry_speed^2 + 2*block(curr).acceleration*60*60*block(curr).millimeters)]); - end - - end - end - - % For two blocks, reverse pass is skipped, but forward pass plans second block entry speed - % onward. This prevents the first, or the potentially executing block, from being over-written. - % NOTE: Can never be bhead, since bsafe is always in active buffer. - next = bplanned; - bind = next_block_index(bplanned); % Start at bplanned - while bind ~= bhead - curr = next; - next = bind; - - % An acceleration block is always an optimally planned block since it starts from the first - % block's current speed or a maximum junction speed. Compute accelerations from this block - % and update the next block's entry speed. - if (block(curr).entry_speed < block(next).entry_speed) - % Once speed is set by forward planner, the plan for this block is finished and optimal. - % Increment the planner pointer forward one block. - - entry_speed = sqrt(block(curr).entry_speed^2 + 2*block(curr).acceleration*60*60*block(curr).millimeters); - if (block(next).entry_speed > entry_speed) - block(next).entry_speed = entry_speed; - bplanned = bind; - end - - end - - % Check if the next block entry speed is at max_entry_speed. If so, move the planned pointer, since - % this entry speed cannot be improved anymore and all prior blocks have been completed and optimally planned. - if block(next).entry_speed == block(next).max_entry_speed - bplanned = bind; - end - - % Recalculate trapezoid can be installed here, since it scans through all of the plannable blocks. - % NOTE: Eventually this will only be computed when being executed. - - bind = next_block_index( bind ); - - end - -return - -% ---------------------------------------------------------------------------------------- -% PLOTTING FUNCTIONS - -% Plots the entire buffer plan into a MATLAB figure to visual the plan. -% BLUE line indicates completed planner blocks that require no recalculation. -% RED line indicates planner blocks that have been recalculated. -% GREEN line indicates the location of the BPLANNED pointer. Always a recalculated block. -% BLACK dotted-line and 'x' indicates block nominal speed and max junction velocity, respectively. -% CYAN '.' indicates block initial entry speed. -function plot_buffer_velocities() - global block bhead btail bplanned acceleration pos ACCELERATION_TICKS_PER_SECOND - bind = btail; - curr = []; - next = []; - - pos_initial = 0; - pos = 0; - while bind ~= bhead - curr = next; - next = bind; - hold on; - if ~isempty(curr) - accel_d = estimate_acceleration_distance(block(curr).entry_speed, block(curr).nominal_speed, block(curr).acceleration*60*60); - decel_d = estimate_acceleration_distance(block(curr).nominal_speed, block(next).entry_speed,-block(curr).acceleration*60*60); - plateau_d = block(curr).millimeters-accel_d-decel_d; - if plateau_d < 0 - accel_d = intersection_distance(block(curr).entry_speed, block(next).entry_speed, block(curr).acceleration*60*60, block(curr).millimeters); - if accel_d < 0 - accel_d = 0; - elseif accel_d > block(curr).millimeters - accel_d = block(curr).millimeters; - end - plateau_d = 0; - end - color = 'b'; - if (block(curr).recalculate_flag || block(next).recalculate_flag) - block(curr).recalculate_flag = false; - color = 'r'; - end - if bplanned == curr - color = 'g'; - end - - plot_trap(pos,block(curr).entry_speed,block(next).entry_speed,block(curr).nominal_speed,block(curr).acceleration,accel_d,plateau_d,block(curr).millimeters,color) - plot([pos pos+block(curr).millimeters],block(curr).nominal_speed*[1 1],'k:') % BLACK dotted indicates - plot(pos,block(curr).max_entry_speed,'kx') - - pos = pos + block(curr).millimeters; - plot(pos,block(next).entry_speed,'c.'); - end - bind = next_block_index( bind ); - end - - accel_d = estimate_acceleration_distance(block(next).entry_speed, block(next).nominal_speed, block(next).acceleration*60*60); - decel_d = estimate_acceleration_distance(block(next).nominal_speed, 0, -block(next).acceleration*60*60); - plateau_d = block(next).millimeters-accel_d-decel_d; - if plateau_d < 0 - accel_d = intersection_distance(block(next).entry_speed, 0, block(next).acceleration*60*60, block(next).millimeters); - if accel_d < 0 - accel_d = 0; - elseif accel_d > block(next).millimeters - accel_d = block(next).millimeters; - end - plateau_d = 0; - end - block(next).recalculate_flag = false; - color = 'r'; - if bplanned == next - color= 'g'; - end - - plot_trap(pos,block(next).entry_speed,0,block(next).nominal_speed,block(next).acceleration,accel_d,plateau_d,block(next).millimeters,color) - plot([pos pos+block(next).millimeters],block(next).nominal_speed*[1 1],'k:') - plot(pos,block(next).max_entry_speed,'kx') - - plot(pos,block(next).entry_speed,'.'); - pos = pos + block(next).millimeters; - plot(pos,0,'rx'); - xlabel('mm'); - ylabel('mm/sec'); - xlim([pos_initial pos]) - title('Planner buffer optimized velocity profile'); - pause(); - hold off; - - plot(pos,0) -return - - -function d_a = estimate_acceleration_distance(initial_rate, target_rate, acceleration,rate_delta) - d_a = (target_rate*target_rate-initial_rate*initial_rate)/(2*acceleration); -return - -function d_i = intersection_distance(initial_rate, final_rate, acceleration, distance, rate_delta) - d_i = (2*acceleration*distance-initial_rate*initial_rate+final_rate*final_rate)/(4*acceleration); -return - - -% Simply plots the ac/de-celeration curves and plateaus of a trapezoid. -function plot_trap(pos,initial_rate,final_rate,rate,accel,accel_d,plateau_d,millimeters,color) - - dx = 1.0; % Line segment length - linex = [pos]; liney = [initial_rate]; - - % Acceleration - np = floor(accel_d/dx); - if np - v = initial_rate; - for i = 1:np - v = sqrt(v^2+2*accel*60*60*dx); - linex = [linex pos+i*dx]; - liney = [liney v]; - end - end - - % Plateau - v = sqrt(initial_rate^2 + 2*accel*60*60*accel_d); - if v < rate - rate = v; - end - linex = [linex pos+[accel_d accel_d+plateau_d]]; - liney = [liney [rate rate]]; - - % Deceleration - np = floor((millimeters-accel_d-plateau_d)/dx); - if np - v = rate; - for i = 1:np - v = sqrt(v^2-2*accel*60*60*dx); - linex = [linex pos+i*dx+accel_d+plateau_d]; - liney = [liney v]; - end - end - - linex = [linex pos+millimeters]; - liney = [ liney final_rate]; - plot(linex,liney,color); - -return - - - diff --git a/test/matlab/matlab.gcode b/test/matlab/matlab.gcode deleted file mode 100644 index 8ad9cdc25..000000000 --- a/test/matlab/matlab.gcode +++ /dev/null @@ -1,2362 +0,0 @@ -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 0.0 -0 0.0 0.0 0.0 6.0 -0 0.0 37.56 12.33 6.0 -1 300.0 37.56 12.33 -1.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 37.56 0.88 6.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 37.56 -10.57 -1.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 37.56 0.88 -1.0 -0 300.0 37.56 0.88 6.0 -0 300.0 49.01 12.33 6.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 52.08 15.01 -1.0 -0 300.0 52.08 15.01 6.0 -0 300.0 49.01 0.88 6.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 52.08 15.01 -1.0 -1 300.0 43.29 15.01 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 49.01 -10.57 6.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 52.08 -2.58 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 49.01 0.88 -1.0 -0 300.0 49.01 0.88 6.0 -0 300.0 49.01 0.88 20.0 -0 300.0 0.0 0.0 20.0 -1 300.0 -7.1 -39.88 20.0 -1 300.0 -10.3 -38.12 20.0 -1 300.0 -10.7 -37.9 20.0 -1 300.0 -11.1 -37.68 20.0 -1 300.0 -11.89 -37.23 20.0 -1 300.0 -13.45 -36.36 20.0 -1 300.0 -13.82 -36.14 20.0 -1 300.0 -14.2 -35.92 20.0 -1 300.0 -14.92 -35.48 20.0 -1 300.0 -16.29 -34.63 20.0 -1 300.0 -16.64 -34.4 20.0 -1 300.0 -16.97 -34.16 20.0 -1 300.0 -17.61 -33.71 20.0 -1 300.0 -17.91 -33.49 20.0 -1 300.0 -18.2 -33.26 20.0 -1 300.0 -18.74 -32.82 20.0 -1 300.0 -18.99 -32.6 20.0 -1 300.0 -19.23 -32.39 20.0 -1 300.0 -19.45 -32.17 20.0 -1 300.0 -19.65 -31.96 20.0 -1 300.0 -19.84 -31.75 20.0 -1 300.0 -20.02 -31.54 20.0 -1 300.0 -20.18 -31.34 20.0 -1 300.0 -20.32 -31.13 20.0 -1 300.0 -20.45 -30.93 20.0 -1 300.0 -20.56 -30.73 20.0 -1 300.0 -20.65 -30.54 20.0 -1 300.0 -20.73 -30.34 20.0 -1 300.0 -20.79 -30.15 20.0 -1 300.0 -20.84 -29.96 20.0 -1 300.0 -20.87 -29.78 20.0 -1 300.0 -20.88 -29.59 20.0 -1 300.0 -20.88 -29.41 20.0 -1 300.0 -20.85 -29.24 20.0 -1 300.0 -20.82 -29.06 20.0 -1 300.0 -20.76 -28.89 20.0 -1 300.0 -20.7 -28.72 20.0 -1 300.0 -20.61 -28.56 20.0 -1 300.0 -20.51 -28.4 20.0 -1 300.0 -20.39 -28.24 20.0 -1 300.0 -20.26 -28.08 20.0 -1 300.0 -20.12 -27.93 20.0 -1 300.0 -19.96 -27.78 20.0 -1 300.0 -19.78 -27.64 20.0 -1 300.0 -19.59 -27.5 20.0 -1 300.0 -19.39 -27.36 20.0 -1 300.0 -19.18 -27.23 20.0 -1 300.0 -18.95 -27.09 20.0 -1 300.0 -18.71 -26.97 20.0 -1 300.0 -18.46 -26.84 20.0 -1 300.0 -18.2 -26.73 20.0 -1 300.0 -17.92 -26.61 20.0 -1 300.0 -17.64 -26.5 20.0 -1 300.0 -17.35 -26.39 20.0 -1 300.0 -16.74 -26.18 20.0 -1 300.0 -16.42 -26.09 20.0 -1 300.0 -16.09 -25.99 20.0 -1 300.0 -15.76 -25.9 20.0 -1 300.0 -15.43 -25.82 20.0 -1 300.0 -15.08 -25.74 20.0 -1 300.0 -14.74 -25.66 20.0 -1 300.0 -14.03 -25.52 20.0 -1 300.0 -13.67 -25.45 20.0 -1 300.0 -13.31 -25.39 20.0 -1 300.0 -12.95 -25.33 20.0 -1 300.0 -12.59 -25.28 20.0 -1 300.0 -12.23 -25.23 20.0 -1 300.0 -11.87 -25.18 20.0 -1 300.0 -11.51 -25.14 20.0 -1 300.0 -11.15 -25.1 20.0 -1 300.0 -10.82 -25.07 20.0 -1 300.0 -10.5 -25.04 20.0 -1 300.0 -10.17 -25.02 20.0 -1 300.0 -9.85 -25.0 20.0 -1 300.0 -9.54 -24.98 20.0 -1 300.0 -9.23 -24.96 20.0 -1 300.0 -8.92 -24.95 20.0 -1 300.0 -8.63 -24.94 20.0 -1 300.0 -8.33 -24.94 20.0 -1 300.0 -8.05 -24.94 20.0 -1 300.0 -7.77 -24.94 20.0 -1 300.0 -7.5 -24.95 20.0 -1 300.0 -7.24 -24.95 20.0 -1 300.0 -6.99 -24.97 20.0 -1 300.0 -6.75 -24.98 20.0 -1 300.0 -6.52 -25.0 20.0 -1 300.0 -6.29 -25.02 20.0 -1 300.0 -6.08 -25.05 20.0 -1 300.0 -5.88 -25.07 20.0 -1 300.0 -5.69 -25.11 20.0 -1 300.0 -5.52 -25.14 20.0 -1 300.0 -5.35 -25.18 20.0 -1 300.0 -5.2 -25.22 20.0 -1 300.0 -5.06 -25.26 20.0 -1 300.0 -4.93 -25.31 20.0 -1 300.0 -4.81 -25.36 20.0 -1 300.0 -4.71 -25.41 20.0 -1 300.0 -4.62 -25.46 20.0 -1 300.0 -4.55 -25.52 20.0 -1 300.0 -4.49 -25.58 20.0 -1 300.0 -4.44 -25.64 20.0 -1 300.0 -4.41 -25.71 20.0 -1 300.0 -4.39 -25.77 20.0 -1 300.0 -4.38 -25.84 20.0 -1 300.0 -4.39 -25.92 20.0 -1 300.0 -4.42 -25.99 20.0 -1 300.0 -4.45 -26.07 20.0 -1 300.0 -4.51 -26.15 20.0 -1 300.0 -4.57 -26.23 20.0 -1 300.0 -4.65 -26.32 20.0 -1 300.0 -4.75 -26.41 20.0 -1 300.0 -4.86 -26.5 20.0 -1 300.0 -4.98 -26.59 20.0 -1 300.0 -5.12 -26.68 20.0 -1 300.0 -5.27 -26.78 20.0 -1 300.0 -5.43 -26.87 20.0 -1 300.0 -5.8 -27.07 20.0 -1 300.0 -6.0 -27.18 20.0 -1 300.0 -6.22 -27.28 20.0 -1 300.0 -6.68 -27.5 20.0 -1 300.0 -7.75 -27.94 20.0 -1 300.0 -8.05 -28.06 20.0 -1 300.0 -8.35 -28.17 20.0 -1 300.0 -8.99 -28.41 20.0 -1 300.0 -10.36 -28.89 20.0 -1 300.0 -10.75 -29.02 20.0 -1 300.0 -11.15 -29.16 20.0 -1 300.0 -11.97 -29.43 20.0 -1 300.0 -13.66 -29.97 20.0 -1 300.0 -17.11 -31.07 20.0 -1 300.0 -17.54 -31.2 20.0 -1 300.0 -17.96 -31.34 20.0 -1 300.0 -18.79 -31.6 20.0 -1 300.0 -20.37 -32.13 20.0 -1 300.0 -20.75 -32.26 20.0 -1 300.0 -21.11 -32.38 20.0 -1 300.0 -21.82 -32.63 20.0 -1 300.0 -23.09 -33.11 20.0 -1 300.0 -23.38 -33.23 20.0 -1 300.0 -23.66 -33.34 20.0 -1 300.0 -24.16 -33.56 20.0 -1 300.0 -24.4 -33.67 20.0 -1 300.0 -24.61 -33.77 20.0 -1 300.0 -25.0 -33.97 20.0 -1 300.0 -25.18 -34.07 20.0 -1 300.0 -25.33 -34.17 20.0 -1 300.0 -25.47 -34.26 20.0 -1 300.0 -25.59 -34.35 20.0 -1 300.0 -25.7 -34.44 20.0 -1 300.0 -25.79 -34.52 20.0 -1 300.0 -25.86 -34.6 20.0 -1 300.0 -25.92 -34.68 20.0 -1 300.0 -25.96 -34.75 20.0 -1 300.0 -25.98 -34.83 20.0 -1 300.0 -25.99 -34.9 20.0 -1 300.0 -25.98 -34.96 20.0 -1 300.0 -25.95 -35.02 20.0 -1 300.0 -25.9 -35.08 20.0 -1 300.0 -25.84 -35.14 20.0 -1 300.0 -25.76 -35.19 20.0 -1 300.0 -25.67 -35.24 20.0 -1 300.0 -25.56 -35.28 20.0 -1 300.0 -25.43 -35.33 20.0 -1 300.0 -25.29 -35.36 20.0 -1 300.0 -25.13 -35.4 20.0 -1 300.0 -24.96 -35.43 20.0 -1 300.0 -24.78 -35.45 20.0 -1 300.0 -24.58 -35.48 20.0 -1 300.0 -24.37 -35.5 20.0 -1 300.0 -24.14 -35.51 20.0 -1 300.0 -23.91 -35.52 20.0 -1 300.0 -23.66 -35.53 20.0 -1 300.0 -23.4 -35.53 20.0 -1 300.0 -23.13 -35.53 20.0 -1 300.0 -22.85 -35.53 20.0 -1 300.0 -22.56 -35.52 20.0 -1 300.0 -22.26 -35.51 20.0 -1 300.0 -21.95 -35.49 20.0 -1 300.0 -21.64 -35.47 20.0 -1 300.0 -21.31 -35.45 20.0 -1 300.0 -20.98 -35.42 20.0 -1 300.0 -20.64 -35.38 20.0 -1 300.0 -20.3 -35.35 20.0 -1 300.0 -19.95 -35.31 20.0 -1 300.0 -19.59 -35.26 20.0 -1 300.0 -19.24 -35.21 20.0 -1 300.0 -18.88 -35.16 20.0 -1 300.0 -18.51 -35.1 20.0 -1 300.0 -18.14 -35.04 20.0 -1 300.0 -17.78 -34.97 20.0 -1 300.0 -17.04 -34.83 20.0 -1 300.0 -16.67 -34.75 20.0 -1 300.0 -16.31 -34.67 20.0 -1 300.0 -15.58 -34.49 20.0 -1 300.0 -15.22 -34.4 20.0 -1 300.0 -14.87 -34.3 20.0 -1 300.0 -14.17 -34.09 20.0 -1 300.0 -13.83 -33.98 20.0 -1 300.0 -13.5 -33.86 20.0 -1 300.0 -13.18 -33.74 20.0 -1 300.0 -12.86 -33.62 20.0 -1 300.0 -12.55 -33.49 20.0 -1 300.0 -12.25 -33.36 20.0 -1 300.0 -11.68 -33.08 20.0 -1 300.0 -11.4 -32.94 20.0 -1 300.0 -11.14 -32.79 20.0 -1 300.0 -10.9 -32.64 20.0 -1 300.0 -10.66 -32.48 20.0 -1 300.0 -10.44 -32.33 20.0 -1 300.0 -10.22 -32.16 20.0 -1 300.0 -10.03 -32.0 20.0 -1 300.0 -9.84 -31.83 20.0 -1 300.0 -9.67 -31.65 20.0 -1 300.0 -9.51 -31.48 20.0 -1 300.0 -9.37 -31.3 20.0 -1 300.0 -9.24 -31.11 20.0 -1 300.0 -9.13 -30.92 20.0 -1 300.0 -9.03 -30.73 20.0 -1 300.0 -8.95 -30.54 20.0 -1 300.0 -8.88 -30.34 20.0 -1 300.0 -8.84 -30.14 20.0 -1 300.0 -8.8 -29.93 20.0 -1 300.0 -8.78 -29.73 20.0 -1 300.0 -8.78 -29.52 20.0 -1 300.0 -8.79 -29.3 20.0 -1 300.0 -8.82 -29.09 20.0 -1 300.0 -8.87 -28.87 20.0 -1 300.0 -8.93 -28.64 20.0 -1 300.0 -9.01 -28.43 20.0 -1 300.0 -9.09 -28.22 20.0 -1 300.0 -9.19 -28.01 20.0 -1 300.0 -9.31 -27.79 20.0 -1 300.0 -9.44 -27.57 20.0 -1 300.0 -9.58 -27.35 20.0 -1 300.0 -9.9 -26.9 20.0 -1 300.0 -10.08 -26.68 20.0 -1 300.0 -10.27 -26.45 20.0 -1 300.0 -10.69 -25.98 20.0 -1 300.0 -10.92 -25.75 20.0 -1 300.0 -11.16 -25.51 20.0 -1 300.0 -11.68 -25.03 20.0 -1 300.0 -11.95 -24.79 20.0 -1 300.0 -12.23 -24.55 20.0 -1 300.0 -12.82 -24.06 20.0 -1 300.0 -14.11 -23.07 20.0 -1 300.0 -17.0 -21.04 20.0 -1 300.0 -17.38 -20.78 20.0 -1 300.0 -17.76 -20.52 20.0 -1 300.0 -18.53 -20.01 20.0 -1 300.0 -20.08 -18.98 20.0 -1 300.0 -20.46 -18.72 20.0 -1 300.0 -20.84 -18.46 20.0 -1 300.0 -21.6 -17.95 20.0 -1 300.0 -23.07 -16.93 20.0 -1 300.0 -23.43 -16.67 20.0 -1 300.0 -23.78 -16.42 20.0 -1 300.0 -24.45 -15.91 20.0 -1 300.0 -25.72 -14.91 20.0 -1 300.0 -26.01 -14.66 20.0 -1 300.0 -26.3 -14.42 20.0 -1 300.0 -26.83 -13.93 20.0 -1 300.0 -27.09 -13.69 20.0 -1 300.0 -27.33 -13.45 20.0 -1 300.0 -27.78 -12.97 20.0 -1 300.0 -28.0 -12.71 20.0 -1 300.0 -28.21 -12.46 20.0 -1 300.0 -28.4 -12.21 20.0 -1 300.0 -28.58 -11.96 20.0 -1 300.0 -28.75 -11.71 20.0 -1 300.0 -28.89 -11.47 20.0 -1 300.0 -29.03 -11.23 20.0 -1 300.0 -29.14 -10.99 20.0 -1 300.0 -29.24 -10.75 20.0 -1 300.0 -29.32 -10.51 20.0 -1 300.0 -29.39 -10.28 20.0 -1 300.0 -29.44 -10.05 20.0 -1 300.0 -29.48 -9.82 20.0 -1 300.0 -29.49 -9.6 20.0 -1 300.0 -29.49 -9.38 20.0 -1 300.0 -29.48 -9.16 20.0 -1 300.0 -29.44 -8.95 20.0 -1 300.0 -29.39 -8.73 20.0 -1 300.0 -29.32 -8.53 20.0 -1 300.0 -29.24 -8.32 20.0 -1 300.0 -29.14 -8.12 20.0 -1 300.0 -29.03 -7.92 20.0 -1 300.0 -28.9 -7.72 20.0 -1 300.0 -28.75 -7.53 20.0 -1 300.0 -28.59 -7.34 20.0 -1 300.0 -28.42 -7.16 20.0 -1 300.0 -28.23 -6.97 20.0 -1 300.0 -28.02 -6.8 20.0 -1 300.0 -27.8 -6.62 20.0 -1 300.0 -27.57 -6.45 20.0 -1 300.0 -27.07 -6.12 20.0 -1 300.0 -26.8 -5.96 20.0 -1 300.0 -26.52 -5.8 20.0 -1 300.0 -25.93 -5.5 20.0 -1 300.0 -25.62 -5.36 20.0 -1 300.0 -25.3 -5.22 20.0 -1 300.0 -24.63 -4.95 20.0 -1 300.0 -24.28 -4.82 20.0 -1 300.0 -23.93 -4.69 20.0 -1 300.0 -23.21 -4.46 20.0 -1 300.0 -22.84 -4.34 20.0 -1 300.0 -22.46 -4.24 20.0 -1 300.0 -21.71 -4.03 20.0 -1 300.0 -21.32 -3.94 20.0 -1 300.0 -20.94 -3.84 20.0 -1 300.0 -20.17 -3.67 20.0 -1 300.0 -19.79 -3.59 20.0 -1 300.0 -19.4 -3.52 20.0 -1 300.0 -18.64 -3.38 20.0 -1 300.0 -18.27 -3.31 20.0 -1 300.0 -17.89 -3.25 20.0 -1 300.0 -17.53 -3.2 20.0 -1 300.0 -17.16 -3.15 20.0 -1 300.0 -16.81 -3.1 20.0 -1 300.0 -16.46 -3.06 20.0 -1 300.0 -16.12 -3.02 20.0 -1 300.0 -15.78 -2.98 20.0 -1 300.0 -15.48 -2.95 20.0 -1 300.0 -15.18 -2.92 20.0 -1 300.0 -14.89 -2.9 20.0 -1 300.0 -14.61 -2.88 20.0 -1 300.0 -14.34 -2.87 20.0 -1 300.0 -14.08 -2.85 20.0 -1 300.0 -13.83 -2.85 20.0 -1 300.0 -13.59 -2.84 20.0 -1 300.0 -13.36 -2.84 20.0 -1 300.0 -13.14 -2.84 20.0 -1 300.0 -12.93 -2.84 20.0 -1 300.0 -12.73 -2.85 20.0 -1 300.0 -12.55 -2.86 20.0 -1 300.0 -12.38 -2.87 20.0 -1 300.0 -12.22 -2.89 20.0 -1 300.0 -12.07 -2.91 20.0 -1 300.0 -11.94 -2.93 20.0 -1 300.0 -11.82 -2.96 20.0 -1 300.0 -11.72 -2.98 20.0 -1 300.0 -11.63 -3.01 20.0 -1 300.0 -11.55 -3.05 20.0 -1 300.0 -11.48 -3.08 20.0 -1 300.0 -11.44 -3.12 20.0 -1 300.0 -11.4 -3.17 20.0 -1 300.0 -11.38 -3.21 20.0 -1 300.0 -11.37 -3.26 20.0 -1 300.0 -11.38 -3.31 20.0 -1 300.0 -11.4 -3.36 20.0 -1 300.0 -11.44 -3.42 20.0 -1 300.0 -11.49 -3.47 20.0 -1 300.0 -11.56 -3.53 20.0 -1 300.0 -11.64 -3.59 20.0 -1 300.0 -11.73 -3.66 20.0 -1 300.0 -11.84 -3.72 20.0 -1 300.0 -11.96 -3.79 20.0 -1 300.0 -12.09 -3.86 20.0 -1 300.0 -12.24 -3.94 20.0 -1 300.0 -12.4 -4.01 20.0 -1 300.0 -12.77 -4.17 20.0 -1 300.0 -12.97 -4.25 20.0 -1 300.0 -13.18 -4.33 20.0 -1 300.0 -13.64 -4.5 20.0 -1 300.0 -14.69 -4.85 20.0 -1 300.0 -14.98 -4.94 20.0 -1 300.0 -15.28 -5.04 20.0 -1 300.0 -15.9 -5.22 20.0 -1 300.0 -17.23 -5.62 20.0 -1 300.0 -20.15 -6.43 20.0 -1 300.0 -20.52 -6.53 20.0 -1 300.0 -20.89 -6.63 20.0 -1 300.0 -21.63 -6.84 20.0 -1 300.0 -23.11 -7.24 20.0 -1 300.0 -25.89 -8.03 20.0 -1 300.0 -26.22 -8.12 20.0 -1 300.0 -26.54 -8.22 20.0 -1 300.0 -27.14 -8.4 20.0 -1 300.0 -28.26 -8.76 20.0 -1 300.0 -28.51 -8.85 20.0 -1 300.0 -28.76 -8.93 20.0 -1 300.0 -29.21 -9.1 20.0 -1 300.0 -29.43 -9.18 20.0 -1 300.0 -29.62 -9.25 20.0 -1 300.0 -29.99 -9.4 20.0 -1 300.0 -30.15 -9.48 20.0 -1 300.0 -30.3 -9.55 20.0 -1 300.0 -30.43 -9.62 20.0 -1 300.0 -30.56 -9.68 20.0 -1 300.0 -30.67 -9.75 20.0 -1 300.0 -30.77 -9.81 20.0 -1 300.0 -30.85 -9.87 20.0 -1 300.0 -30.92 -9.93 20.0 -1 300.0 -30.97 -9.99 20.0 -1 300.0 -31.02 -10.04 20.0 -1 300.0 -31.04 -10.09 20.0 -1 300.0 -31.06 -10.14 20.0 -1 300.0 -31.06 -10.19 20.0 -1 300.0 -31.04 -10.23 20.0 -1 300.0 -31.02 -10.27 20.0 -1 300.0 -30.97 -10.31 20.0 -1 300.0 -30.92 -10.35 20.0 -1 300.0 -30.85 -10.38 20.0 -1 300.0 -30.76 -10.41 20.0 -1 300.0 -30.67 -10.44 20.0 -1 300.0 -30.56 -10.47 20.0 -1 300.0 -30.43 -10.49 20.0 -1 300.0 -30.3 -10.51 20.0 -1 300.0 -30.15 -10.53 20.0 -1 300.0 -29.98 -10.54 20.0 -1 300.0 -29.81 -10.55 20.0 -1 300.0 -29.62 -10.56 20.0 -1 300.0 -29.42 -10.56 20.0 -1 300.0 -29.21 -10.56 20.0 -1 300.0 -28.99 -10.56 20.0 -1 300.0 -28.76 -10.56 20.0 -1 300.0 -28.52 -10.55 20.0 -1 300.0 -28.24 -10.54 20.0 -1 300.0 -27.95 -10.52 20.0 -1 300.0 -27.66 -10.5 20.0 -1 300.0 -27.35 -10.48 20.0 -1 300.0 -27.03 -10.45 20.0 -1 300.0 -26.7 -10.42 20.0 -1 300.0 -26.37 -10.38 20.0 -1 300.0 -26.02 -10.34 20.0 -1 300.0 -25.67 -10.3 20.0 -1 300.0 -25.31 -10.25 20.0 -1 300.0 -24.57 -10.15 20.0 -1 300.0 -24.19 -10.09 20.0 -1 300.0 -23.81 -10.02 20.0 -1 300.0 -23.03 -9.88 20.0 -1 300.0 -22.64 -9.81 20.0 -1 300.0 -22.25 -9.73 20.0 -1 300.0 -21.45 -9.56 20.0 -1 300.0 -21.06 -9.46 20.0 -1 300.0 -20.66 -9.37 20.0 -1 300.0 -19.88 -9.16 20.0 -1 300.0 -19.49 -9.05 20.0 -1 300.0 -19.1 -8.94 20.0 -1 300.0 -18.34 -8.7 20.0 -1 300.0 -17.97 -8.58 20.0 -1 300.0 -17.61 -8.45 20.0 -1 300.0 -16.9 -8.18 20.0 -1 300.0 -16.55 -8.04 20.0 -1 300.0 -16.22 -7.89 20.0 -1 300.0 -15.57 -7.59 20.0 -1 300.0 -15.27 -7.44 20.0 -1 300.0 -14.97 -7.28 20.0 -1 300.0 -14.41 -6.95 20.0 -1 300.0 -14.15 -6.77 20.0 -1 300.0 -13.9 -6.6 20.0 -1 300.0 -13.67 -6.42 20.0 -1 300.0 -13.45 -6.24 20.0 -1 300.0 -13.24 -6.05 20.0 -1 300.0 -13.04 -5.86 20.0 -1 300.0 -12.86 -5.67 20.0 -1 300.0 -12.7 -5.47 20.0 -1 300.0 -12.55 -5.27 20.0 -1 300.0 -12.41 -5.07 20.0 -1 300.0 -12.29 -4.86 20.0 -1 300.0 -12.19 -4.65 20.0 -1 300.0 -12.1 -4.44 20.0 -1 300.0 -12.03 -4.22 20.0 -1 300.0 -11.97 -4.0 20.0 -1 300.0 -11.94 -3.78 20.0 -1 300.0 -11.91 -3.56 20.0 -1 300.0 -11.9 -3.33 20.0 -1 300.0 -11.91 -3.1 20.0 -1 300.0 -11.94 -2.86 20.0 -1 300.0 -11.98 -2.63 20.0 -1 300.0 -12.04 -2.39 20.0 -1 300.0 -12.11 -2.14 20.0 -1 300.0 -12.2 -1.9 20.0 -1 300.0 -12.3 -1.67 20.0 -1 300.0 -12.41 -1.44 20.0 -1 300.0 -12.54 -1.2 20.0 -1 300.0 -12.68 -0.96 20.0 -1 300.0 -12.83 -0.73 20.0 -1 300.0 -12.99 -0.49 20.0 -1 300.0 -13.36 0.0 20.0 -1 300.0 -13.55 0.25 20.0 -1 300.0 -13.77 0.49 20.0 -1 300.0 -14.23 0.99 20.0 -1 300.0 -15.27 2.01 20.0 -1 300.0 -15.55 2.27 20.0 -1 300.0 -15.84 2.52 20.0 -1 300.0 -16.45 3.04 20.0 -1 300.0 -17.75 4.09 20.0 -1 300.0 -20.57 6.22 20.0 -1 300.0 -20.93 6.49 20.0 -1 300.0 -21.3 6.75 20.0 -1 300.0 -22.02 7.29 20.0 -1 300.0 -23.46 8.35 20.0 -1 300.0 -23.81 8.62 20.0 -1 300.0 -24.15 8.88 20.0 -1 300.0 -24.84 9.41 20.0 -1 300.0 -26.13 10.46 20.0 -1 300.0 -26.43 10.72 20.0 -1 300.0 -26.73 10.97 20.0 -1 300.0 -27.3 11.49 20.0 -1 300.0 -27.57 11.74 20.0 -1 300.0 -27.83 12.0 20.0 -1 300.0 -28.32 12.5 20.0 -1 300.0 -28.55 12.75 20.0 -1 300.0 -28.77 13.0 20.0 -1 300.0 -28.98 13.24 20.0 -1 300.0 -29.17 13.49 20.0 -1 300.0 -29.36 13.73 20.0 -1 300.0 -29.53 13.97 20.0 -1 300.0 -29.69 14.21 20.0 -1 300.0 -29.83 14.45 20.0 -1 300.0 -29.97 14.7 20.0 -1 300.0 -30.1 14.95 20.0 -1 300.0 -30.21 15.2 20.0 -1 300.0 -30.31 15.45 20.0 -1 300.0 -30.39 15.69 20.0 -1 300.0 -30.45 15.94 20.0 -1 300.0 -30.49 16.18 20.0 -1 300.0 -30.52 16.41 20.0 -1 300.0 -30.53 16.64 20.0 -1 300.0 -30.53 16.87 20.0 -1 300.0 -30.5 17.1 20.0 -1 300.0 -30.47 17.33 20.0 -1 300.0 -30.41 17.55 20.0 -1 300.0 -30.34 17.77 20.0 -1 300.0 -30.25 17.98 20.0 -1 300.0 -30.14 18.19 20.0 -1 300.0 -30.02 18.4 20.0 -1 300.0 -29.88 18.6 20.0 -1 300.0 -29.73 18.8 20.0 -1 300.0 -29.56 19.0 20.0 -1 300.0 -29.38 19.2 20.0 -1 300.0 -29.18 19.39 20.0 -1 300.0 -28.96 19.57 20.0 -1 300.0 -28.73 19.76 20.0 -1 300.0 -28.49 19.93 20.0 -1 300.0 -28.23 20.11 20.0 -1 300.0 -27.96 20.28 20.0 -1 300.0 -27.68 20.45 20.0 -1 300.0 -27.39 20.61 20.0 -1 300.0 -27.08 20.77 20.0 -1 300.0 -26.43 21.08 20.0 -1 300.0 -26.1 21.23 20.0 -1 300.0 -25.75 21.37 20.0 -1 300.0 -25.02 21.65 20.0 -1 300.0 -24.65 21.78 20.0 -1 300.0 -24.27 21.91 20.0 -1 300.0 -23.49 22.15 20.0 -1 300.0 -23.09 22.26 20.0 -1 300.0 -22.69 22.38 20.0 -1 300.0 -21.88 22.58 20.0 -1 300.0 -21.47 22.68 20.0 -1 300.0 -21.05 22.77 20.0 -1 300.0 -20.22 22.95 20.0 -1 300.0 -19.81 23.03 20.0 -1 300.0 -19.4 23.11 20.0 -1 300.0 -18.57 23.25 20.0 -1 300.0 -18.17 23.31 20.0 -1 300.0 -17.77 23.37 20.0 -1 300.0 -16.98 23.48 20.0 -1 300.0 -16.59 23.52 20.0 -1 300.0 -16.21 23.57 20.0 -1 300.0 -15.84 23.61 20.0 -1 300.0 -15.47 23.64 20.0 -1 300.0 -15.12 23.67 20.0 -1 300.0 -14.77 23.7 20.0 -1 300.0 -14.43 23.72 20.0 -1 300.0 -14.1 23.74 20.0 -1 300.0 -13.79 23.75 20.0 -1 300.0 -13.49 23.76 20.0 -1 300.0 -13.2 23.77 20.0 -1 300.0 -12.92 23.77 20.0 -1 300.0 -12.66 23.77 20.0 -1 300.0 -12.4 23.77 20.0 -1 300.0 -12.16 23.76 20.0 -1 300.0 -11.94 23.75 20.0 -1 300.0 -11.72 23.73 20.0 -1 300.0 -11.53 23.71 20.0 -1 300.0 -11.34 23.69 20.0 -1 300.0 -11.17 23.66 20.0 -1 300.0 -11.02 23.63 20.0 -1 300.0 -10.88 23.6 20.0 -1 300.0 -10.75 23.56 20.0 -1 300.0 -10.64 23.52 20.0 -1 300.0 -10.55 23.48 20.0 -1 300.0 -10.47 23.43 20.0 -1 300.0 -10.41 23.39 20.0 -1 300.0 -10.37 23.33 20.0 -1 300.0 -10.34 23.28 20.0 -1 300.0 -10.32 23.22 20.0 -1 300.0 -10.33 23.16 20.0 -1 300.0 -10.34 23.1 20.0 -1 300.0 -10.38 23.03 20.0 -1 300.0 -10.43 22.96 20.0 -1 300.0 -10.5 22.89 20.0 -1 300.0 -10.58 22.82 20.0 -1 300.0 -10.68 22.74 20.0 -1 300.0 -10.79 22.66 20.0 -1 300.0 -10.92 22.58 20.0 -1 300.0 -11.06 22.49 20.0 -1 300.0 -11.22 22.41 20.0 -1 300.0 -11.39 22.32 20.0 -1 300.0 -11.77 22.14 20.0 -1 300.0 -11.98 22.04 20.0 -1 300.0 -12.21 21.95 20.0 -1 300.0 -12.7 21.75 20.0 -1 300.0 -12.96 21.64 20.0 -1 300.0 -13.23 21.54 20.0 -1 300.0 -13.81 21.33 20.0 -1 300.0 -15.07 20.89 20.0 -1 300.0 -15.4 20.78 20.0 -1 300.0 -15.74 20.67 20.0 -1 300.0 -16.44 20.44 20.0 -1 300.0 -17.9 19.98 20.0 -1 300.0 -20.87 19.04 20.0 -1 300.0 -21.21 18.93 20.0 -1 300.0 -21.55 18.82 20.0 -1 300.0 -22.21 18.6 20.0 -1 300.0 -23.47 18.17 20.0 -1 300.0 -23.77 18.07 20.0 -1 300.0 -24.07 17.96 20.0 -1 300.0 -24.63 17.76 20.0 -1 300.0 -25.65 17.36 20.0 -1 300.0 -25.88 17.27 20.0 -1 300.0 -26.1 17.17 20.0 -1 300.0 -26.51 16.98 20.0 -1 300.0 -26.7 16.89 20.0 -1 300.0 -26.87 16.8 20.0 -1 300.0 -27.18 16.63 20.0 -1 300.0 -27.32 16.55 20.0 -1 300.0 -27.45 16.46 20.0 -1 300.0 -27.56 16.39 20.0 -1 300.0 -27.66 16.31 20.0 -1 300.0 -27.74 16.23 20.0 -1 300.0 -27.82 16.16 20.0 -1 300.0 -27.87 16.08 20.0 -1 300.0 -27.92 16.01 20.0 -1 300.0 -27.95 15.95 20.0 -1 300.0 -27.96 15.88 20.0 -1 300.0 -27.96 15.82 20.0 -1 300.0 -27.95 15.76 20.0 -1 300.0 -27.93 15.7 20.0 -1 300.0 -27.89 15.64 20.0 -1 300.0 -27.83 15.59 20.0 -1 300.0 -27.76 15.54 20.0 -1 300.0 -27.68 15.49 20.0 -1 300.0 -27.59 15.44 20.0 -1 300.0 -27.48 15.4 20.0 -1 300.0 -27.35 15.36 20.0 -1 300.0 -27.21 15.32 20.0 -1 300.0 -27.06 15.29 20.0 -1 300.0 -26.9 15.25 20.0 -1 300.0 -26.72 15.22 20.0 -1 300.0 -26.53 15.2 20.0 -1 300.0 -26.33 15.17 20.0 -1 300.0 -26.12 15.15 20.0 -1 300.0 -25.89 15.14 20.0 -1 300.0 -25.65 15.12 20.0 -1 300.0 -25.41 15.11 20.0 -1 300.0 -25.14 15.1 20.0 -1 300.0 -24.88 15.1 20.0 -1 300.0 -24.59 15.1 20.0 -1 300.0 -24.3 15.1 20.0 -1 300.0 -24.0 15.1 20.0 -1 300.0 -23.69 15.11 20.0 -1 300.0 -23.38 15.12 20.0 -1 300.0 -23.05 15.13 20.0 -1 300.0 -22.72 15.15 20.0 -1 300.0 -22.38 15.17 20.0 -1 300.0 -22.0 15.2 20.0 -1 300.0 -21.61 15.23 20.0 -1 300.0 -21.22 15.26 20.0 -1 300.0 -20.82 15.3 20.0 -1 300.0 -20.42 15.34 20.0 -1 300.0 -20.01 15.38 20.0 -1 300.0 -19.18 15.49 20.0 -1 300.0 -18.76 15.55 20.0 -1 300.0 -18.34 15.61 20.0 -1 300.0 -17.49 15.74 20.0 -1 300.0 -17.07 15.82 20.0 -1 300.0 -16.64 15.9 20.0 -1 300.0 -15.8 16.06 20.0 -1 300.0 -15.38 16.15 20.0 -1 300.0 -14.97 16.25 20.0 -1 300.0 -14.15 16.45 20.0 -1 300.0 -13.75 16.55 20.0 -1 300.0 -13.35 16.66 20.0 -1 300.0 -12.58 16.89 20.0 -1 300.0 -12.21 17.02 20.0 -1 300.0 -11.84 17.14 20.0 -1 300.0 -11.14 17.41 20.0 -1 300.0 -10.8 17.54 20.0 -1 300.0 -10.48 17.68 20.0 -1 300.0 -9.86 17.98 20.0 -1 300.0 -9.57 18.13 20.0 -1 300.0 -9.29 18.28 20.0 -1 300.0 -9.02 18.44 20.0 -1 300.0 -8.77 18.6 20.0 -1 300.0 -8.53 18.77 20.0 -1 300.0 -8.3 18.94 20.0 -1 300.0 -8.09 19.11 20.0 -1 300.0 -7.9 19.29 20.0 -1 300.0 -7.72 19.47 20.0 -1 300.0 -7.55 19.65 20.0 -1 300.0 -7.4 19.84 20.0 -1 300.0 -7.27 20.03 20.0 -1 300.0 -7.15 20.22 20.0 -1 300.0 -7.05 20.42 20.0 -1 300.0 -6.96 20.62 20.0 -1 300.0 -6.89 20.82 20.0 -1 300.0 -6.84 21.02 20.0 -1 300.0 -6.81 21.23 20.0 -1 300.0 -6.79 21.44 20.0 -1 300.0 -6.78 21.65 20.0 -1 300.0 -6.8 21.87 20.0 -1 300.0 -6.83 22.09 20.0 -1 300.0 -6.87 22.31 20.0 -1 300.0 -6.93 22.53 20.0 -1 300.0 -7.01 22.76 20.0 -1 300.0 -7.1 22.99 20.0 -1 300.0 -7.21 23.22 20.0 -1 300.0 -7.34 23.45 20.0 -1 300.0 -7.48 23.68 20.0 -1 300.0 -7.63 23.92 20.0 -1 300.0 -7.98 24.4 20.0 -1 300.0 -8.16 24.63 20.0 -1 300.0 -8.36 24.86 20.0 -1 300.0 -8.78 25.32 20.0 -1 300.0 -9.75 26.25 20.0 -1 300.0 -10.02 26.49 20.0 -1 300.0 -10.29 26.73 20.0 -1 300.0 -10.86 27.2 20.0 -1 300.0 -12.09 28.17 20.0 -1 300.0 -12.41 28.41 20.0 -1 300.0 -12.73 28.66 20.0 -1 300.0 -13.39 29.14 20.0 -1 300.0 -14.75 30.12 20.0 -1 300.0 -17.46 32.08 20.0 -1 300.0 -17.79 32.32 20.0 -1 300.0 -18.11 32.56 20.0 -1 300.0 -18.74 33.04 20.0 -1 300.0 -19.93 33.99 20.0 -1 300.0 -20.21 34.23 20.0 -1 300.0 -20.48 34.46 20.0 -1 300.0 -21.0 34.93 20.0 -1 300.0 -21.24 35.16 20.0 -1 300.0 -21.47 35.39 20.0 -1 300.0 -21.91 35.84 20.0 -1 300.0 -22.11 36.06 20.0 -1 300.0 -22.3 36.28 20.0 -1 300.0 -22.48 36.51 20.0 -1 300.0 -22.65 36.72 20.0 -1 300.0 -22.8 36.94 20.0 -1 300.0 -22.94 37.16 20.0 -1 300.0 -23.07 37.37 20.0 -1 300.0 -23.18 37.58 20.0 -1 300.0 -23.29 37.79 20.0 -1 300.0 -23.37 37.99 20.0 -1 300.0 -23.45 38.2 20.0 -1 300.0 -23.51 38.4 20.0 -1 300.0 -23.55 38.6 20.0 -1 300.0 -23.59 38.8 20.0 -1 300.0 -23.6 38.99 20.0 -1 300.0 -23.61 39.18 20.0 -1 300.0 -23.59 39.39 20.0 -1 300.0 -23.56 39.59 20.0 -1 300.0 -23.52 39.79 20.0 -1 300.0 -23.45 39.98 20.0 -1 300.0 -23.37 40.17 20.0 -1 300.0 -23.27 40.36 20.0 -1 300.0 -23.16 40.55 20.0 -1 300.0 -23.03 40.73 20.0 -1 300.0 -22.88 40.91 20.0 -1 300.0 -22.72 41.09 20.0 -1 300.0 -22.54 41.26 20.0 -1 300.0 -22.34 41.42 20.0 -1 300.0 -22.13 41.59 20.0 -1 300.0 -21.91 41.75 20.0 -1 300.0 -21.67 41.91 20.0 -1 300.0 -21.41 42.06 20.0 -1 300.0 -21.14 42.21 20.0 -1 300.0 -20.86 42.35 20.0 -1 300.0 -20.57 42.49 20.0 -1 300.0 -20.26 42.63 20.0 -1 300.0 -19.94 42.76 20.0 -1 300.0 -19.6 42.89 20.0 -1 300.0 -18.91 43.14 20.0 -1 300.0 -18.54 43.25 20.0 -1 300.0 -18.17 43.37 20.0 -1 300.0 -17.79 43.47 20.0 -1 300.0 -17.39 43.58 20.0 -1 300.0 -17.0 43.68 20.0 -1 300.0 -16.59 43.77 20.0 -1 300.0 -15.76 43.95 20.0 -1 300.0 -15.34 44.03 20.0 -1 300.0 -14.91 44.11 20.0 -1 300.0 -14.48 44.18 20.0 -1 300.0 -14.04 44.25 20.0 -1 300.0 -13.61 44.32 20.0 -1 300.0 -13.17 44.38 20.0 -1 300.0 -12.29 44.49 20.0 -1 300.0 -11.85 44.53 20.0 -1 300.0 -11.41 44.58 20.0 -1 300.0 -10.98 44.62 20.0 -1 300.0 -10.55 44.65 20.0 -1 300.0 -10.12 44.68 20.0 -1 300.0 -9.69 44.7 20.0 -1 300.0 -9.27 44.73 20.0 -1 300.0 -8.86 44.74 20.0 -1 300.0 -8.45 44.76 20.0 -1 300.0 -8.04 44.76 20.0 -1 300.0 -7.65 44.77 20.0 -1 300.0 -7.26 44.77 20.0 -1 300.0 -6.88 44.76 20.0 -1 300.0 -6.52 44.75 20.0 -1 300.0 -6.16 44.74 20.0 -1 300.0 -5.81 44.72 20.0 -1 300.0 -5.47 44.7 20.0 -1 300.0 -5.14 44.68 20.0 -1 300.0 -4.83 44.65 20.0 -1 300.0 -4.53 44.61 20.0 -1 300.0 -4.24 44.58 20.0 -1 300.0 -3.96 44.53 20.0 -1 300.0 -3.7 44.49 20.0 -1 300.0 -3.46 44.44 20.0 -1 300.0 -3.23 44.39 20.0 -1 300.0 -3.01 44.33 20.0 -1 300.0 -2.81 44.27 20.0 -1 300.0 -2.63 44.21 20.0 -1 300.0 -2.46 44.14 20.0 -1 300.0 -2.31 44.07 20.0 -1 300.0 -2.17 44.0 20.0 -1 300.0 -2.04 43.92 20.0 -1 300.0 -1.94 43.84 20.0 -1 300.0 -1.85 43.76 20.0 -1 300.0 -1.77 43.67 20.0 -1 300.0 -1.72 43.59 20.0 -1 300.0 -1.67 43.49 20.0 -1 300.0 -1.65 43.4 20.0 -1 300.0 -1.64 43.3 20.0 -1 300.0 -1.65 43.2 20.0 -1 300.0 -1.67 43.09 20.0 -1 300.0 -1.71 42.99 20.0 -1 300.0 -1.76 42.88 20.0 -1 300.0 -1.83 42.77 20.0 -1 300.0 -1.92 42.65 20.0 -1 300.0 -2.02 42.53 20.0 -1 300.0 -2.13 42.41 20.0 -1 300.0 -2.27 42.29 20.0 -1 300.0 -2.41 42.17 20.0 -1 300.0 -2.57 42.04 20.0 -1 300.0 -2.93 41.78 20.0 -1 300.0 -3.13 41.65 20.0 -1 300.0 -3.35 41.51 20.0 -1 300.0 -3.81 41.23 20.0 -1 300.0 -4.06 41.09 20.0 -1 300.0 -4.32 40.95 20.0 -1 300.0 -4.87 40.66 20.0 -1 300.0 -6.08 40.07 20.0 -1 300.0 -8.79 38.84 20.0 -1 300.0 -9.14 38.68 20.0 -1 300.0 -9.49 38.53 20.0 -1 300.0 -10.21 38.21 20.0 -1 300.0 -11.61 37.58 20.0 -1 300.0 -14.21 36.34 20.0 -1 300.0 -14.49 36.2 20.0 -1 300.0 -14.76 36.06 20.0 -1 300.0 -15.26 35.78 20.0 -1 300.0 -15.5 35.65 20.0 -1 300.0 -15.73 35.51 20.0 -1 300.0 -16.16 35.24 20.0 -1 300.0 -16.36 35.11 20.0 -1 300.0 -16.55 34.98 20.0 -1 300.0 -16.73 34.84 20.0 -1 300.0 -16.89 34.72 20.0 -1 300.0 -17.05 34.59 20.0 -1 300.0 -17.19 34.47 20.0 -1 300.0 -17.32 34.34 20.0 -1 300.0 -17.43 34.22 20.0 -1 300.0 -17.54 34.1 20.0 -1 300.0 -17.63 33.98 20.0 -1 300.0 -17.7 33.87 20.0 -1 300.0 -17.76 33.75 20.0 -1 300.0 -17.81 33.64 20.0 -1 300.0 -17.85 33.53 20.0 -1 300.0 -17.87 33.42 20.0 -1 300.0 -17.88 33.31 20.0 -1 300.0 -17.87 33.21 20.0 -1 300.0 -17.84 33.11 20.0 -1 300.0 -17.81 33.01 20.0 -1 300.0 -17.76 32.91 20.0 -1 300.0 -17.7 32.82 20.0 -1 300.0 -17.62 32.73 20.0 -1 300.0 -17.52 32.64 20.0 -1 300.0 -17.42 32.55 20.0 -1 300.0 -17.3 32.47 20.0 -1 300.0 -17.16 32.39 20.0 -1 300.0 -17.01 32.31 20.0 -1 300.0 -16.85 32.23 20.0 -1 300.0 -16.68 32.16 20.0 -1 300.0 -16.49 32.09 20.0 -1 300.0 -16.29 32.02 20.0 -1 300.0 -16.07 31.96 20.0 -1 300.0 -15.85 31.89 20.0 -1 300.0 -15.61 31.84 20.0 -1 300.0 -15.36 31.78 20.0 -1 300.0 -15.1 31.73 20.0 -1 300.0 -14.83 31.68 20.0 -1 300.0 -14.54 31.63 20.0 -1 300.0 -14.25 31.59 20.0 -1 300.0 -13.95 31.55 20.0 -1 300.0 -13.63 31.51 20.0 -1 300.0 -13.31 31.48 20.0 -1 300.0 -12.98 31.44 20.0 -1 300.0 -12.64 31.42 20.0 -1 300.0 -12.29 31.39 20.0 -1 300.0 -11.93 31.37 20.0 -1 300.0 -11.57 31.35 20.0 -1 300.0 -11.2 31.34 20.0 -1 300.0 -10.82 31.33 20.0 -1 300.0 -10.44 31.32 20.0 -1 300.0 -10.06 31.31 20.0 -1 300.0 -9.67 31.31 20.0 -1 300.0 -9.27 31.32 20.0 -1 300.0 -8.87 31.32 20.0 -1 300.0 -8.47 31.33 20.0 -1 300.0 -8.07 31.34 20.0 -1 300.0 -7.63 31.36 20.0 -1 300.0 -7.19 31.38 20.0 -1 300.0 -6.75 31.4 20.0 -1 300.0 -6.3 31.43 20.0 -1 300.0 -5.86 31.47 20.0 -1 300.0 -5.42 31.5 20.0 -1 300.0 -4.98 31.54 20.0 -1 300.0 -4.55 31.59 20.0 -1 300.0 -4.11 31.64 20.0 -1 300.0 -3.68 31.69 20.0 -1 300.0 -3.26 31.75 20.0 -1 300.0 -2.84 31.81 20.0 -1 300.0 -2.43 31.87 20.0 -1 300.0 -2.02 31.94 20.0 -1 300.0 -1.23 32.09 20.0 -1 300.0 -0.85 32.17 20.0 -1 300.0 -0.47 32.26 20.0 -1 300.0 -0.11 32.34 20.0 -1 300.0 0.24 32.43 20.0 -1 300.0 0.59 32.53 20.0 -1 300.0 0.92 32.63 20.0 -1 300.0 1.55 32.84 20.0 -1 300.0 1.84 32.95 20.0 -1 300.0 2.12 33.06 20.0 -1 300.0 2.39 33.18 20.0 -1 300.0 2.65 33.3 20.0 -1 300.0 2.89 33.42 20.0 -1 300.0 3.11 33.55 20.0 -1 300.0 3.32 33.68 20.0 -1 300.0 3.52 33.81 20.0 -1 300.0 3.7 33.95 20.0 -1 300.0 3.86 34.09 20.0 -1 300.0 4.01 34.24 20.0 -1 300.0 4.14 34.38 20.0 -1 300.0 4.26 34.53 20.0 -1 300.0 4.36 34.69 20.0 -1 300.0 4.44 34.84 20.0 -1 300.0 4.5 35.0 20.0 -1 300.0 4.55 35.16 20.0 -1 300.0 4.59 35.33 20.0 -1 300.0 4.6 35.49 20.0 -1 300.0 4.6 35.66 20.0 -1 300.0 4.58 35.83 20.0 -1 300.0 4.55 36.01 20.0 -1 300.0 4.5 36.19 20.0 -1 300.0 4.43 36.36 20.0 -1 300.0 4.35 36.55 20.0 -1 300.0 4.25 36.73 20.0 -1 300.0 4.14 36.92 20.0 -1 300.0 4.01 37.1 20.0 -1 300.0 3.87 37.29 20.0 -1 300.0 3.71 37.49 20.0 -1 300.0 3.36 37.88 20.0 -1 300.0 3.16 38.07 20.0 -1 300.0 2.94 38.27 20.0 -1 300.0 2.48 38.67 20.0 -1 300.0 1.43 39.5 20.0 -1 300.0 1.16 39.69 20.0 -1 300.0 0.88 39.88 20.0 -1 300.0 0.3 40.28 20.0 -1 300.0 -0.93 41.07 20.0 -1 300.0 -3.54 42.67 20.0 -1 300.0 -3.87 42.87 20.0 -1 300.0 -4.2 43.07 20.0 -1 300.0 -4.86 43.46 20.0 -1 300.0 -6.14 44.25 20.0 -1 300.0 -6.44 44.45 20.0 -1 300.0 -6.75 44.64 20.0 -1 300.0 -7.34 45.03 20.0 -1 300.0 -8.43 45.79 20.0 -1 300.0 -8.68 45.98 20.0 -1 300.0 -8.93 46.16 20.0 -1 300.0 -9.38 46.53 20.0 -1 300.0 -9.6 46.71 20.0 -1 300.0 -9.8 46.89 20.0 -1 300.0 -10.17 47.24 20.0 -1 300.0 -10.34 47.41 20.0 -1 300.0 -10.49 47.59 20.0 -1 300.0 -10.64 47.76 20.0 -1 300.0 -10.77 47.92 20.0 -1 300.0 -10.88 48.09 20.0 -1 300.0 -10.99 48.26 20.0 -1 300.0 -11.08 48.42 20.0 -1 300.0 -11.15 48.58 20.0 -1 300.0 -11.22 48.73 20.0 -1 300.0 -11.27 48.89 20.0 -1 300.0 -11.3 49.04 20.0 -1 300.0 -11.32 49.19 20.0 -1 300.0 -11.33 49.34 20.0 -1 300.0 -11.32 49.48 20.0 -1 300.0 -11.3 49.62 20.0 -1 300.0 -11.26 49.76 20.0 -1 300.0 -11.21 49.9 20.0 -1 300.0 -11.14 50.03 20.0 -1 300.0 -11.06 50.16 20.0 -1 300.0 -10.96 50.29 20.0 -1 300.0 -10.85 50.42 20.0 -1 300.0 -10.73 50.54 20.0 -1 300.0 -10.59 50.66 20.0 -1 300.0 -10.44 50.77 20.0 -1 300.0 -10.28 50.89 20.0 -1 300.0 -10.1 50.99 20.0 -1 300.0 -9.91 51.1 20.0 -1 300.0 -9.71 51.2 20.0 -1 300.0 -9.5 51.3 20.0 -1 300.0 -9.27 51.39 20.0 -1 300.0 -8.78 51.57 20.0 -1 300.0 -8.52 51.66 20.0 -1 300.0 -8.25 51.74 20.0 -1 300.0 -7.97 51.82 20.0 -1 300.0 -7.67 51.9 20.0 -1 300.0 -7.37 51.97 20.0 -1 300.0 -7.06 52.04 20.0 -1 300.0 -6.41 52.16 20.0 -1 300.0 -6.07 52.22 20.0 -1 300.0 -5.72 52.28 20.0 -1 300.0 -5.37 52.33 20.0 -1 300.0 -5.01 52.38 20.0 -1 300.0 -4.64 52.42 20.0 -1 300.0 -4.26 52.46 20.0 -1 300.0 -3.89 52.5 20.0 -1 300.0 -3.5 52.53 20.0 -1 300.0 -3.11 52.56 20.0 -1 300.0 -2.72 52.59 20.0 -1 300.0 -2.32 52.61 20.0 -1 300.0 -1.92 52.63 20.0 -1 300.0 -1.52 52.65 20.0 -1 300.0 -1.12 52.66 20.0 -1 300.0 -0.71 52.67 20.0 -1 300.0 -0.3 52.67 20.0 -1 300.0 0.1 52.67 20.0 -1 300.0 0.51 52.67 20.0 -1 300.0 0.92 52.66 20.0 -1 300.0 1.32 52.65 20.0 -1 300.0 1.72 52.64 20.0 -1 300.0 2.13 52.62 20.0 -1 300.0 2.52 52.6 20.0 -1 300.0 2.92 52.58 20.0 -1 300.0 3.31 52.55 20.0 -1 300.0 3.7 52.52 20.0 -1 300.0 4.08 52.48 20.0 -1 300.0 4.46 52.44 20.0 -1 300.0 4.83 52.4 20.0 -1 300.0 5.19 52.35 20.0 -1 300.0 5.55 52.3 20.0 -1 300.0 5.9 52.25 20.0 -1 300.0 6.24 52.19 20.0 -1 300.0 6.58 52.13 20.0 -1 300.0 6.9 52.07 20.0 -1 300.0 7.22 52.0 20.0 -1 300.0 7.53 51.93 20.0 -1 300.0 7.82 51.86 20.0 -1 300.0 8.39 51.7 20.0 -1 300.0 8.66 51.62 20.0 -1 300.0 8.91 51.53 20.0 -1 300.0 9.15 51.44 20.0 -1 300.0 9.39 51.35 20.0 -1 300.0 9.61 51.25 20.0 -1 300.0 9.81 51.15 20.0 -1 300.0 10.01 51.05 20.0 -1 300.0 10.19 50.94 20.0 -1 300.0 10.37 50.82 20.0 -1 300.0 10.54 50.7 20.0 -1 300.0 10.69 50.57 20.0 -1 300.0 10.83 50.44 20.0 -1 300.0 10.95 50.31 20.0 -1 300.0 11.05 50.17 20.0 -1 300.0 11.14 50.04 20.0 -1 300.0 11.21 49.89 20.0 -1 300.0 11.26 49.75 20.0 -1 300.0 11.3 49.6 20.0 -1 300.0 11.32 49.45 20.0 -1 300.0 11.33 49.29 20.0 -1 300.0 11.32 49.14 20.0 -1 300.0 11.29 48.98 20.0 -1 300.0 11.24 48.81 20.0 -1 300.0 11.19 48.65 20.0 -1 300.0 11.11 48.48 20.0 -1 300.0 11.02 48.31 20.0 -1 300.0 10.91 48.13 20.0 -1 300.0 10.79 47.96 20.0 -1 300.0 10.65 47.78 20.0 -1 300.0 10.5 47.6 20.0 -1 300.0 10.16 47.23 20.0 -1 300.0 9.97 47.04 20.0 -1 300.0 9.76 46.85 20.0 -1 300.0 9.31 46.47 20.0 -1 300.0 8.28 45.68 20.0 -1 300.0 8.0 45.48 20.0 -1 300.0 7.71 45.28 20.0 -1 300.0 7.1 44.87 20.0 -1 300.0 5.8 44.04 20.0 -1 300.0 3.01 42.35 20.0 -1 300.0 2.66 42.14 20.0 -1 300.0 2.31 41.92 20.0 -1 300.0 1.62 41.5 20.0 -1 300.0 0.27 40.65 20.0 -1 300.0 -0.05 40.44 20.0 -1 300.0 -0.36 40.23 20.0 -1 300.0 -0.97 39.82 20.0 -1 300.0 -2.09 38.99 20.0 -1 300.0 -2.32 38.8 20.0 -1 300.0 -2.55 38.62 20.0 -1 300.0 -2.97 38.24 20.0 -1 300.0 -3.17 38.06 20.0 -1 300.0 -3.35 37.88 20.0 -1 300.0 -3.69 37.52 20.0 -1 300.0 -3.84 37.34 20.0 -1 300.0 -3.97 37.16 20.0 -1 300.0 -4.1 36.99 20.0 -1 300.0 -4.21 36.81 20.0 -1 300.0 -4.3 36.64 20.0 -1 300.0 -4.39 36.47 20.0 -1 300.0 -4.46 36.3 20.0 -1 300.0 -4.51 36.14 20.0 -1 300.0 -4.56 35.98 20.0 -1 300.0 -4.59 35.81 20.0 -1 300.0 -4.6 35.66 20.0 -1 300.0 -4.6 35.5 20.0 -1 300.0 -4.59 35.34 20.0 -1 300.0 -4.56 35.19 20.0 -1 300.0 -4.52 35.04 20.0 -1 300.0 -4.46 34.89 20.0 -1 300.0 -4.39 34.75 20.0 -1 300.0 -4.31 34.6 20.0 -1 300.0 -4.21 34.47 20.0 -1 300.0 -4.09 34.33 20.0 -1 300.0 -3.97 34.19 20.0 -1 300.0 -3.83 34.06 20.0 -1 300.0 -3.67 33.93 20.0 -1 300.0 -3.5 33.8 20.0 -1 300.0 -3.32 33.68 20.0 -1 300.0 -3.13 33.56 20.0 -1 300.0 -2.92 33.44 20.0 -1 300.0 -2.7 33.32 20.0 -1 300.0 -2.47 33.21 20.0 -1 300.0 -2.22 33.1 20.0 -1 300.0 -1.7 32.89 20.0 -1 300.0 -1.42 32.79 20.0 -1 300.0 -1.13 32.7 20.0 -1 300.0 -0.83 32.6 20.0 -1 300.0 -0.52 32.51 20.0 -1 300.0 -0.2 32.42 20.0 -1 300.0 0.13 32.34 20.0 -1 300.0 0.81 32.18 20.0 -1 300.0 1.17 32.1 20.0 -1 300.0 1.53 32.03 20.0 -1 300.0 1.9 31.96 20.0 -1 300.0 2.27 31.9 20.0 -1 300.0 2.65 31.84 20.0 -1 300.0 3.04 31.78 20.0 -1 300.0 3.82 31.67 20.0 -1 300.0 4.22 31.63 20.0 -1 300.0 4.62 31.58 20.0 -1 300.0 5.03 31.54 20.0 -1 300.0 5.43 31.5 20.0 -1 300.0 5.84 31.47 20.0 -1 300.0 6.25 31.44 20.0 -1 300.0 6.66 31.41 20.0 -1 300.0 7.07 31.39 20.0 -1 300.0 7.51 31.36 20.0 -1 300.0 7.96 31.34 20.0 -1 300.0 8.4 31.33 20.0 -1 300.0 8.84 31.32 20.0 -1 300.0 9.27 31.32 20.0 -1 300.0 9.7 31.31 20.0 -1 300.0 10.12 31.32 20.0 -1 300.0 10.54 31.32 20.0 -1 300.0 10.96 31.33 20.0 -1 300.0 11.36 31.34 20.0 -1 300.0 11.76 31.36 20.0 -1 300.0 12.15 31.38 20.0 -1 300.0 12.53 31.41 20.0 -1 300.0 12.91 31.44 20.0 -1 300.0 13.27 31.47 20.0 -1 300.0 13.62 31.51 20.0 -1 300.0 13.96 31.55 20.0 -1 300.0 14.29 31.59 20.0 -1 300.0 14.61 31.64 20.0 -1 300.0 14.92 31.69 20.0 -1 300.0 15.21 31.75 20.0 -1 300.0 15.49 31.81 20.0 -1 300.0 15.75 31.87 20.0 -1 300.0 16.0 31.94 20.0 -1 300.0 16.24 32.01 20.0 -1 300.0 16.46 32.08 20.0 -1 300.0 16.67 32.16 20.0 -1 300.0 16.86 32.23 20.0 -1 300.0 17.03 32.32 20.0 -1 300.0 17.19 32.4 20.0 -1 300.0 17.33 32.49 20.0 -1 300.0 17.46 32.59 20.0 -1 300.0 17.57 32.68 20.0 -1 300.0 17.66 32.78 20.0 -1 300.0 17.74 32.88 20.0 -1 300.0 17.8 32.99 20.0 -1 300.0 17.84 33.09 20.0 -1 300.0 17.87 33.2 20.0 -1 300.0 17.88 33.32 20.0 -1 300.0 17.87 33.43 20.0 -1 300.0 17.84 33.55 20.0 -1 300.0 17.8 33.67 20.0 -1 300.0 17.74 33.79 20.0 -1 300.0 17.67 33.92 20.0 -1 300.0 17.58 34.05 20.0 -1 300.0 17.47 34.17 20.0 -1 300.0 17.35 34.31 20.0 -1 300.0 17.21 34.44 20.0 -1 300.0 17.06 34.58 20.0 -1 300.0 16.9 34.72 20.0 -1 300.0 16.52 35.0 20.0 -1 300.0 16.31 35.14 20.0 -1 300.0 16.09 35.28 20.0 -1 300.0 15.61 35.58 20.0 -1 300.0 15.36 35.73 20.0 -1 300.0 15.09 35.88 20.0 -1 300.0 14.52 36.18 20.0 -1 300.0 13.28 36.81 20.0 -1 300.0 12.96 36.96 20.0 -1 300.0 12.63 37.12 20.0 -1 300.0 11.95 37.43 20.0 -1 300.0 10.56 38.05 20.0 -1 300.0 7.75 39.3 20.0 -1 300.0 7.4 39.46 20.0 -1 300.0 7.07 39.61 20.0 -1 300.0 6.41 39.91 20.0 -1 300.0 5.17 40.51 20.0 -1 300.0 4.88 40.66 20.0 -1 300.0 4.6 40.8 20.0 -1 300.0 4.07 41.09 20.0 -1 300.0 3.83 41.23 20.0 -1 300.0 3.59 41.37 20.0 -1 300.0 3.15 41.64 20.0 -1 300.0 2.95 41.77 20.0 -1 300.0 2.76 41.9 20.0 -1 300.0 2.58 42.03 20.0 -1 300.0 2.42 42.16 20.0 -1 300.0 2.28 42.28 20.0 -1 300.0 2.15 42.4 20.0 -1 300.0 2.03 42.52 20.0 -1 300.0 1.93 42.64 20.0 -1 300.0 1.84 42.75 20.0 -1 300.0 1.77 42.87 20.0 -1 300.0 1.71 42.98 20.0 -1 300.0 1.67 43.08 20.0 -1 300.0 1.65 43.19 20.0 -1 300.0 1.64 43.29 20.0 -1 300.0 1.65 43.39 20.0 -1 300.0 1.67 43.48 20.0 -1 300.0 1.71 43.58 20.0 -1 300.0 1.76 43.66 20.0 -1 300.0 1.84 43.75 20.0 -1 300.0 1.93 43.84 20.0 -1 300.0 2.03 43.91 20.0 -1 300.0 2.15 43.99 20.0 -1 300.0 2.29 44.06 20.0 -1 300.0 2.44 44.13 20.0 -1 300.0 2.6 44.2 20.0 -1 300.0 2.79 44.27 20.0 -1 300.0 2.98 44.32 20.0 -1 300.0 3.19 44.38 20.0 -1 300.0 3.42 44.43 20.0 -1 300.0 3.66 44.48 20.0 -1 300.0 3.92 44.53 20.0 -1 300.0 4.18 44.57 20.0 -1 300.0 4.44 44.6 20.0 -1 300.0 4.71 44.63 20.0 -1 300.0 5.0 44.66 20.0 -1 300.0 5.29 44.69 20.0 -1 300.0 5.59 44.71 20.0 -1 300.0 5.9 44.73 20.0 -1 300.0 6.22 44.74 20.0 -1 300.0 6.55 44.75 20.0 -1 300.0 6.89 44.76 20.0 -1 300.0 7.24 44.77 20.0 -1 300.0 7.59 44.77 20.0 -1 300.0 7.95 44.76 20.0 -1 300.0 8.31 44.76 20.0 -1 300.0 8.68 44.75 20.0 -1 300.0 9.06 44.73 20.0 -1 300.0 9.44 44.72 20.0 -1 300.0 9.83 44.7 20.0 -1 300.0 10.22 44.67 20.0 -1 300.0 10.61 44.64 20.0 -1 300.0 11.0 44.61 20.0 -1 300.0 11.4 44.58 20.0 -1 300.0 11.8 44.54 20.0 -1 300.0 12.6 44.45 20.0 -1 300.0 13.0 44.4 20.0 -1 300.0 13.4 44.35 20.0 -1 300.0 13.8 44.29 20.0 -1 300.0 14.2 44.23 20.0 -1 300.0 14.6 44.16 20.0 -1 300.0 14.99 44.1 20.0 -1 300.0 15.77 43.95 20.0 -1 300.0 16.15 43.87 20.0 -1 300.0 16.52 43.79 20.0 -1 300.0 17.26 43.61 20.0 -1 300.0 17.62 43.52 20.0 -1 300.0 17.98 43.42 20.0 -1 300.0 18.66 43.22 20.0 -1 300.0 18.99 43.11 20.0 -1 300.0 19.31 43.0 20.0 -1 300.0 19.63 42.88 20.0 -1 300.0 19.93 42.77 20.0 -1 300.0 20.22 42.65 20.0 -1 300.0 20.51 42.52 20.0 -1 300.0 21.04 42.26 20.0 -1 300.0 21.29 42.13 20.0 -1 300.0 21.53 41.99 20.0 -1 300.0 21.76 41.85 20.0 -1 300.0 21.97 41.7 20.0 -1 300.0 22.18 41.56 20.0 -1 300.0 22.37 41.41 20.0 -1 300.0 22.54 41.25 20.0 -1 300.0 22.71 41.1 20.0 -1 300.0 22.86 40.94 20.0 -1 300.0 23.0 40.77 20.0 -1 300.0 23.12 40.61 20.0 -1 300.0 23.23 40.44 20.0 -1 300.0 23.32 40.27 20.0 -1 300.0 23.41 40.09 20.0 -1 300.0 23.48 39.92 20.0 -1 300.0 23.53 39.74 20.0 -1 300.0 23.57 39.54 20.0 -1 300.0 23.6 39.34 20.0 -1 300.0 23.61 39.14 20.0 -1 300.0 23.6 38.93 20.0 -1 300.0 23.57 38.72 20.0 -1 300.0 23.53 38.51 20.0 -1 300.0 23.48 38.29 20.0 -1 300.0 23.4 38.08 20.0 -1 300.0 23.32 37.85 20.0 -1 300.0 23.21 37.63 20.0 -1 300.0 23.09 37.41 20.0 -1 300.0 22.95 37.18 20.0 -1 300.0 22.8 36.95 20.0 -1 300.0 22.64 36.72 20.0 -1 300.0 22.27 36.24 20.0 -1 300.0 22.06 36.01 20.0 -1 300.0 21.84 35.77 20.0 -1 300.0 21.36 35.28 20.0 -1 300.0 20.27 34.28 20.0 -1 300.0 19.98 34.03 20.0 -1 300.0 19.67 33.78 20.0 -1 300.0 19.03 33.27 20.0 -1 300.0 17.67 32.23 20.0 -1 300.0 17.32 31.97 20.0 -1 300.0 16.96 31.71 20.0 -1 300.0 16.24 31.19 20.0 -1 300.0 14.77 30.14 20.0 -1 300.0 14.4 29.88 20.0 -1 300.0 14.04 29.61 20.0 -1 300.0 13.32 29.09 20.0 -1 300.0 11.92 28.04 20.0 -1 300.0 11.59 27.78 20.0 -1 300.0 11.26 27.52 20.0 -1 300.0 10.63 27.01 20.0 -1 300.0 10.32 26.75 20.0 -1 300.0 10.03 26.5 20.0 -1 300.0 9.47 25.99 20.0 -1 300.0 9.2 25.74 20.0 -1 300.0 8.95 25.49 20.0 -1 300.0 8.48 24.99 20.0 -1 300.0 8.27 24.75 20.0 -1 300.0 8.06 24.5 20.0 -1 300.0 7.7 24.02 20.0 -1 300.0 7.55 23.8 20.0 -1 300.0 7.41 23.58 20.0 -1 300.0 7.29 23.36 20.0 -1 300.0 7.18 23.14 20.0 -1 300.0 7.08 22.93 20.0 -1 300.0 7.0 22.71 20.0 -1 300.0 6.92 22.5 20.0 -1 300.0 6.87 22.3 20.0 -1 300.0 6.83 22.09 20.0 -1 300.0 6.8 21.88 20.0 -1 300.0 6.78 21.68 20.0 -1 300.0 6.79 21.48 20.0 -1 300.0 6.8 21.29 20.0 -1 300.0 6.83 21.09 20.0 -1 300.0 6.87 20.9 20.0 -1 300.0 6.93 20.71 20.0 -1 300.0 7.0 20.52 20.0 -1 300.0 7.09 20.34 20.0 -1 300.0 7.19 20.15 20.0 -1 300.0 7.31 19.98 20.0 -1 300.0 7.43 19.8 20.0 -1 300.0 7.58 19.63 20.0 -1 300.0 7.73 19.45 20.0 -1 300.0 7.9 19.29 20.0 -1 300.0 8.09 19.12 20.0 -1 300.0 8.28 18.96 20.0 -1 300.0 8.49 18.8 20.0 -1 300.0 8.71 18.64 20.0 -1 300.0 8.94 18.49 20.0 -1 300.0 9.19 18.34 20.0 -1 300.0 9.71 18.05 20.0 -1 300.0 9.99 17.91 20.0 -1 300.0 10.28 17.77 20.0 -1 300.0 10.88 17.51 20.0 -1 300.0 11.2 17.38 20.0 -1 300.0 11.53 17.26 20.0 -1 300.0 12.2 17.02 20.0 -1 300.0 12.55 16.91 20.0 -1 300.0 12.91 16.8 20.0 -1 300.0 13.64 16.58 20.0 -1 300.0 14.01 16.48 20.0 -1 300.0 14.39 16.39 20.0 -1 300.0 15.16 16.2 20.0 -1 300.0 15.55 16.12 20.0 -1 300.0 15.94 16.04 20.0 -1 300.0 16.73 15.88 20.0 -1 300.0 17.13 15.81 20.0 -1 300.0 17.52 15.74 20.0 -1 300.0 18.32 15.61 20.0 -1 300.0 18.71 15.55 20.0 -1 300.0 19.1 15.5 20.0 -1 300.0 19.49 15.45 20.0 -1 300.0 19.88 15.4 20.0 -1 300.0 20.26 15.36 20.0 -1 300.0 20.64 15.32 20.0 -1 300.0 21.02 15.28 20.0 -1 300.0 21.39 15.24 20.0 -1 300.0 21.74 15.21 20.0 -1 300.0 22.09 15.19 20.0 -1 300.0 22.44 15.17 20.0 -1 300.0 22.78 15.15 20.0 -1 300.0 23.11 15.13 20.0 -1 300.0 23.43 15.12 20.0 -1 300.0 23.75 15.11 20.0 -1 300.0 24.05 15.1 20.0 -1 300.0 24.35 15.1 20.0 -1 300.0 24.64 15.1 20.0 -1 300.0 24.91 15.1 20.0 -1 300.0 25.18 15.1 20.0 -1 300.0 25.44 15.11 20.0 -1 300.0 25.68 15.12 20.0 -1 300.0 25.92 15.14 20.0 -1 300.0 26.14 15.16 20.0 -1 300.0 26.35 15.18 20.0 -1 300.0 26.55 15.2 20.0 -1 300.0 26.74 15.23 20.0 -1 300.0 26.91 15.26 20.0 -1 300.0 27.08 15.29 20.0 -1 300.0 27.23 15.32 20.0 -1 300.0 27.36 15.36 20.0 -1 300.0 27.48 15.4 20.0 -1 300.0 27.59 15.45 20.0 -1 300.0 27.69 15.49 20.0 -1 300.0 27.77 15.54 20.0 -1 300.0 27.84 15.59 20.0 -1 300.0 27.89 15.64 20.0 -1 300.0 27.93 15.7 20.0 -1 300.0 27.95 15.76 20.0 -1 300.0 27.96 15.82 20.0 -1 300.0 27.96 15.88 20.0 -1 300.0 27.95 15.95 20.0 -1 300.0 27.92 16.01 20.0 -1 300.0 27.87 16.08 20.0 -1 300.0 27.82 16.16 20.0 -1 300.0 27.74 16.23 20.0 -1 300.0 27.66 16.3 20.0 -1 300.0 27.56 16.38 20.0 -1 300.0 27.45 16.46 20.0 -1 300.0 27.33 16.54 20.0 -1 300.0 27.04 16.71 20.0 -1 300.0 26.88 16.8 20.0 -1 300.0 26.71 16.89 20.0 -1 300.0 26.33 17.07 20.0 -1 300.0 26.12 17.16 20.0 -1 300.0 25.9 17.26 20.0 -1 300.0 25.43 17.45 20.0 -1 300.0 24.39 17.85 20.0 -1 300.0 21.93 18.69 20.0 -1 300.0 21.57 18.81 20.0 -1 300.0 21.21 18.93 20.0 -1 300.0 20.47 19.16 20.0 -1 300.0 18.98 19.64 20.0 -1 300.0 16.04 20.57 20.0 -1 300.0 15.69 20.69 20.0 -1 300.0 15.35 20.8 20.0 -1 300.0 14.68 21.02 20.0 -1 300.0 13.46 21.46 20.0 -1 300.0 13.18 21.56 20.0 -1 300.0 12.9 21.67 20.0 -1 300.0 12.4 21.87 20.0 -1 300.0 12.16 21.97 20.0 -1 300.0 11.94 22.06 20.0 -1 300.0 11.53 22.25 20.0 -1 300.0 11.35 22.34 20.0 -1 300.0 11.18 22.43 20.0 -1 300.0 11.02 22.52 20.0 -1 300.0 10.88 22.6 20.0 -1 300.0 10.76 22.68 20.0 -1 300.0 10.65 22.76 20.0 -1 300.0 10.55 22.84 20.0 -1 300.0 10.48 22.91 20.0 -1 300.0 10.41 22.98 20.0 -1 300.0 10.37 23.05 20.0 -1 300.0 10.34 23.12 20.0 -1 300.0 10.32 23.18 20.0 -1 300.0 10.32 23.24 20.0 -1 300.0 10.34 23.3 20.0 -1 300.0 10.38 23.35 20.0 -1 300.0 10.43 23.4 20.0 -1 300.0 10.5 23.45 20.0 -1 300.0 10.58 23.5 20.0 -1 300.0 10.68 23.54 20.0 -1 300.0 10.79 23.58 20.0 -1 300.0 10.93 23.61 20.0 -1 300.0 11.07 23.64 20.0 -1 300.0 11.23 23.67 20.0 -1 300.0 11.41 23.7 20.0 -1 300.0 11.6 23.72 20.0 -1 300.0 11.81 23.74 20.0 -1 300.0 12.03 23.75 20.0 -1 300.0 12.26 23.76 20.0 -1 300.0 12.51 23.77 20.0 -1 300.0 12.77 23.77 20.0 -1 300.0 13.04 23.77 20.0 -1 300.0 13.32 23.77 20.0 -1 300.0 13.6 23.76 20.0 -1 300.0 13.89 23.75 20.0 -1 300.0 14.18 23.73 20.0 -1 300.0 14.49 23.72 20.0 -1 300.0 14.8 23.7 20.0 -1 300.0 15.12 23.67 20.0 -1 300.0 15.45 23.64 20.0 -1 300.0 15.78 23.61 20.0 -1 300.0 16.13 23.58 20.0 -1 300.0 16.48 23.54 20.0 -1 300.0 16.83 23.5 20.0 -1 300.0 17.19 23.45 20.0 -1 300.0 17.55 23.4 20.0 -1 300.0 17.92 23.35 20.0 -1 300.0 18.67 23.23 20.0 -1 300.0 19.05 23.17 20.0 -1 300.0 19.42 23.1 20.0 -1 300.0 20.19 22.96 20.0 -1 300.0 20.57 22.88 20.0 -1 300.0 20.95 22.8 20.0 -1 300.0 21.71 22.62 20.0 -1 300.0 22.09 22.53 20.0 -1 300.0 22.47 22.43 20.0 -1 300.0 23.21 22.23 20.0 -1 300.0 23.57 22.13 20.0 -1 300.0 23.93 22.02 20.0 -1 300.0 24.64 21.78 20.0 -1 300.0 24.98 21.66 20.0 -1 300.0 25.32 21.54 20.0 -1 300.0 25.98 21.28 20.0 -1 300.0 26.29 21.14 20.0 -1 300.0 26.6 21.01 20.0 -1 300.0 27.19 20.72 20.0 -1 300.0 27.46 20.57 20.0 -1 300.0 27.73 20.42 20.0 -1 300.0 27.99 20.26 20.0 -1 300.0 28.24 20.11 20.0 -1 300.0 28.48 19.94 20.0 -1 300.0 28.7 19.78 20.0 -1 300.0 29.12 19.44 20.0 -1 300.0 29.3 19.27 20.0 -1 300.0 29.48 19.09 20.0 -1 300.0 29.64 18.91 20.0 -1 300.0 29.79 18.72 20.0 -1 300.0 29.93 18.54 20.0 -1 300.0 30.05 18.35 20.0 -1 300.0 30.16 18.16 20.0 -1 300.0 30.26 17.96 20.0 -1 300.0 30.34 17.76 20.0 -1 300.0 30.41 17.56 20.0 -1 300.0 30.46 17.36 20.0 -1 300.0 30.5 17.15 20.0 -1 300.0 30.52 16.94 20.0 -1 300.0 30.53 16.73 20.0 -1 300.0 30.53 16.52 20.0 -1 300.0 30.51 16.3 20.0 -1 300.0 30.47 16.07 20.0 -1 300.0 30.42 15.83 20.0 -1 300.0 30.35 15.58 20.0 -1 300.0 30.27 15.34 20.0 -1 300.0 30.16 15.09 20.0 -1 300.0 30.05 14.84 20.0 -1 300.0 29.91 14.59 20.0 -1 300.0 29.76 14.33 20.0 -1 300.0 29.6 14.07 20.0 -1 300.0 29.42 13.81 20.0 -1 300.0 29.01 13.29 20.0 -1 300.0 28.79 13.02 20.0 -1 300.0 28.55 12.75 20.0 -1 300.0 28.04 12.21 20.0 -1 300.0 27.77 11.94 20.0 -1 300.0 27.48 11.66 20.0 -1 300.0 26.88 11.11 20.0 -1 300.0 25.55 9.98 20.0 -1 300.0 22.57 7.69 20.0 -1 300.0 22.18 7.41 20.0 -1 300.0 21.79 7.12 20.0 -1 300.0 21.0 6.54 20.0 -1 300.0 19.44 5.38 20.0 -1 300.0 19.06 5.09 20.0 -1 300.0 18.68 4.81 20.0 -1 300.0 17.93 4.23 20.0 -1 300.0 16.51 3.1 20.0 -1 300.0 16.18 2.81 20.0 -1 300.0 15.85 2.53 20.0 -1 300.0 15.23 1.97 20.0 -1 300.0 14.93 1.7 20.0 -1 300.0 14.65 1.42 20.0 -1 300.0 14.12 0.88 20.0 -1 300.0 13.87 0.61 20.0 -1 300.0 13.63 0.34 20.0 -1 300.0 13.41 0.07 20.0 -1 300.0 13.2 -0.19 20.0 -1 300.0 13.01 -0.46 20.0 -1 300.0 12.83 -0.72 20.0 -1 300.0 12.67 -0.98 20.0 -1 300.0 12.52 -1.23 20.0 -1 300.0 12.39 -1.47 20.0 -1 300.0 12.28 -1.7 20.0 -1 300.0 12.19 -1.94 20.0 -1 300.0 12.11 -2.17 20.0 -1 300.0 12.04 -2.4 20.0 -1 300.0 11.98 -2.62 20.0 -1 300.0 11.94 -2.84 20.0 -1 300.0 11.92 -3.06 20.0 -1 300.0 11.9 -3.28 20.0 -1 300.0 11.91 -3.5 20.0 -1 300.0 11.93 -3.71 20.0 -1 300.0 11.96 -3.92 20.0 -1 300.0 12.01 -4.13 20.0 -1 300.0 12.07 -4.34 20.0 -1 300.0 12.14 -4.54 20.0 -1 300.0 12.23 -4.74 20.0 -1 300.0 12.34 -4.94 20.0 -1 300.0 12.45 -5.13 20.0 -1 300.0 12.58 -5.32 20.0 -1 300.0 12.73 -5.51 20.0 -1 300.0 12.89 -5.7 20.0 -1 300.0 13.06 -5.88 20.0 -1 300.0 13.24 -6.05 20.0 -1 300.0 13.44 -6.23 20.0 -1 300.0 13.65 -6.4 20.0 -1 300.0 13.87 -6.57 20.0 -1 300.0 14.1 -6.74 20.0 -1 300.0 14.35 -6.9 20.0 -1 300.0 14.6 -7.06 20.0 -1 300.0 14.86 -7.22 20.0 -1 300.0 15.42 -7.52 20.0 -1 300.0 15.72 -7.66 20.0 -1 300.0 16.02 -7.81 20.0 -1 300.0 16.65 -8.08 20.0 -1 300.0 16.98 -8.21 20.0 -1 300.0 17.31 -8.34 20.0 -1 300.0 17.99 -8.59 20.0 -1 300.0 18.34 -8.7 20.0 -1 300.0 18.7 -8.82 20.0 -1 300.0 19.42 -9.04 20.0 -1 300.0 20.9 -9.43 20.0 -1 300.0 21.28 -9.52 20.0 -1 300.0 21.65 -9.6 20.0 -1 300.0 22.4 -9.76 20.0 -1 300.0 22.77 -9.83 20.0 -1 300.0 23.14 -9.9 20.0 -1 300.0 23.87 -10.03 20.0 -1 300.0 24.23 -10.09 20.0 -1 300.0 24.58 -10.15 20.0 -1 300.0 24.94 -10.2 20.0 -1 300.0 25.28 -10.25 20.0 -1 300.0 25.62 -10.29 20.0 -1 300.0 25.96 -10.34 20.0 -1 300.0 26.6 -10.41 20.0 -1 300.0 26.91 -10.44 20.0 -1 300.0 27.21 -10.46 20.0 -1 300.0 27.5 -10.49 20.0 -1 300.0 27.78 -10.51 20.0 -1 300.0 28.05 -10.53 20.0 -1 300.0 28.31 -10.54 20.0 -1 300.0 28.57 -10.55 20.0 -1 300.0 28.81 -10.56 20.0 -1 300.0 29.04 -10.56 20.0 -1 300.0 29.26 -10.56 20.0 -1 300.0 29.47 -10.56 20.0 -1 300.0 29.66 -10.56 20.0 -1 300.0 29.85 -10.55 20.0 -1 300.0 30.02 -10.54 20.0 -1 300.0 30.18 -10.52 20.0 -1 300.0 30.33 -10.5 20.0 -1 300.0 30.46 -10.48 20.0 -1 300.0 30.58 -10.46 20.0 -1 300.0 30.69 -10.44 20.0 -1 300.0 30.78 -10.41 20.0 -1 300.0 30.86 -10.37 20.0 -1 300.0 30.93 -10.34 20.0 -1 300.0 30.98 -10.3 20.0 -1 300.0 31.02 -10.26 20.0 -1 300.0 31.05 -10.22 20.0 -1 300.0 31.06 -10.18 20.0 -1 300.0 31.05 -10.13 20.0 -1 300.0 31.04 -10.08 20.0 -1 300.0 31.01 -10.03 20.0 -1 300.0 30.96 -9.97 20.0 -1 300.0 30.9 -9.91 20.0 -1 300.0 30.83 -9.86 20.0 -1 300.0 30.74 -9.79 20.0 -1 300.0 30.64 -9.73 20.0 -1 300.0 30.52 -9.66 20.0 -1 300.0 30.4 -9.6 20.0 -1 300.0 30.25 -9.53 20.0 -1 300.0 30.1 -9.46 20.0 -1 300.0 29.75 -9.31 20.0 -1 300.0 29.56 -9.23 20.0 -1 300.0 29.36 -9.15 20.0 -1 300.0 28.92 -8.99 20.0 -1 300.0 27.9 -8.64 20.0 -1 300.0 27.62 -8.55 20.0 -1 300.0 27.34 -8.46 20.0 -1 300.0 26.73 -8.28 20.0 -1 300.0 25.44 -7.9 20.0 -1 300.0 22.59 -7.1 20.0 -1 300.0 22.19 -6.99 20.0 -1 300.0 21.79 -6.88 20.0 -1 300.0 20.98 -6.66 20.0 -1 300.0 19.37 -6.22 20.0 -1 300.0 18.98 -6.11 20.0 -1 300.0 18.58 -6.0 20.0 -1 300.0 17.81 -5.78 20.0 -1 300.0 16.35 -5.36 20.0 -1 300.0 16.0 -5.26 20.0 -1 300.0 15.66 -5.16 20.0 -1 300.0 15.02 -4.95 20.0 -1 300.0 14.71 -4.86 20.0 -1 300.0 14.41 -4.76 20.0 -1 300.0 13.85 -4.57 20.0 -1 300.0 13.59 -4.48 20.0 -1 300.0 13.34 -4.39 20.0 -1 300.0 12.88 -4.21 20.0 -1 300.0 12.68 -4.13 20.0 -1 300.0 12.48 -4.04 20.0 -1 300.0 12.14 -3.89 20.0 -1 300.0 11.99 -3.81 20.0 -1 300.0 11.86 -3.74 20.0 -1 300.0 11.74 -3.67 20.0 -1 300.0 11.64 -3.6 20.0 -1 300.0 11.55 -3.53 20.0 -1 300.0 11.49 -3.47 20.0 -1 300.0 11.43 -3.41 20.0 -1 300.0 11.4 -3.35 20.0 -1 300.0 11.38 -3.29 20.0 -1 300.0 11.37 -3.24 20.0 -1 300.0 11.39 -3.19 20.0 -1 300.0 11.41 -3.15 20.0 -1 300.0 11.46 -3.1 20.0 -1 300.0 11.52 -3.06 20.0 -1 300.0 11.6 -3.02 20.0 -1 300.0 11.69 -2.99 20.0 -1 300.0 11.8 -2.96 20.0 -1 300.0 11.93 -2.93 20.0 -1 300.0 12.07 -2.91 20.0 -1 300.0 12.22 -2.89 20.0 -1 300.0 12.39 -2.87 20.0 -1 300.0 12.58 -2.86 20.0 -1 300.0 12.78 -2.85 20.0 -1 300.0 12.99 -2.84 20.0 -1 300.0 13.21 -2.84 20.0 -1 300.0 13.45 -2.84 20.0 -1 300.0 13.7 -2.84 20.0 -1 300.0 13.97 -2.85 20.0 -1 300.0 14.24 -2.86 20.0 -1 300.0 14.53 -2.88 20.0 -1 300.0 14.82 -2.9 20.0 -1 300.0 15.13 -2.92 20.0 -1 300.0 15.43 -2.95 20.0 -1 300.0 15.73 -2.98 20.0 -1 300.0 16.04 -3.01 20.0 -1 300.0 16.35 -3.04 20.0 -1 300.0 16.68 -3.08 20.0 -1 300.0 17.0 -3.12 20.0 -1 300.0 17.68 -3.22 20.0 -1 300.0 18.02 -3.27 20.0 -1 300.0 18.37 -3.33 20.0 -1 300.0 19.07 -3.45 20.0 -1 300.0 19.43 -3.52 20.0 -1 300.0 19.78 -3.59 20.0 -1 300.0 20.5 -3.74 20.0 -1 300.0 20.86 -3.82 20.0 -1 300.0 21.21 -3.91 20.0 -1 300.0 21.93 -4.09 20.0 -1 300.0 22.28 -4.18 20.0 -1 300.0 22.63 -4.28 20.0 -1 300.0 23.31 -4.49 20.0 -1 300.0 23.65 -4.6 20.0 -1 300.0 23.98 -4.71 20.0 -1 300.0 24.63 -4.95 20.0 -1 300.0 24.95 -5.07 20.0 -1 300.0 25.25 -5.2 20.0 -1 300.0 25.85 -5.46 20.0 -1 300.0 26.13 -5.6 20.0 -1 300.0 26.4 -5.74 20.0 -1 300.0 26.67 -5.88 20.0 -1 300.0 26.93 -6.03 20.0 -1 300.0 27.17 -6.18 20.0 -1 300.0 27.41 -6.33 20.0 -1 300.0 27.84 -6.65 20.0 -1 300.0 28.04 -6.81 20.0 -1 300.0 28.23 -6.98 20.0 -1 300.0 28.41 -7.15 20.0 -1 300.0 28.57 -7.32 20.0 -1 300.0 28.73 -7.5 20.0 -1 300.0 28.86 -7.67 20.0 -1 300.0 28.99 -7.86 20.0 -1 300.0 29.1 -8.04 20.0 -1 300.0 29.2 -8.23 20.0 -1 300.0 29.28 -8.42 20.0 -1 300.0 29.35 -8.61 20.0 -1 300.0 29.41 -8.8 20.0 -1 300.0 29.45 -9.0 20.0 -1 300.0 29.48 -9.2 20.0 -1 300.0 29.49 -9.41 20.0 -1 300.0 29.49 -9.61 20.0 -1 300.0 29.48 -9.82 20.0 -1 300.0 29.45 -10.03 20.0 -1 300.0 29.4 -10.24 20.0 -1 300.0 29.34 -10.46 20.0 -1 300.0 29.27 -10.68 20.0 -1 300.0 29.18 -10.9 20.0 -1 300.0 29.08 -11.12 20.0 -1 300.0 28.96 -11.34 20.0 -1 300.0 28.82 -11.59 20.0 -1 300.0 28.67 -11.84 20.0 -1 300.0 28.49 -12.09 20.0 -1 300.0 28.3 -12.34 20.0 -1 300.0 28.1 -12.59 20.0 -1 300.0 27.88 -12.85 20.0 -1 300.0 27.4 -13.37 20.0 -1 300.0 27.14 -13.63 20.0 -1 300.0 26.87 -13.9 20.0 -1 300.0 26.28 -14.43 20.0 -1 300.0 24.97 -15.51 20.0 -1 300.0 24.61 -15.79 20.0 -1 300.0 24.25 -16.06 20.0 -1 300.0 23.5 -16.62 20.0 -1 300.0 21.92 -17.73 20.0 -1 300.0 18.57 -19.98 20.0 -1 300.0 18.15 -20.27 20.0 -1 300.0 17.73 -20.55 20.0 -1 300.0 16.9 -21.11 20.0 -1 300.0 15.29 -22.22 20.0 -1 300.0 14.9 -22.5 20.0 -1 300.0 14.52 -22.77 20.0 -1 300.0 13.78 -23.32 20.0 -1 300.0 12.41 -24.4 20.0 -1 300.0 12.1 -24.67 20.0 -1 300.0 11.79 -24.93 20.0 -1 300.0 11.22 -25.45 20.0 -1 300.0 10.96 -25.71 20.0 -1 300.0 10.71 -25.97 20.0 -1 300.0 10.25 -26.48 20.0 -1 300.0 10.04 -26.73 20.0 -1 300.0 9.85 -26.97 20.0 -1 300.0 9.67 -27.22 20.0 -1 300.0 9.51 -27.46 20.0 -1 300.0 9.36 -27.7 20.0 -1 300.0 9.23 -27.94 20.0 -1 300.0 9.12 -28.18 20.0 -1 300.0 9.02 -28.41 20.0 -1 300.0 8.94 -28.63 20.0 -1 300.0 8.87 -28.86 20.0 -1 300.0 8.83 -29.07 20.0 -1 300.0 8.8 -29.29 20.0 -1 300.0 8.78 -29.5 20.0 -1 300.0 8.78 -29.72 20.0 -1 300.0 8.8 -29.92 20.0 -1 300.0 8.83 -30.13 20.0 -1 300.0 8.88 -30.33 20.0 -1 300.0 8.95 -30.53 20.0 -1 300.0 9.03 -30.72 20.0 -1 300.0 9.13 -30.91 20.0 -1 300.0 9.24 -31.1 20.0 -1 300.0 9.36 -31.29 20.0 -1 300.0 9.51 -31.47 20.0 -1 300.0 9.66 -31.64 20.0 -1 300.0 9.83 -31.82 20.0 -1 300.0 10.02 -31.99 20.0 -1 300.0 10.21 -32.16 20.0 -1 300.0 10.43 -32.32 20.0 -1 300.0 10.65 -32.48 20.0 -1 300.0 10.88 -32.63 20.0 -1 300.0 11.39 -32.93 20.0 -1 300.0 11.66 -33.08 20.0 -1 300.0 11.95 -33.22 20.0 -1 300.0 12.54 -33.48 20.0 -1 300.0 12.85 -33.61 20.0 -1 300.0 13.16 -33.73 20.0 -1 300.0 13.82 -33.97 20.0 -1 300.0 14.16 -34.08 20.0 -1 300.0 14.5 -34.19 20.0 -1 300.0 15.21 -34.39 20.0 -1 300.0 15.57 -34.49 20.0 -1 300.0 15.93 -34.58 20.0 -1 300.0 16.66 -34.75 20.0 -1 300.0 17.03 -34.83 20.0 -1 300.0 17.4 -34.9 20.0 -1 300.0 17.77 -34.97 20.0 -1 300.0 18.13 -35.04 20.0 -1 300.0 18.5 -35.1 20.0 -1 300.0 18.86 -35.16 20.0 -1 300.0 19.59 -35.26 20.0 -1 300.0 19.94 -35.3 20.0 -1 300.0 20.29 -35.35 20.0 -1 300.0 20.63 -35.38 20.0 -1 300.0 20.97 -35.42 20.0 -1 300.0 21.3 -35.44 20.0 -1 300.0 21.63 -35.47 20.0 -1 300.0 21.95 -35.49 20.0 -1 300.0 22.26 -35.51 20.0 -1 300.0 22.56 -35.52 20.0 -1 300.0 22.85 -35.53 20.0 -1 300.0 23.13 -35.53 20.0 -1 300.0 23.4 -35.53 20.0 -1 300.0 23.66 -35.53 20.0 -1 300.0 23.9 -35.52 20.0 -1 300.0 24.14 -35.51 20.0 -1 300.0 24.36 -35.5 20.0 -1 300.0 24.56 -35.48 20.0 -1 300.0 24.75 -35.46 20.0 -1 300.0 24.92 -35.44 20.0 -1 300.0 25.08 -35.41 20.0 -1 300.0 25.23 -35.38 20.0 -1 300.0 25.36 -35.34 20.0 -1 300.0 25.49 -35.31 20.0 -1 300.0 25.6 -35.27 20.0 -1 300.0 25.69 -35.23 20.0 -1 300.0 25.78 -35.18 20.0 -1 300.0 25.85 -35.13 20.0 -1 300.0 25.9 -35.08 20.0 -1 300.0 25.94 -35.03 20.0 -1 300.0 25.97 -34.97 20.0 -1 300.0 25.99 -34.91 20.0 -1 300.0 25.99 -34.85 20.0 -1 300.0 25.97 -34.78 20.0 -1 300.0 25.94 -34.72 20.0 -1 300.0 25.9 -34.65 20.0 -1 300.0 25.84 -34.58 20.0 -1 300.0 25.77 -34.5 20.0 -1 300.0 25.68 -34.42 20.0 -1 300.0 25.59 -34.34 20.0 -1 300.0 25.47 -34.26 20.0 -1 300.0 25.34 -34.17 20.0 -1 300.0 25.2 -34.09 20.0 -1 300.0 24.88 -33.91 20.0 -1 300.0 24.7 -33.81 20.0 -1 300.0 24.51 -33.72 20.0 -1 300.0 24.09 -33.52 20.0 -1 300.0 23.86 -33.42 20.0 -1 300.0 23.61 -33.32 20.0 -1 300.0 23.09 -33.11 20.0 -1 300.0 21.93 -32.67 20.0 -1 300.0 19.2 -31.74 20.0 -1 300.0 12.95 -29.75 20.0 -1 300.0 12.53 -29.61 20.0 -1 300.0 12.12 -29.48 20.0 -1 300.0 11.3 -29.21 20.0 -1 300.0 9.75 -28.68 20.0 -1 300.0 9.38 -28.55 20.0 -1 300.0 9.03 -28.42 20.0 -1 300.0 8.34 -28.17 20.0 -1 300.0 7.1 -27.68 20.0 -1 300.0 6.83 -27.56 20.0 -1 300.0 6.56 -27.44 20.0 -1 300.0 6.07 -27.21 20.0 -1 300.0 5.85 -27.1 20.0 -1 300.0 5.64 -26.99 20.0 -1 300.0 5.27 -26.78 20.0 -1 300.0 5.11 -26.68 20.0 -1 300.0 4.96 -26.58 20.0 -1 300.0 4.83 -26.48 20.0 -1 300.0 4.72 -26.38 20.0 -1 300.0 4.62 -26.29 20.0 -1 300.0 4.54 -26.2 20.0 -1 300.0 4.48 -26.11 20.0 -1 300.0 4.43 -26.03 20.0 -1 300.0 4.4 -25.94 20.0 -1 300.0 4.38 -25.86 20.0 -1 300.0 4.38 -25.79 20.0 -1 300.0 4.4 -25.71 20.0 -1 300.0 4.44 -25.64 20.0 -1 300.0 4.49 -25.58 20.0 -1 300.0 4.56 -25.51 20.0 -1 300.0 4.64 -25.45 20.0 -1 300.0 4.74 -25.39 20.0 -1 300.0 4.85 -25.34 20.0 -1 300.0 4.98 -25.29 20.0 -1 300.0 5.13 -25.24 20.0 -1 300.0 5.29 -25.19 20.0 -1 300.0 5.46 -25.15 20.0 -1 300.0 5.65 -25.11 20.0 -1 300.0 5.85 -25.08 20.0 -1 300.0 6.06 -25.05 20.0 -1 300.0 6.29 -25.02 20.0 -1 300.0 6.53 -25.0 20.0 -1 300.0 6.78 -24.98 20.0 -1 300.0 7.04 -24.96 20.0 -1 300.0 7.31 -24.95 20.0 -1 300.0 7.6 -24.94 20.0 -1 300.0 7.89 -24.94 20.0 -1 300.0 8.19 -24.94 20.0 -1 300.0 8.5 -24.94 20.0 -1 300.0 8.82 -24.95 20.0 -1 300.0 9.15 -24.96 20.0 -1 300.0 9.48 -24.98 20.0 -1 300.0 9.82 -24.99 20.0 -1 300.0 10.16 -25.02 20.0 -1 300.0 10.51 -25.04 20.0 -1 300.0 10.84 -25.07 20.0 -1 300.0 11.17 -25.1 20.0 -1 300.0 11.51 -25.14 20.0 -1 300.0 11.84 -25.18 20.0 -1 300.0 12.18 -25.22 20.0 -1 300.0 12.52 -25.27 20.0 -1 300.0 13.2 -25.37 20.0 -1 300.0 13.53 -25.43 20.0 -1 300.0 13.87 -25.49 20.0 -1 300.0 14.2 -25.55 20.0 -1 300.0 14.54 -25.62 20.0 -1 300.0 14.86 -25.69 20.0 -1 300.0 15.19 -25.76 20.0 -1 300.0 15.82 -25.92 20.0 -1 300.0 16.13 -26.0 20.0 -1 300.0 16.44 -26.09 20.0 -1 300.0 16.74 -26.18 20.0 -1 300.0 17.03 -26.28 20.0 -1 300.0 17.31 -26.38 20.0 -1 300.0 17.59 -26.48 20.0 -1 300.0 18.11 -26.69 20.0 -1 300.0 18.36 -26.8 20.0 -1 300.0 18.6 -26.91 20.0 -1 300.0 18.83 -27.03 20.0 -1 300.0 19.05 -27.15 20.0 -1 300.0 19.26 -27.28 20.0 -1 300.0 19.46 -27.4 20.0 -1 300.0 19.64 -27.53 20.0 -1 300.0 19.82 -27.67 20.0 -1 300.0 19.98 -27.8 20.0 -1 300.0 20.13 -27.94 20.0 -1 300.0 20.26 -28.09 20.0 -1 300.0 20.39 -28.23 20.0 -1 300.0 20.5 -28.38 20.0 -1 300.0 20.59 -28.53 20.0 -1 300.0 20.68 -28.68 20.0 -1 300.0 20.75 -28.84 20.0 -1 300.0 20.8 -29.0 20.0 -1 300.0 20.84 -29.16 20.0 -1 300.0 20.87 -29.33 20.0 -1 300.0 20.88 -29.49 20.0 -1 300.0 20.88 -29.66 20.0 -1 300.0 20.86 -29.84 20.0 -1 300.0 20.83 -30.01 20.0 -1 300.0 20.78 -30.19 20.0 -1 300.0 20.72 -30.37 20.0 -1 300.0 20.64 -30.55 20.0 -1 300.0 20.56 -30.73 20.0 -1 300.0 20.45 -30.92 20.0 -1 300.0 20.33 -31.11 20.0 -1 300.0 20.2 -31.3 20.0 -1 300.0 20.05 -31.49 20.0 -1 300.0 19.89 -31.69 20.0 -1 300.0 19.72 -31.89 20.0 -1 300.0 19.53 -32.08 20.0 -1 300.0 19.12 -32.49 20.0 -1 300.0 18.89 -32.69 20.0 -1 300.0 18.66 -32.9 20.0 -1 300.0 18.14 -33.31 20.0 -1 300.0 17.87 -33.52 20.0 -1 300.0 17.59 -33.72 20.0 -1 300.0 17.01 -34.14 20.0 -1 300.0 15.72 -34.99 20.0 -1 300.0 12.8 -36.73 20.0 -1 300.0 12.41 -36.95 20.0 -1 300.0 12.02 -37.17 20.0 -1 300.0 11.22 -37.61 20.0 -1 300.0 9.62 -38.49 20.0 -1 300.0 6.46 -40.24 20.0 -1 300.0 6.07 -40.45 20.0 -1 300.0 5.7 -40.67 20.0 -1 300.0 4.96 -41.1 20.0 -1 300.0 3.57 -41.94 20.0 -1 300.0 3.24 -42.15 20.0 -1 300.0 2.92 -42.36 20.0 -1 300.0 2.3 -42.77 20.0 -1 300.0 1.19 -43.57 20.0 -1 300.0 0.94 -43.76 20.0 -1 300.0 0.71 -43.96 20.0 -1 300.0 0.26 -44.34 20.0 -1 300.0 0.06 -44.53 20.0 -1 300.0 -0.13 -44.72 20.0 -1 300.0 -0.47 -45.09 20.0 -1 300.0 -0.62 -45.27 20.0 -1 300.0 -0.76 -45.44 20.0 -1 300.0 -0.88 -45.62 20.0 -1 300.0 -0.99 -45.79 20.0 -1 300.0 -1.09 -45.97 20.0 -1 300.0 -1.17 -46.13 20.0 -1 300.0 -1.24 -46.3 20.0 -1 300.0 -1.3 -46.47 20.0 -1 300.0 -1.34 -46.64 20.0 -1 300.0 -1.37 -46.81 20.0 -1 300.0 -1.38 -46.98 20.0 -1 300.0 -1.38 -47.15 20.0 -1 300.0 -1.36 -47.31 20.0 -1 300.0 -1.32 -47.47 20.0 -1 300.0 -1.27 -47.62 20.0 -1 300.0 -1.2 -47.77 20.0 -1 300.0 -1.11 -47.92 20.0 -1 300.0 -1.01 -48.07 20.0 -1 300.0 -0.9 -48.21 20.0 -1 300.0 -0.77 -48.35 20.0 -1 300.0 -0.63 -48.48 20.0 -1 300.0 -0.47 -48.61 20.0 -1 300.0 -0.29 -48.74 20.0 -1 300.0 -0.11 -48.86 20.0 -1 300.0 0.09 -48.98 20.0 -1 300.0 0.3 -49.1 20.0 -1 300.0 0.53 -49.21 20.0 -1 300.0 0.77 -49.31 20.0 -1 300.0 1.01 -49.42 20.0 -1 300.0 1.27 -49.52 20.0 -1 300.0 1.82 -49.7 20.0 -1 300.0 2.11 -49.79 20.0 -1 300.0 2.41 -49.88 20.0 -1 300.0 2.71 -49.95 20.0 -1 300.0 3.03 -50.03 20.0 -1 300.0 3.35 -50.1 20.0 -1 300.0 3.67 -50.17 20.0 -1 300.0 4.0 -50.23 20.0 -1 300.0 4.34 -50.29 20.0 -1 300.0 4.68 -50.34 20.0 -1 300.0 5.03 -50.39 20.0 -1 300.0 5.38 -50.44 20.0 -1 300.0 5.73 -50.48 20.0 -1 300.0 6.08 -50.51 20.0 -1 300.0 6.43 -50.55 20.0 -1 300.0 6.79 -50.57 20.0 -1 300.0 7.14 -50.6 20.0 -1 300.0 7.49 -50.62 20.0 -1 300.0 7.84 -50.63 20.0 -1 300.0 8.19 -50.64 20.0 -1 300.0 8.54 -50.65 20.0 -1 300.0 8.88 -50.65 20.0 -1 300.0 9.22 -50.65 20.0 -1 300.0 9.55 -50.65 20.0 -1 300.0 9.88 -50.63 20.0 -1 300.0 10.2 -50.62 20.0 -1 300.0 10.52 -50.6 20.0 -1 300.0 10.82 -50.58 20.0 -1 300.0 11.12 -50.55 20.0 -1 300.0 11.41 -50.52 20.0 -1 300.0 11.69 -50.49 20.0 -1 300.0 11.96 -50.45 20.0 -1 300.0 12.22 -50.4 20.0 -1 300.0 12.47 -50.36 20.0 -1 300.0 12.71 -50.3 20.0 -1 300.0 12.94 -50.25 20.0 -1 300.0 13.15 -50.19 20.0 -1 300.0 13.36 -50.13 20.0 -1 300.0 13.55 -50.06 20.0 -1 300.0 13.72 -49.99 20.0 -1 300.0 13.88 -49.92 20.0 -1 300.0 14.02 -49.84 20.0 -1 300.0 14.14 -49.77 20.0 -1 300.0 14.26 -49.69 20.0 -1 300.0 14.36 -49.6 20.0 -1 300.0 14.44 -49.52 20.0 -1 300.0 14.51 -49.43 20.0 -1 300.0 14.57 -49.34 20.0 -1 300.0 14.62 -49.24 20.0 -1 300.0 14.64 -49.15 20.0 -1 300.0 14.66 -49.05 20.0 -1 300.0 14.66 -48.94 20.0 -1 300.0 14.65 -48.84 20.0 -1 300.0 14.63 -48.73 20.0 -1 300.0 14.58 -48.62 20.0 -1 300.0 14.53 -48.5 20.0 -1 300.0 14.46 -48.39 20.0 -1 300.0 14.38 -48.27 20.0 -1 300.0 14.28 -48.15 20.0 -1 300.0 14.17 -48.02 20.0 -1 300.0 14.04 -47.9 20.0 -1 300.0 13.9 -47.77 20.0 -1 300.0 13.75 -47.63 20.0 -1 300.0 13.4 -47.37 20.0 -1 300.0 13.21 -47.23 20.0 -1 300.0 13.0 -47.09 20.0 -1 300.0 12.55 -46.8 20.0 -1 300.0 11.5 -46.21 20.0 -1 300.0 11.21 -46.06 20.0 -1 300.0 10.92 -45.9 20.0 -1 300.0 10.29 -45.59 20.0 -1 300.0 8.92 -44.95 20.0 -1 300.0 5.87 -43.61 20.0 -1 300.0 5.47 -43.44 20.0 -1 300.0 5.06 -43.27 20.0 -1 300.0 4.25 -42.93 20.0 -1 300.0 2.6 -42.24 20.0 -1 300.0 -0.6 -40.87 20.0 -1 300.0 -1.02 -40.68 20.0 -1 300.0 -1.44 -40.49 20.0 -1 300.0 -2.26 -40.12 20.0 -1 300.0 -3.76 -39.38 20.0 -1 300.0 -4.11 -39.2 20.0 -1 300.0 -4.45 -39.02 20.0 -1 300.0 -5.08 -38.66 20.0 -1 300.0 -5.38 -38.49 20.0 -1 300.0 -5.66 -38.32 20.0 -1 300.0 -6.18 -37.98 20.0 -1 300.0 -6.42 -37.81 20.0 -1 300.0 -6.64 -37.65 20.0 -1 300.0 -6.84 -37.48 20.0 -1 300.0 -7.03 -37.32 20.0 -1 300.0 -7.2 -37.16 20.0 -1 300.0 -7.35 -37.01 20.0 -1 300.0 -7.49 -36.86 20.0 -1 300.0 -7.61 -36.71 20.0 -1 300.0 -7.71 -36.56 20.0 -1 300.0 -7.79 -36.41 20.0 -1 300.0 -7.86 -36.27 20.0 -1 300.0 -7.9 -36.13 20.0 -1 300.0 -7.93 -36.0 20.0 -1 300.0 -7.95 -35.86 20.0 -1 300.0 -7.94 -35.73 20.0 -1 300.0 -7.92 -35.61 20.0 -1 300.0 -7.88 -35.48 20.0 -1 300.0 -7.82 -35.36 20.0 -1 300.0 -7.74 -35.25 20.0 -1 300.0 -7.65 -35.13 20.0 -1 300.0 -7.54 -35.02 20.0 -1 300.0 -7.42 -34.92 20.0 -1 300.0 -7.28 -34.81 20.0 -1 300.0 -7.12 -34.72 20.0 -1 300.0 -6.95 -34.62 20.0 -1 300.0 -6.76 -34.53 20.0 -1 300.0 -6.56 -34.44 20.0 -1 300.0 -6.34 -34.36 20.0 -1 300.0 -6.12 -34.28 20.0 -1 300.0 -5.87 -34.2 20.0 -1 300.0 -5.62 -34.13 20.0 -1 300.0 -5.35 -34.06 20.0 -1 300.0 -5.08 -33.99 20.0 -1 300.0 -4.79 -33.93 20.0 -1 300.0 -4.49 -33.88 20.0 -1 300.0 -4.18 -33.82 20.0 -1 300.0 -3.86 -33.77 20.0 -1 300.0 -3.54 -33.73 20.0 -1 300.0 -3.21 -33.69 20.0 -1 300.0 -2.87 -33.66 20.0 -1 300.0 -2.52 -33.62 20.0 -1 300.0 -2.17 -33.6 20.0 -1 300.0 -1.82 -33.57 20.0 -1 300.0 -1.46 -33.55 20.0 -1 300.0 -1.1 -33.54 20.0 -1 300.0 -0.73 -33.53 20.0 -1 300.0 -0.37 -33.52 20.0 -1 300.0 0.0 -33.52 20.0 -0 300.0 0.0 -33.52 6.0 -0 300.0 37.56 12.33 6.0 -1 300.0 37.56 12.33 -1.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 37.56 0.88 6.0 -1 300.0 37.56 0.88 -1.0 -1 300.0 37.56 -10.57 -1.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 37.56 0.88 -1.0 -0 300.0 37.56 0.88 6.0 -0 300.0 49.01 12.33 6.0 -1 300.0 49.01 12.33 -1.0 -1 300.0 52.08 15.01 -1.0 -0 300.0 52.08 15.01 6.0 -0 300.0 49.01 0.88 6.0 -1 300.0 49.01 0.88 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 52.08 15.01 -1.0 -1 300.0 43.29 15.01 -1.0 -1 300.0 37.56 12.33 -1.0 -0 300.0 37.56 12.33 6.0 -0 300.0 49.01 -10.57 6.0 -1 300.0 49.01 -10.57 -1.0 -1 300.0 52.08 -2.58 -1.0 -1 300.0 52.08 6.21 -1.0 -1 300.0 49.01 0.88 -1.0 -0 300.0 49.01 0.88 6.0 -0 300.0 49.01 0.88 20.0 -0 300.0 0.0 0.0 20.0 -0 300.0 0.0 0.0 20.0 diff --git a/test/matlab/matlab_convert.py b/test/matlab/matlab_convert.py deleted file mode 100755 index cf750acf7..000000000 --- a/test/matlab/matlab_convert.py +++ /dev/null @@ -1,270 +0,0 @@ -#!/usr/bin/env python -"""\ -The MIT License (MIT) - -Copyright (c) 2014 Sungeun K. Jeon - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. ----------------------------------------------------------------------------------------- -""" -"""\ -G-code preprocessor for the grbl_sim.m MATLAB script. Parses the g-code program to a -specific file format for the MATLAB script to use. Based on PreGrbl by @chamnit. - -How to use: When running this python script, it will process the g-code program under -the filename "test.gcode" (may be changed below) and produces a file called "matlab.gcode" -that the grbl_sim.m MATLAB script will search for and execute. -""" - -import re -from math import * -from copy import * - -# -= SETTINGS =- -filein = 'test.gcode' # Input file name -fileout = 'matlab.gcode' # Output file name -ndigits_in = 4 # inch significant digits after '.' -ndigits_mm = 2 # mm significant digits after '.' -# mm_per_arc_segment = 0.38 # mm per arc segment -arc_tolerance = 0.00005*25.4 -n_arc_correction = 20 -inch2mm = 25.4 # inch to mm conversion scalar -verbose = False # Verbose flag to show all progress -remove_unsupported = True # Removal flag for all unsupported statements - -# Initialize parser state -gc = { 'current_xyz' : [0,0,0], - 'feed_rate' : 0, # F0 - 'motion_mode' : 'SEEK', # G00 - 'plane_axis' : [0,1,2], # G17 - 'inches_mode' : False, # G21 - 'inverse_feedrate_mode' : False, # G94 - 'absolute_mode' : True} # G90 - -def unit_conv(val) : # Converts value to mm - if gc['inches_mode'] : val *= inch2mm - return(val) - -def fout_conv(val) : # Returns converted value as rounded string for output file. - if gc['inches_mode'] : return( str(round(val/inch2mm,ndigits_in)) ) - else : return( str(round(val,ndigits_mm)) ) - -# Open g-code file -fin = open(filein,'r'); -fout = open(fileout,'w'); - -# Iterate through g-code file -l_count = 0 -for line in fin: - l_count += 1 # Iterate line counter - - # Strip comments/spaces/tabs/new line and capitalize. Comment MSG not supported. - block = re.sub('\s|\(.*?\)','',line).upper() - block = re.sub('\\\\','',block) # Strip \ block delete character - block = re.sub('%','',block) # Strip % program start/stop character - - if len(block) == 0 : # Ignore empty blocks - - print "Skipping: " + line.strip() - - else : # Process valid g-code clean block. Assumes no block delete characters or comments - - g_cmd = re.findall(r'[^0-9\.\-]+',block) # Extract block command characters - g_num = re.findall(r'[0-9\.\-]+',block) # Extract block numbers - - # G-code block error checks - # if len(g_cmd) != len(g_num) : print block; raise Exception('Invalid block. Unbalanced word and values.') - if 'N' in g_cmd : - if g_cmd[0]!='N': raise Exception('Line number must be first command in line.') - if g_cmd.count('N') > 1: raise Exception('More than one line number in block.') - g_cmd = g_cmd[1:] # Remove line number word - g_num = g_num[1:] - # Block item repeat checks? (0<=n'M'<5, G/M modal groups) - - # Initialize block state - blk = { 'next_action' : 'DEFAULT', - 'absolute_override' : False, - 'target_xyz' : deepcopy(gc['current_xyz']), - 'offset_ijk' : [0,0,0], - 'radius_mode' : False, - 'unsupported': [] } - - # Pass 1 - for cmd,num in zip(g_cmd,g_num) : - fnum = float(num) - inum = int(fnum) - if cmd is 'G' : - if inum is 0 : gc['motion_mode'] = 'SEEK' - elif inum is 1 : gc['motion_mode'] = 'LINEAR' - elif inum is 2 : gc['motion_mode'] = 'CW_ARC' - elif inum is 3 : gc['motion_mode'] = 'CCW_ARC' - elif inum is 4 : blk['next_action'] = 'DWELL' - elif inum is 17 : gc['plane_axis'] = [0,1,2] # Select XY Plane - elif inum is 18 : gc['plane_axis'] = [0,2,1] # Select XZ Plane - elif inum is 19 : gc['plane_axis'] = [1,2,0] # Select YZ Plane - elif inum is 20 : gc['inches_mode'] = True - elif inum is 21 : gc['inches_mode'] = False - elif inum in [28,30] : blk['next_action'] = 'GO_HOME' - elif inum is 53 : blk['absolute_override'] = True - elif inum is 54 : pass - elif inum is 80 : gc['motion_mode'] = 'MOTION_CANCEL' - elif inum is 90 : gc['absolute_mode'] = True - elif inum is 91 : gc['absolute_mode'] = False - elif inum is 92 : blk['next_action'] = 'SET_OFFSET' - elif inum is 93 : gc['inverse_feedrate_mode'] = True - elif inum is 94 : gc['inverse_feedrate_mode'] = False - else : - print 'Unsupported command ' + cmd + num + ' on line ' + str(l_count) - if remove_unsupported : blk['unsupported'].append(zip(g_cmd,g_num).index((cmd,num))) - elif cmd is 'M' : - if inum in [0,1] : pass # Program Pause - elif inum in [2,30,60] : pass # Program Completed - elif inum is 3 : pass # Spindle Direction 1 - elif inum is 4 : pass # Spindle Direction -1 - elif inum is 5 : pass # Spindle Direction 0 - else : - print 'Unsupported command ' + cmd + num + ' on line ' + str(l_count) - if remove_unsupported : blk['unsupported'].append(zip(g_cmd,g_num).index((cmd,num))) - elif cmd is 'T' : pass # Tool Number - - # Pass 2 - for cmd,num in zip(g_cmd,g_num) : - fnum = float(num) - if cmd is 'F' : gc['feed_rate'] = unit_conv(fnum) # Feed Rate - elif cmd in ['I','J','K'] : blk['offset_ijk'][ord(cmd)-ord('I')] = unit_conv(fnum) # Arc Center Offset - elif cmd is 'N' : pass - elif cmd is 'P' : p = fnum # Misc value parameter - elif cmd is 'R' : r = unit_conv(fnum); blk['radius_mode'] = True # Arc Radius Mode - elif cmd is 'S' : pass # Spindle Speed - elif cmd in ['X','Y','Z'] : # Target Coordinates - if (gc['absolute_mode'] | blk['absolute_override']) : - blk['target_xyz'][ord(cmd)-ord('X')] = unit_conv(fnum) - else : - blk['target_xyz'][ord(cmd)-ord('X')] += unit_conv(fnum) - - # Execute actions - if blk['next_action'] is 'GO_HOME' : - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif blk['next_action'] is 'SET_OFFSET' : - pass - elif blk['next_action'] is 'DWELL' : - if p < 0 : raise Exception('Dwell time negative.') - else : # 'DEFAULT' - if gc['motion_mode'] is 'SEEK' : - fout.write('0 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(blk['target_xyz'][0])) - fout.write(' '+fout_conv(blk['target_xyz'][1])) - fout.write(' '+fout_conv(blk['target_xyz'][2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif gc['motion_mode'] is 'LINEAR' : - fout.write('1 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(blk['target_xyz'][0])) - fout.write(' '+fout_conv(blk['target_xyz'][1])) - fout.write(' '+fout_conv(blk['target_xyz'][2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(blk['target_xyz']) # Update position - elif gc['motion_mode'] in ['CW_ARC','CCW_ARC'] : - axis = gc['plane_axis'] - - # Convert radius mode to ijk mode - if blk['radius_mode'] : - x = blk['target_xyz'][axis[0]]-gc['current_xyz'][axis[0]] - y = blk['target_xyz'][axis[1]]-gc['current_xyz'][axis[1]] - if not (x==0 and y==0) : raise Exception('Same target and current XYZ not allowed in arc radius mode.') - h_x2_div_d = -sqrt(4 * r*r - x*x - y*y)/hypot(x,y) - if isnan(h_x2_div_d) : raise Exception('Floating point error in arc conversion') - if gc['motion_mode'] is 'CCW_ARC' : h_x2_div_d = -h_x2_div_d - if r < 0 : h_x2_div_d = -h_x2_div_d - blk['offset_ijk'][axis[0]] = (x-(y*h_x2_div_d))/2; - blk['offset_ijk'][axis[1]] = (y+(x*h_x2_div_d))/2; - else : - radius = sqrt(blk['offset_ijk'][axis[0]]**2+blk['offset_ijk'][axis[1]]**2) - - center_axis0 = gc['current_xyz'][axis[0]]+blk['offset_ijk'][axis[0]] - center_axis1 = gc['current_xyz'][axis[1]]+blk['offset_ijk'][axis[1]] - linear_travel = blk['target_xyz'][axis[2]]-gc['current_xyz'][axis[2]] - r_axis0 = -blk['offset_ijk'][axis[0]] - r_axis1 = -blk['offset_ijk'][axis[1]] - rt_axis0 = blk['target_xyz'][axis[0]] - center_axis0; - rt_axis1 = blk['target_xyz'][axis[1]] - center_axis1; - clockwise_sign = 1 - if gc['motion_mode'] is 'CW_ARC' : clockwise_sign = -1 - - angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1) - if gc['motion_mode'] is 'CW_ARC' : - if angular_travel >= 0 : - angular_travel -= 2*pi - else : - if angular_travel <= 0 : - angular_travel += 2*pi - - millimeters_of_travel = sqrt((angular_travel*radius)**2 + abs(linear_travel)**2) - - mm_per_arc_segment = sqrt(4*(2*radius*arc_tolerance-arc_tolerance**2)) - segments = int(millimeters_of_travel/mm_per_arc_segment) - print segments - print l_count - theta_per_segment = angular_travel/segments - linear_per_segment = linear_travel/segments - cos_T = 1-0.5*theta_per_segment*theta_per_segment - sin_T = theta_per_segment-theta_per_segment**3/6 - print(fout_conv(mm_per_arc_segment)) - print theta_per_segment*180/pi - - arc_target = [0,0,0] - arc_target[axis[2]] = gc['current_xyz'][axis[2]] - - count = 0 - for i in range(1,segments+1) : - if i < segments : - if count < n_arc_correction : - r_axisi = r_axis0*sin_T + r_axis1*cos_T - r_axis0 = r_axis0*cos_T - r_axis1*sin_T - r_axis1 = deepcopy(r_axisi) - count += 1 - else : - cos_Ti = cos((i-1)*theta_per_segment) - sin_Ti = sin((i-1)*theta_per_segment) - print n_arc_correction*(r_axis0 -( -blk['offset_ijk'][axis[0]]*cos_Ti + blk['offset_ijk'][axis[1]]*sin_Ti)) - print n_arc_correction*(r_axis1 -( -blk['offset_ijk'][axis[0]]*sin_Ti - blk['offset_ijk'][axis[1]]*cos_Ti)) - cos_Ti = cos(i*theta_per_segment) - sin_Ti = sin(i*theta_per_segment) - r_axis0 = -blk['offset_ijk'][axis[0]]*cos_Ti + blk['offset_ijk'][axis[1]]*sin_Ti - r_axis1 = -blk['offset_ijk'][axis[0]]*sin_Ti - blk['offset_ijk'][axis[1]]*cos_Ti - count = 0 - arc_target[axis[0]] = center_axis0 + r_axis0 - arc_target[axis[1]] = center_axis1 + r_axis1 - arc_target[axis[2]] += linear_per_segment - else : - arc_target = deepcopy(blk['target_xyz']) # Last segment at target_xyz - # Write only changed variables. - fout.write('1 '+fout_conv(gc['feed_rate'])) - fout.write(' '+fout_conv(arc_target[0])) - fout.write(' '+fout_conv(arc_target[1])) - fout.write(' '+fout_conv(arc_target[2])) - fout.write('\n') - gc['current_xyz'] = deepcopy(arc_target) # Update position - - -print 'Done!' - -# Close files -fin.close() -fout.close() \ No newline at end of file diff --git a/test/matlab/test.gcode b/test/matlab/test.gcode deleted file mode 100644 index 3d9d56cd7..000000000 --- a/test/matlab/test.gcode +++ /dev/null @@ -1,2363 +0,0 @@ -(Braid.NC Test Program) -T1M6 -G17G21 -G0X0Y0 -G0Z6.000 -G0X37.560Y12.327Z6.000 -G1Z-1.000 F300 -G1Y0.876 -X49.011 -Y12.327 -X37.560 -G0Z6.000 -G0Y0.876 -G1Z-1.000 -G1Y-10.575 -X49.011 -Y0.876 -X37.560 -G0Z6.000 -G0X49.011Y12.327 -G1Z-1.000 -G1X52.084Y15.011 -G0Z6.000 -G0X49.011Y0.876 -G1Z-1.000 -G1X52.084Y6.213 -Y15.011 -X43.286 -X37.560Y12.327 -G0Z6.000 -G0X49.011Y-10.575 -G1Z-1.000 -G1X52.084Y-2.585 -Y6.213 -X49.011Y0.876 -G0Z6.000 -G0Z20.000 -G0X0.000Y0.000 -G1X-7.098Y-39.876 -X-10.296Y-38.118 -X-10.698Y-37.897 -X-11.099Y-37.676 -X-11.894Y-37.235 -X-13.448Y-36.356 -X-13.825Y-36.137 -X-14.197Y-35.919 -X-14.923Y-35.485 -X-16.288Y-34.625 -X-16.636Y-34.395 -X-16.973Y-34.165 -X-17.613Y-33.711 -X-17.915Y-33.486 -X-18.204Y-33.262 -X-18.743Y-32.821 -X-18.992Y-32.602 -X-19.227Y-32.386 -X-19.447Y-32.171 -X-19.652Y-31.959 -X-19.843Y-31.749 -X-20.017Y-31.540 -X-20.176Y-31.335 -X-20.320Y-31.131 -X-20.447Y-30.930 -X-20.558Y-30.731 -X-20.653Y-30.535 -X-20.731Y-30.341 -X-20.793Y-30.150 -X-20.838Y-29.961 -X-20.867Y-29.776 -X-20.879Y-29.593 -X-20.875Y-29.413 -X-20.854Y-29.236 -X-20.817Y-29.062 -X-20.764Y-28.891 -X-20.695Y-28.723 -X-20.610Y-28.559 -X-20.510Y-28.397 -X-20.394Y-28.239 -X-20.263Y-28.084 -X-20.117Y-27.932 -X-19.957Y-27.784 -X-19.782Y-27.639 -X-19.594Y-27.498 -X-19.392Y-27.360 -X-19.177Y-27.226 -X-18.950Y-27.095 -X-18.710Y-26.968 -X-18.459Y-26.845 -X-18.197Y-26.725 -X-17.924Y-26.609 -X-17.641Y-26.497 -X-17.349Y-26.389 -X-16.737Y-26.183 -X-16.419Y-26.086 -X-16.094Y-25.993 -X-15.763Y-25.904 -X-15.426Y-25.818 -X-15.083Y-25.737 -X-14.736Y-25.660 -X-14.030Y-25.516 -X-13.672Y-25.451 -X-13.313Y-25.389 -X-12.953Y-25.332 -X-12.591Y-25.278 -X-12.230Y-25.228 -X-11.870Y-25.182 -X-11.511Y-25.140 -X-11.155Y-25.103 -X-10.824Y-25.071 -X-10.497Y-25.043 -X-10.173Y-25.018 -X-9.853Y-24.996 -X-9.538Y-24.978 -X-9.228Y-24.964 -X-8.924Y-24.952 -X-8.625Y-24.944 -X-8.334Y-24.940 -X-8.049Y-24.939 -X-7.772Y-24.941 -X-7.504Y-24.946 -X-7.243Y-24.955 -X-6.992Y-24.967 -X-6.750Y-24.982 -X-6.518Y-25.000 -X-6.295Y-25.022 -X-6.084Y-25.047 -X-5.883Y-25.075 -X-5.694Y-25.106 -X-5.517Y-25.140 -X-5.351Y-25.177 -X-5.197Y-25.217 -X-5.057Y-25.260 -X-4.928Y-25.306 -X-4.813Y-25.355 -X-4.711Y-25.407 -X-4.623Y-25.461 -X-4.548Y-25.518 -X-4.487Y-25.578 -X-4.439Y-25.641 -X-4.406Y-25.707 -X-4.387Y-25.775 -X-4.382Y-25.845 -X-4.392Y-25.918 -X-4.416Y-25.994 -X-4.454Y-26.072 -X-4.506Y-26.152 -X-4.572Y-26.235 -X-4.653Y-26.320 -X-4.748Y-26.407 -X-4.857Y-26.496 -X-4.980Y-26.588 -X-5.117Y-26.681 -X-5.267Y-26.777 -X-5.431Y-26.874 -X-5.798Y-27.074 -X-6.001Y-27.177 -X-6.216Y-27.282 -X-6.683Y-27.496 -X-7.755Y-27.942 -X-8.049Y-28.057 -X-8.353Y-28.173 -X-8.990Y-28.409 -X-10.362Y-28.891 -X-10.753Y-29.024 -X-11.151Y-29.158 -X-11.968Y-29.428 -X-13.658Y-29.973 -X-17.113Y-31.067 -X-17.538Y-31.202 -X-17.959Y-31.337 -X-18.788Y-31.604 -X-20.370Y-32.127 -X-20.746Y-32.255 -X-21.113Y-32.382 -X-21.817Y-32.631 -X-23.093Y-33.111 -X-23.381Y-33.226 -X-23.656Y-33.339 -X-24.164Y-33.560 -X-24.397Y-33.667 -X-24.615Y-33.772 -X-25.005Y-33.974 -X-25.177Y-34.072 -X-25.332Y-34.167 -X-25.472Y-34.259 -X-25.595Y-34.349 -X-25.701Y-34.436 -X-25.791Y-34.520 -X-25.864Y-34.601 -X-25.920Y-34.679 -X-25.960Y-34.754 -X-25.982Y-34.826 -X-25.987Y-34.895 -X-25.976Y-34.961 -X-25.948Y-35.023 -X-25.903Y-35.082 -X-25.841Y-35.138 -X-25.763Y-35.190 -X-25.669Y-35.239 -X-25.559Y-35.284 -X-25.433Y-35.325 -X-25.291Y-35.363 -X-25.134Y-35.397 -X-24.963Y-35.428 -X-24.777Y-35.455 -X-24.577Y-35.477 -X-24.367Y-35.496 -X-24.144Y-35.511 -X-23.909Y-35.522 -X-23.661Y-35.529 -X-23.403Y-35.532 -X-23.133Y-35.532 -X-22.853Y-35.527 -X-22.563Y-35.519 -X-22.263Y-35.506 -X-21.955Y-35.490 -X-21.638Y-35.470 -X-21.313Y-35.445 -X-20.981Y-35.416 -X-20.643Y-35.384 -X-20.299Y-35.347 -X-19.949Y-35.306 -X-19.595Y-35.261 -X-19.237Y-35.212 -X-18.875Y-35.158 -X-18.511Y-35.101 -X-18.145Y-35.039 -X-17.777Y-34.973 -X-17.041Y-34.829 -X-16.673Y-34.751 -X-16.306Y-34.668 -X-15.580Y-34.491 -X-15.222Y-34.396 -X-14.867Y-34.297 -X-14.172Y-34.086 -X-13.833Y-33.975 -X-13.501Y-33.859 -X-13.176Y-33.740 -X-12.858Y-33.616 -X-12.548Y-33.488 -X-12.248Y-33.357 -X-11.675Y-33.082 -X-11.404Y-32.938 -X-11.144Y-32.791 -X-10.896Y-32.639 -X-10.659Y-32.484 -X-10.435Y-32.326 -X-10.223Y-32.163 -X-10.025Y-31.997 -X-9.840Y-31.827 -X-9.669Y-31.653 -X-9.512Y-31.476 -X-9.370Y-31.295 -X-9.242Y-31.111 -X-9.130Y-30.923 -X-9.033Y-30.732 -X-8.951Y-30.538 -X-8.885Y-30.340 -X-8.835Y-30.139 -X-8.801Y-29.934 -X-8.782Y-29.727 -X-8.780Y-29.517 -X-8.794Y-29.303 -X-8.825Y-29.087 -X-8.871Y-28.867 -X-8.934Y-28.645 -X-9.006Y-28.435 -X-9.093Y-28.223 -X-9.194Y-28.008 -X-9.308Y-27.792 -X-9.435Y-27.573 -X-9.577Y-27.352 -X-9.898Y-26.903 -X-10.078Y-26.676 -X-10.271Y-26.446 -X-10.693Y-25.982 -X-10.922Y-25.748 -X-11.162Y-25.511 -X-11.675Y-25.034 -X-11.948Y-24.793 -X-12.230Y-24.550 -X-12.824Y-24.061 -X-14.114Y-23.068 -X-17.000Y-21.038 -X-17.380Y-20.782 -X-17.762Y-20.525 -X-18.532Y-20.010 -X-20.077Y-18.979 -X-20.462Y-18.721 -X-20.845Y-18.464 -X-21.602Y-17.949 -X-23.072Y-16.925 -X-23.427Y-16.671 -X-23.776Y-16.417 -X-24.454Y-15.911 -X-25.717Y-14.911 -X-26.011Y-14.664 -X-26.295Y-14.418 -X-26.833Y-13.930 -X-27.086Y-13.688 -X-27.328Y-13.447 -X-27.777Y-12.971 -X-28.000Y-12.715 -X-28.209Y-12.461 -X-28.404Y-12.210 -X-28.583Y-11.961 -X-28.746Y-11.713 -X-28.894Y-11.469 -X-29.026Y-11.226 -X-29.142Y-10.986 -X-29.242Y-10.749 -X-29.325Y-10.514 -X-29.391Y-10.281 -X-29.441Y-10.052 -X-29.475Y-9.825 -X-29.491Y-9.601 -X-29.491Y-9.380 -X-29.475Y-9.162 -X-29.441Y-8.947 -X-29.391Y-8.735 -X-29.325Y-8.526 -X-29.242Y-8.320 -X-29.144Y-8.118 -X-29.029Y-7.919 -X-28.899Y-7.723 -X-28.753Y-7.531 -X-28.592Y-7.342 -X-28.416Y-7.156 -X-28.226Y-6.974 -X-28.022Y-6.796 -X-27.804Y-6.621 -X-27.572Y-6.450 -X-27.071Y-6.119 -X-26.802Y-5.959 -X-26.522Y-5.803 -X-25.929Y-5.502 -X-25.617Y-5.358 -X-25.296Y-5.217 -X-24.628Y-4.948 -X-24.283Y-4.819 -X-23.930Y-4.694 -X-23.207Y-4.457 -X-22.838Y-4.344 -X-22.465Y-4.236 -X-21.707Y-4.031 -X-21.325Y-3.935 -X-20.941Y-3.842 -X-20.170Y-3.670 -X-19.786Y-3.590 -X-19.402Y-3.515 -X-18.642Y-3.375 -X-18.266Y-3.312 -X-17.894Y-3.252 -X-17.527Y-3.197 -X-17.164Y-3.145 -X-16.808Y-3.098 -X-16.459Y-3.055 -X-16.116Y-3.015 -X-15.781Y-2.980 -X-15.477Y-2.951 -X-15.179Y-2.925 -X-14.891Y-2.902 -X-14.611Y-2.883 -X-14.340Y-2.867 -X-14.078Y-2.855 -X-13.827Y-2.845 -X-13.586Y-2.839 -X-13.355Y-2.837 -X-13.136Y-2.837 -X-12.929Y-2.841 -X-12.733Y-2.848 -X-12.549Y-2.858 -X-12.378Y-2.871 -X-12.220Y-2.888 -X-12.074Y-2.907 -X-11.942Y-2.929 -X-11.823Y-2.955 -X-11.717Y-2.983 -X-11.626Y-3.014 -X-11.548Y-3.048 -X-11.484Y-3.084 -X-11.435Y-3.124 -X-11.400Y-3.166 -X-11.379Y-3.210 -X-11.372Y-3.258 -X-11.380Y-3.308 -X-11.403Y-3.360 -X-11.440Y-3.415 -X-11.491Y-3.472 -X-11.556Y-3.532 -X-11.636Y-3.594 -X-11.729Y-3.658 -X-11.837Y-3.724 -X-11.959Y-3.793 -X-12.094Y-3.863 -X-12.242Y-3.936 -X-12.404Y-4.010 -X-12.767Y-4.165 -X-12.967Y-4.245 -X-13.179Y-4.327 -X-13.639Y-4.495 -X-14.691Y-4.850 -X-14.979Y-4.942 -X-15.277Y-5.036 -X-15.897Y-5.225 -X-17.230Y-5.617 -X-20.146Y-6.431 -X-20.516Y-6.532 -X-20.887Y-6.634 -X-21.630Y-6.837 -X-23.106Y-7.241 -X-25.895Y-8.028 -X-26.218Y-8.123 -X-26.535Y-8.218 -X-27.145Y-8.403 -X-28.260Y-8.760 -X-28.514Y-8.846 -X-28.759Y-8.930 -X-29.214Y-9.095 -X-29.425Y-9.175 -X-29.624Y-9.253 -X-29.986Y-9.404 -X-30.149Y-9.477 -X-30.298Y-9.548 -X-30.435Y-9.617 -X-30.559Y-9.684 -X-30.669Y-9.749 -X-30.766Y-9.812 -X-30.849Y-9.872 -X-30.918Y-9.931 -X-30.974Y-9.987 -X-31.016Y-10.041 -X-31.043Y-10.092 -X-31.057Y-10.141 -X-31.057Y-10.188 -X-31.043Y-10.232 -X-31.015Y-10.273 -X-30.972Y-10.312 -X-30.916Y-10.349 -X-30.847Y-10.382 -X-30.763Y-10.413 -X-30.666Y-10.441 -X-30.556Y-10.466 -X-30.432Y-10.489 -X-30.295Y-10.508 -X-30.146Y-10.525 -X-29.984Y-10.539 -X-29.809Y-10.549 -X-29.622Y-10.557 -X-29.424Y-10.562 -X-29.214Y-10.563 -X-28.992Y-10.562 -X-28.760Y-10.557 -X-28.517Y-10.549 -X-28.242Y-10.537 -X-27.955Y-10.521 -X-27.657Y-10.501 -X-27.349Y-10.477 -X-27.031Y-10.450 -X-26.703Y-10.418 -X-26.366Y-10.383 -X-26.021Y-10.343 -X-25.668Y-10.300 -X-25.308Y-10.253 -X-24.568Y-10.146 -X-24.191Y-10.086 -X-23.808Y-10.023 -X-23.032Y-9.883 -X-22.640Y-9.807 -X-22.245Y-9.728 -X-21.453Y-9.556 -X-21.057Y-9.463 -X-20.662Y-9.367 -X-19.876Y-9.162 -X-19.487Y-9.054 -X-19.101Y-8.941 -X-18.343Y-8.704 -X-17.972Y-8.579 -X-17.606Y-8.450 -X-16.896Y-8.180 -X-16.552Y-8.040 -X-16.217Y-7.895 -X-15.574Y-7.594 -X-15.268Y-7.438 -X-14.972Y-7.277 -X-14.414Y-6.946 -X-14.153Y-6.774 -X-13.905Y-6.599 -X-13.669Y-6.420 -X-13.447Y-6.237 -X-13.239Y-6.051 -X-13.044Y-5.862 -X-12.864Y-5.669 -X-12.699Y-5.472 -X-12.549Y-5.272 -X-12.414Y-5.069 -X-12.294Y-4.862 -X-12.190Y-4.652 -X-12.102Y-4.439 -X-12.030Y-4.223 -X-11.975Y-4.003 -X-11.935Y-3.781 -X-11.911Y-3.555 -X-11.904Y-3.327 -X-11.914Y-3.096 -X-11.939Y-2.862 -X-11.981Y-2.625 -X-12.038Y-2.386 -X-12.112Y-2.144 -X-12.202Y-1.899 -X-12.300Y-1.669 -X-12.412Y-1.436 -X-12.537Y-1.201 -X-12.675Y-0.965 -X-12.826Y-0.726 -X-12.990Y-0.486 -X-13.355Y0.001 -X-13.555Y0.246 -X-13.768Y0.494 -X-14.226Y0.993 -X-15.266Y2.009 -X-15.550Y2.266 -X-15.842Y2.524 -X-16.451Y3.043 -X-17.752Y4.093 -X-20.572Y6.219 -X-20.935Y6.486 -X-21.298Y6.753 -X-22.024Y7.287 -X-23.456Y8.353 -X-23.807Y8.618 -X-24.154Y8.883 -X-24.835Y9.411 -X-26.125Y10.458 -X-26.431Y10.717 -X-26.728Y10.975 -X-27.297Y11.489 -X-27.568Y11.744 -X-27.830Y11.997 -X-28.322Y12.500 -X-28.552Y12.749 -X-28.771Y12.997 -X-28.978Y13.243 -X-29.174Y13.487 -X-29.357Y13.729 -X-29.528Y13.970 -X-29.686Y14.209 -X-29.831Y14.446 -X-29.974Y14.700 -X-30.101Y14.953 -X-30.212Y15.202 -X-30.307Y15.449 -X-30.385Y15.694 -X-30.447Y15.936 -X-30.492Y16.175 -X-30.521Y16.411 -X-30.532Y16.644 -X-30.527Y16.874 -X-30.505Y17.102 -X-30.466Y17.326 -X-30.411Y17.547 -X-30.338Y17.765 -X-30.249Y17.980 -X-30.144Y18.191 -X-30.022Y18.399 -X-29.884Y18.603 -X-29.730Y18.805 -X-29.561Y19.002 -X-29.376Y19.196 -X-29.176Y19.386 -X-28.962Y19.573 -X-28.733Y19.756 -X-28.490Y19.935 -X-28.233Y20.111 -X-27.964Y20.282 -X-27.681Y20.450 -X-27.386Y20.614 -X-27.080Y20.774 -X-26.434Y21.081 -X-26.096Y21.229 -X-25.748Y21.373 -X-25.025Y21.648 -X-24.652Y21.780 -X-24.272Y21.907 -X-23.493Y22.149 -X-23.095Y22.264 -X-22.693Y22.375 -X-21.877Y22.583 -X-21.466Y22.681 -X-21.053Y22.775 -X-20.223Y22.949 -X-19.809Y23.030 -X-19.396Y23.107 -X-18.575Y23.247 -X-18.169Y23.311 -X-17.767Y23.371 -X-16.977Y23.478 -X-16.591Y23.525 -X-16.211Y23.568 -X-15.838Y23.606 -X-15.473Y23.641 -X-15.116Y23.671 -X-14.769Y23.698 -X-14.430Y23.720 -X-14.102Y23.739 -X-13.791Y23.753 -X-13.490Y23.763 -X-13.200Y23.769 -X-12.922Y23.772 -X-12.657Y23.771 -X-12.404Y23.766 -X-12.164Y23.758 -X-11.937Y23.746 -X-11.724Y23.730 -X-11.525Y23.711 -X-11.340Y23.688 -X-11.171Y23.662 -X-11.016Y23.633 -X-10.876Y23.600 -X-10.752Y23.564 -X-10.643Y23.524 -X-10.549Y23.481 -X-10.472Y23.435 -X-10.411Y23.386 -X-10.365Y23.334 -X-10.336Y23.279 -X-10.323Y23.221 -X-10.326Y23.161 -X-10.344Y23.097 -X-10.379Y23.030 -X-10.430Y22.961 -X-10.497Y22.889 -X-10.579Y22.815 -X-10.676Y22.738 -X-10.789Y22.659 -X-10.917Y22.577 -X-11.060Y22.493 -X-11.217Y22.407 -X-11.389Y22.318 -X-11.773Y22.135 -X-11.985Y22.041 -X-12.210Y21.945 -X-12.697Y21.747 -X-12.958Y21.645 -X-13.230Y21.542 -X-13.806Y21.331 -X-15.066Y20.894 -X-15.401Y20.782 -X-15.742Y20.670 -X-16.442Y20.441 -X-17.896Y19.977 -X-20.868Y19.035 -X-21.208Y18.926 -X-21.545Y18.817 -X-22.208Y18.600 -X-23.472Y18.173 -X-23.772Y18.068 -X-24.066Y17.964 -X-24.629Y17.759 -X-25.650Y17.361 -X-25.881Y17.265 -X-26.101Y17.170 -X-26.509Y16.984 -X-26.696Y16.893 -X-26.871Y16.804 -X-27.184Y16.631 -X-27.322Y16.547 -X-27.447Y16.465 -X-27.559Y16.385 -X-27.658Y16.306 -X-27.743Y16.230 -X-27.815Y16.156 -X-27.873Y16.084 -X-27.917Y16.014 -X-27.947Y15.946 -X-27.963Y15.880 -X-27.965Y15.817 -X-27.953Y15.756 -X-27.927Y15.697 -X-27.887Y15.641 -X-27.832Y15.588 -X-27.764Y15.537 -X-27.681Y15.488 -X-27.585Y15.442 -X-27.475Y15.399 -X-27.351Y15.358 -X-27.214Y15.321 -X-27.063Y15.286 -X-26.899Y15.253 -X-26.723Y15.224 -X-26.533Y15.198 -X-26.332Y15.174 -X-26.118Y15.154 -X-25.892Y15.136 -X-25.654Y15.122 -X-25.405Y15.110 -X-25.145Y15.102 -X-24.875Y15.097 -X-24.594Y15.095 -X-24.304Y15.096 -X-24.004Y15.100 -X-23.694Y15.107 -X-23.377Y15.118 -X-23.051Y15.132 -X-22.717Y15.149 -X-22.376Y15.170 -X-21.998Y15.196 -X-21.613Y15.226 -X-21.221Y15.260 -X-20.822Y15.298 -X-20.418Y15.340 -X-20.010Y15.385 -X-19.180Y15.489 -X-18.761Y15.547 -X-18.339Y15.609 -X-17.492Y15.744 -X-17.067Y15.818 -X-16.644Y15.896 -X-15.800Y16.064 -X-15.382Y16.154 -X-14.967Y16.248 -X-14.150Y16.448 -X-13.749Y16.554 -X-13.354Y16.664 -X-12.583Y16.895 -X-12.209Y17.017 -X-11.844Y17.142 -X-11.140Y17.405 -X-10.803Y17.542 -X-10.477Y17.683 -X-9.858Y17.975 -X-9.566Y18.127 -X-9.287Y18.283 -X-9.021Y18.442 -X-8.768Y18.604 -X-8.529Y18.771 -X-8.305Y18.940 -X-8.094Y19.113 -X-7.899Y19.290 -X-7.718Y19.470 -X-7.553Y19.653 -X-7.403Y19.839 -X-7.270Y20.029 -X-7.152Y20.221 -X-7.050Y20.417 -X-6.965Y20.616 -X-6.895Y20.818 -X-6.843Y21.023 -X-6.806Y21.230 -X-6.787Y21.441 -X-6.783Y21.654 -X-6.796Y21.870 -X-6.826Y22.088 -X-6.872Y22.309 -X-6.933Y22.532 -X-7.011Y22.758 -X-7.104Y22.986 -X-7.213Y23.217 -X-7.338Y23.449 -X-7.477Y23.684 -X-7.631Y23.921 -X-7.982Y24.401 -X-8.165Y24.627 -X-8.360Y24.855 -X-8.782Y25.315 -X-9.751Y26.251 -X-10.017Y26.488 -X-10.291Y26.726 -X-10.863Y27.204 -X-12.089Y28.170 -X-12.409Y28.413 -X-12.734Y28.657 -X-13.395Y29.145 -X-14.749Y30.124 -X-17.457Y32.077 -X-17.785Y32.320 -X-18.108Y32.561 -X-18.740Y33.042 -X-19.930Y33.994 -X-20.210Y34.229 -X-20.481Y34.463 -X-20.997Y34.927 -X-21.240Y35.157 -X-21.474Y35.386 -X-21.910Y35.838 -X-22.111Y36.062 -X-22.302Y36.284 -X-22.480Y36.505 -X-22.646Y36.723 -X-22.800Y36.940 -X-22.941Y37.155 -X-23.069Y37.367 -X-23.183Y37.578 -X-23.285Y37.786 -X-23.373Y37.993 -X-23.447Y38.197 -X-23.507Y38.398 -X-23.553Y38.598 -X-23.585Y38.795 -X-23.602Y38.989 -X-23.606Y39.181 -X-23.593Y39.386 -X-23.563Y39.588 -X-23.516Y39.787 -X-23.452Y39.983 -X-23.372Y40.175 -X-23.274Y40.364 -X-23.160Y40.550 -X-23.029Y40.732 -X-22.882Y40.910 -X-22.719Y41.086 -X-22.539Y41.257 -X-22.344Y41.425 -X-22.134Y41.589 -X-21.908Y41.749 -X-21.668Y41.906 -X-21.413Y42.059 -X-21.144Y42.208 -X-20.862Y42.353 -X-20.566Y42.494 -X-20.257Y42.631 -X-19.937Y42.763 -X-19.604Y42.892 -X-18.906Y43.138 -X-18.542Y43.254 -X-18.168Y43.366 -X-17.785Y43.474 -X-17.394Y43.578 -X-16.995Y43.678 -X-16.589Y43.773 -X-15.758Y43.950 -X-15.335Y44.033 -X-14.908Y44.111 -X-14.476Y44.184 -X-14.042Y44.253 -X-13.606Y44.318 -X-13.168Y44.379 -X-12.289Y44.486 -X-11.851Y44.534 -X-11.414Y44.576 -X-10.978Y44.615 -X-10.546Y44.649 -X-10.116Y44.679 -X-9.691Y44.704 -X-9.271Y44.726 -X-8.856Y44.742 -X-8.447Y44.755 -X-8.044Y44.763 -X-7.650Y44.767 -X-7.263Y44.766 -X-6.885Y44.762 -X-6.516Y44.753 -X-6.157Y44.740 -X-5.808Y44.723 -X-5.471Y44.702 -X-5.145Y44.676 -X-4.830Y44.647 -X-4.529Y44.613 -X-4.240Y44.576 -X-3.965Y44.535 -X-3.703Y44.489 -X-3.456Y44.440 -X-3.227Y44.388 -X-3.013Y44.332 -X-2.813Y44.273 -X-2.629Y44.210 -X-2.459Y44.144 -X-2.305Y44.074 -X-2.167Y44.001 -X-2.044Y43.925 -X-1.938Y43.845 -X-1.847Y43.762 -X-1.773Y43.675 -X-1.715Y43.586 -X-1.673Y43.494 -X-1.647Y43.398 -X-1.638Y43.299 -X-1.645Y43.198 -X-1.667Y43.094 -X-1.706Y42.987 -X-1.761Y42.877 -X-1.832Y42.765 -X-1.918Y42.650 -X-2.019Y42.532 -X-2.135Y42.412 -X-2.267Y42.290 -X-2.412Y42.166 -X-2.572Y42.039 -X-2.934Y41.779 -X-3.134Y41.646 -X-3.347Y41.511 -X-3.810Y41.235 -X-4.059Y41.095 -X-4.319Y40.953 -X-4.869Y40.664 -X-6.076Y40.071 -X-8.785Y38.840 -X-9.139Y38.683 -X-9.494Y38.526 -X-10.205Y38.212 -X-11.612Y37.583 -X-14.215Y36.343 -X-14.490Y36.201 -X-14.756Y36.061 -X-15.263Y35.782 -X-15.503Y35.645 -X-15.734Y35.508 -X-16.165Y35.239 -X-16.365Y35.106 -X-16.553Y34.975 -X-16.730Y34.845 -X-16.895Y34.717 -X-17.049Y34.590 -X-17.190Y34.465 -X-17.318Y34.341 -X-17.434Y34.219 -X-17.537Y34.099 -X-17.626Y33.981 -X-17.702Y33.865 -X-17.764Y33.751 -X-17.813Y33.639 -X-17.847Y33.528 -X-17.868Y33.420 -X-17.875Y33.315 -X-17.867Y33.211 -X-17.845Y33.110 -X-17.809Y33.011 -X-17.759Y32.914 -X-17.695Y32.820 -X-17.616Y32.728 -X-17.523Y32.639 -X-17.417Y32.552 -X-17.296Y32.468 -X-17.162Y32.387 -X-17.014Y32.308 -X-16.852Y32.232 -X-16.677Y32.159 -X-16.489Y32.089 -X-16.288Y32.021 -X-16.075Y31.956 -X-15.849Y31.895 -X-15.611Y31.836 -X-15.361Y31.780 -X-15.099Y31.727 -X-14.827Y31.677 -X-14.543Y31.631 -X-14.250Y31.587 -X-13.946Y31.547 -X-13.632Y31.509 -X-13.309Y31.475 -X-12.977Y31.444 -X-12.637Y31.417 -X-12.289Y31.392 -X-11.933Y31.371 -X-11.570Y31.353 -X-11.201Y31.338 -X-10.825Y31.327 -X-10.444Y31.319 -X-10.058Y31.314 -X-9.667Y31.313 -X-9.273Y31.315 -X-8.874Y31.320 -X-8.473Y31.329 -X-8.069Y31.341 -X-7.630Y31.358 -X-7.188Y31.379 -X-6.746Y31.404 -X-6.303Y31.433 -X-5.861Y31.466 -X-5.421Y31.503 -X-4.982Y31.544 -X-4.546Y31.589 -X-4.113Y31.638 -X-3.684Y31.691 -X-3.260Y31.748 -X-2.841Y31.809 -X-2.428Y31.873 -X-2.021Y31.942 -X-1.231Y32.091 -X-0.848Y32.171 -X-0.475Y32.255 -X-0.110Y32.343 -X0.243Y32.434 -X0.587Y32.530 -X0.919Y32.629 -X1.547Y32.838 -X1.842Y32.948 -X2.124Y33.061 -X2.392Y33.178 -X2.647Y33.299 -X2.887Y33.423 -X3.112Y33.550 -X3.323Y33.681 -X3.518Y33.815 -X3.698Y33.952 -X3.862Y34.092 -X4.010Y34.236 -X4.142Y34.383 -X4.257Y34.533 -X4.356Y34.685 -X4.439Y34.841 -X4.505Y35.000 -X4.554Y35.161 -X4.586Y35.325 -X4.602Y35.492 -X4.602Y35.662 -X4.584Y35.834 -X4.551Y36.008 -X4.501Y36.185 -X4.435Y36.364 -X4.353Y36.546 -X4.255Y36.730 -X4.142Y36.916 -X4.014Y37.104 -X3.871Y37.294 -X3.713Y37.486 -X3.356Y37.876 -X3.157Y38.073 -X2.944Y38.272 -X2.483Y38.675 -X1.425Y39.496 -X1.155Y39.690 -X0.877Y39.885 -X0.300Y40.277 -X-0.925Y41.070 -X-3.540Y42.667 -X-3.871Y42.867 -X-4.202Y43.066 -X-4.858Y43.463 -X-6.136Y44.252 -X-6.444Y44.447 -X-6.748Y44.642 -X-7.337Y45.028 -X-8.430Y45.788 -X-8.682Y45.975 -X-8.926Y46.161 -X-9.383Y46.527 -X-9.596Y46.708 -X-9.799Y46.887 -X-10.170Y47.241 -X-10.337Y47.415 -X-10.493Y47.587 -X-10.636Y47.757 -X-10.766Y47.925 -X-10.884Y48.091 -X-10.988Y48.255 -X-11.078Y48.416 -X-11.155Y48.576 -X-11.218Y48.733 -X-11.267Y48.888 -X-11.301Y49.040 -X-11.322Y49.190 -X-11.328Y49.337 -X-11.319Y49.482 -X-11.296Y49.624 -X-11.259Y49.763 -X-11.207Y49.900 -X-11.140Y50.033 -X-11.059Y50.164 -X-10.963Y50.293 -X-10.853Y50.418 -X-10.729Y50.540 -X-10.591Y50.659 -X-10.439Y50.775 -X-10.276Y50.886 -X-10.100Y50.994 -X-9.912Y51.098 -X-9.710Y51.200 -X-9.496Y51.298 -X-9.270Y51.394 -X-8.783Y51.574 -X-8.522Y51.660 -X-8.250Y51.742 -X-7.968Y51.821 -X-7.675Y51.897 -X-7.372Y51.969 -X-7.059Y52.038 -X-6.407Y52.165 -X-6.068Y52.223 -X-5.722Y52.278 -X-5.368Y52.330 -X-5.006Y52.378 -X-4.639Y52.422 -X-4.265Y52.463 -X-3.886Y52.500 -X-3.501Y52.533 -X-3.112Y52.563 -X-2.719Y52.590 -X-2.322Y52.613 -X-1.923Y52.632 -X-1.521Y52.647 -X-1.116Y52.659 -X-0.711Y52.667 -X-0.304Y52.672 -X0.103Y52.673 -X0.510Y52.670 -X0.916Y52.664 -X1.321Y52.654 -X1.724Y52.640 -X2.125Y52.623 -X2.524Y52.602 -X2.919Y52.577 -X3.310Y52.549 -X3.696Y52.517 -X4.078Y52.481 -X4.455Y52.442 -X4.826Y52.400 -X5.190Y52.354 -X5.548Y52.304 -X5.898Y52.251 -X6.241Y52.194 -X6.576Y52.134 -X6.902Y52.070 -X7.219Y52.003 -X7.526Y51.933 -X7.824Y51.859 -X8.389Y51.701 -X8.656Y51.617 -X8.911Y51.530 -X9.154Y51.439 -X9.386Y51.346 -X9.606Y51.249 -X9.814Y51.149 -X10.009Y51.046 -X10.191Y50.939 -X10.374Y50.821 -X10.541Y50.698 -X10.693Y50.573 -X10.829Y50.444 -X10.948Y50.311 -X11.052Y50.175 -X11.139Y50.036 -X11.209Y49.894 -X11.263Y49.748 -X11.301Y49.600 -X11.323Y49.448 -X11.327Y49.293 -X11.316Y49.136 -X11.288Y48.975 -X11.245Y48.812 -X11.185Y48.646 -X11.109Y48.478 -X11.018Y48.307 -X10.912Y48.133 -X10.790Y47.957 -X10.654Y47.779 -X10.503Y47.598 -X10.159Y47.230 -X9.967Y47.043 -X9.762Y46.854 -X9.314Y46.470 -X8.282Y45.681 -X7.999Y45.480 -X7.707Y45.278 -X7.098Y44.870 -X5.798Y44.041 -X3.014Y42.350 -X2.662Y42.138 -X2.311Y41.925 -X1.617Y41.500 -X0.273Y40.654 -X-0.049Y40.444 -X-0.365Y40.234 -X-0.975Y39.817 -X-2.088Y38.994 -X-2.324Y38.805 -X-2.551Y38.617 -X-2.974Y38.245 -X-3.170Y38.061 -X-3.354Y37.878 -X-3.687Y37.516 -X-3.836Y37.338 -X-3.972Y37.162 -X-4.096Y36.987 -X-4.206Y36.813 -X-4.304Y36.642 -X-4.388Y36.473 -X-4.459Y36.305 -X-4.515Y36.139 -X-4.558Y35.976 -X-4.587Y35.815 -X-4.602Y35.655 -X-4.603Y35.498 -X-4.589Y35.343 -X-4.561Y35.191 -X-4.519Y35.041 -X-4.462Y34.893 -X-4.391Y34.748 -X-4.306Y34.605 -X-4.207Y34.465 -X-4.094Y34.327 -X-3.967Y34.192 -X-3.826Y34.060 -X-3.671Y33.930 -X-3.503Y33.803 -X-3.321Y33.679 -X-3.126Y33.558 -X-2.919Y33.440 -X-2.698Y33.324 -X-2.466Y33.212 -X-2.221Y33.102 -X-1.697Y32.893 -X-1.418Y32.792 -X-1.128Y32.695 -X-0.828Y32.601 -X-0.518Y32.510 -X-0.198Y32.422 -X0.131Y32.338 -X0.814Y32.178 -X1.168Y32.104 -X1.529Y32.032 -X1.897Y31.964 -X2.271Y31.899 -X2.651Y31.838 -X3.037Y31.780 -X3.822Y31.674 -X4.221Y31.626 -X4.622Y31.581 -X5.027Y31.540 -X5.434Y31.502 -X5.842Y31.468 -X6.252Y31.437 -X6.662Y31.410 -X7.072Y31.386 -X7.515Y31.363 -X7.957Y31.345 -X8.398Y31.331 -X8.835Y31.321 -X9.269Y31.315 -X9.699Y31.313 -X10.123Y31.315 -X10.543Y31.321 -X10.956Y31.330 -X11.362Y31.344 -X11.761Y31.362 -X12.152Y31.383 -X12.534Y31.409 -X12.907Y31.438 -X13.269Y31.471 -X13.622Y31.508 -X13.963Y31.549 -X14.293Y31.593 -X14.611Y31.641 -X14.916Y31.693 -X15.209Y31.749 -X15.487Y31.808 -X15.753Y31.870 -X16.003Y31.936 -X16.240Y32.006 -X16.461Y32.079 -X16.667Y32.155 -X16.858Y32.235 -X17.033Y32.318 -X17.191Y32.404 -X17.334Y32.493 -X17.460Y32.586 -X17.570Y32.681 -X17.662Y32.780 -X17.739Y32.881 -X17.798Y32.986 -X17.840Y33.093 -X17.866Y33.203 -X17.875Y33.316 -X17.867Y33.431 -X17.842Y33.549 -X17.801Y33.670 -X17.743Y33.793 -X17.669Y33.918 -X17.579Y34.045 -X17.473Y34.175 -X17.352Y34.307 -X17.215Y34.441 -X17.063Y34.577 -X16.897Y34.715 -X16.522Y34.997 -X16.314Y35.140 -X16.093Y35.285 -X15.614Y35.580 -X15.357Y35.729 -X15.089Y35.879 -X14.522Y36.184 -X13.280Y36.806 -X12.957Y36.960 -X12.628Y37.115 -X11.954Y37.427 -X10.561Y38.054 -X7.746Y39.303 -X7.404Y39.457 -X7.067Y39.611 -X6.409Y39.915 -X5.172Y40.511 -X4.883Y40.657 -X4.603Y40.802 -X4.074Y41.087 -X3.825Y41.227 -X3.588Y41.365 -X3.148Y41.636 -X2.947Y41.769 -X2.760Y41.900 -X2.585Y42.029 -X2.425Y42.156 -X2.278Y42.280 -X2.146Y42.402 -X2.028Y42.522 -X1.926Y42.639 -X1.839Y42.754 -X1.767Y42.866 -X1.711Y42.976 -X1.671Y43.083 -X1.646Y43.187 -X1.638Y43.289 -X1.645Y43.387 -X1.669Y43.483 -X1.709Y43.576 -X1.765Y43.665 -X1.838Y43.752 -X1.926Y43.835 -X2.030Y43.915 -X2.150Y43.992 -X2.286Y44.065 -X2.438Y44.135 -X2.605Y44.202 -X2.787Y44.265 -X2.984Y44.324 -X3.195Y44.380 -X3.421Y44.433 -X3.661Y44.481 -X3.915Y44.526 -X4.182Y44.568 -X4.443Y44.603 -X4.714Y44.635 -X4.996Y44.663 -X5.289Y44.688 -X5.591Y44.710 -X5.902Y44.728 -X6.223Y44.743 -X6.552Y44.754 -X6.890Y44.762 -X7.235Y44.766 -X7.587Y44.767 -X7.946Y44.764 -X8.311Y44.758 -X8.683Y44.748 -X9.059Y44.735 -X9.440Y44.717 -X9.826Y44.697 -X10.216Y44.672 -X10.608Y44.644 -X11.004Y44.613 -X11.401Y44.578 -X11.800Y44.539 -X12.602Y44.450 -X13.003Y44.400 -X13.403Y44.347 -X13.803Y44.289 -X14.201Y44.229 -X14.596Y44.164 -X14.990Y44.096 -X15.766Y43.949 -X16.148Y43.870 -X16.525Y43.787 -X17.263Y43.611 -X17.623Y43.518 -X17.976Y43.421 -X18.661Y43.217 -X18.991Y43.109 -X19.313Y42.999 -X19.626Y42.884 -X19.929Y42.767 -X20.223Y42.645 -X20.506Y42.521 -X21.041Y42.262 -X21.292Y42.127 -X21.531Y41.990 -X21.758Y41.849 -X21.974Y41.704 -X22.176Y41.557 -X22.366Y41.407 -X22.544Y41.253 -X22.708Y41.097 -X22.859Y40.937 -X22.996Y40.775 -X23.119Y40.609 -X23.229Y40.441 -X23.325Y40.269 -X23.407Y40.095 -X23.475Y39.919 -X23.529Y39.739 -X23.571Y39.541 -X23.597Y39.341 -X23.606Y39.137 -X23.599Y38.930 -X23.575Y38.721 -X23.534Y38.508 -X23.477Y38.293 -X23.404Y38.075 -X23.315Y37.855 -X23.211Y37.632 -X23.091Y37.406 -X22.955Y37.178 -X22.805Y36.948 -X22.640Y36.716 -X22.268Y36.244 -X22.061Y36.005 -X21.841Y35.765 -X21.364Y35.278 -X20.274Y34.284 -X19.975Y34.031 -X19.668Y33.778 -X19.029Y33.267 -X17.670Y32.234 -X17.316Y31.974 -X16.959Y31.713 -X16.236Y31.190 -X14.771Y30.140 -X14.405Y29.877 -X14.040Y29.614 -X13.319Y29.089 -X11.923Y28.043 -X11.588Y27.783 -X11.260Y27.524 -X10.626Y27.008 -X10.322Y26.752 -X10.027Y26.497 -X9.467Y25.990 -X9.203Y25.738 -X8.951Y25.488 -X8.482Y24.992 -X8.266Y24.747 -X8.064Y24.503 -X7.700Y24.021 -X7.550Y23.799 -X7.412Y23.578 -X7.288Y23.359 -X7.177Y23.143 -X7.079Y22.928 -X6.995Y22.715 -X6.925Y22.504 -X6.868Y22.295 -X6.826Y22.089 -X6.798Y21.884 -X6.784Y21.682 -X6.785Y21.483 -X6.800Y21.285 -X6.829Y21.091 -X6.873Y20.898 -X6.931Y20.708 -X7.003Y20.521 -X7.090Y20.336 -X7.191Y20.154 -X7.306Y19.975 -X7.434Y19.799 -X7.577Y19.625 -X7.733Y19.454 -X7.903Y19.286 -X8.085Y19.121 -X8.281Y18.959 -X8.489Y18.800 -X8.710Y18.644 -X8.943Y18.491 -X9.188Y18.341 -X9.711Y18.051 -X9.989Y17.910 -X10.278Y17.773 -X10.884Y17.508 -X11.201Y17.381 -X11.527Y17.257 -X12.203Y17.019 -X12.552Y16.905 -X12.908Y16.795 -X13.639Y16.584 -X14.012Y16.484 -X14.390Y16.387 -X15.159Y16.204 -X15.548Y16.118 -X15.940Y16.035 -X16.729Y15.880 -X17.126Y15.808 -X17.522Y15.739 -X18.315Y15.612 -X18.709Y15.554 -X19.102Y15.499 -X19.492Y15.448 -X19.879Y15.401 -X20.263Y15.357 -X20.642Y15.316 -X21.017Y15.279 -X21.387Y15.245 -X21.744Y15.215 -X22.095Y15.189 -X22.440Y15.166 -X22.778Y15.146 -X23.109Y15.129 -X23.431Y15.116 -X23.746Y15.106 -X24.052Y15.099 -X24.349Y15.095 -X24.636Y15.095 -X24.914Y15.097 -X25.181Y15.103 -X25.438Y15.112 -X25.684Y15.123 -X25.919Y15.138 -X26.142Y15.156 -X26.354Y15.177 -X26.553Y15.200 -X26.740Y15.227 -X26.914Y15.256 -X27.076Y15.288 -X27.225Y15.323 -X27.360Y15.361 -X27.482Y15.402 -X27.591Y15.445 -X27.686Y15.491 -X27.767Y15.539 -X27.835Y15.590 -X27.888Y15.643 -X27.928Y15.699 -X27.954Y15.757 -X27.965Y15.818 -X27.963Y15.881 -X27.947Y15.946 -X27.917Y16.014 -X27.873Y16.083 -X27.816Y16.155 -X27.744Y16.229 -X27.660Y16.305 -X27.562Y16.382 -X27.451Y16.462 -X27.327Y16.544 -X27.042Y16.712 -X26.881Y16.799 -X26.707Y16.887 -X26.326Y17.069 -X26.118Y17.162 -X25.900Y17.256 -X25.433Y17.449 -X24.385Y17.849 -X21.934Y18.690 -X21.575Y18.807 -X21.212Y18.925 -X20.474Y19.161 -X18.977Y19.635 -X16.040Y20.572 -X15.691Y20.686 -X15.348Y20.800 -X14.684Y21.024 -X13.458Y21.457 -X13.176Y21.562 -X12.904Y21.666 -X12.396Y21.868 -X12.159Y21.966 -X11.936Y22.063 -X11.528Y22.250 -X11.345Y22.340 -X11.176Y22.429 -X11.022Y22.515 -X10.882Y22.599 -X10.757Y22.681 -X10.648Y22.760 -X10.554Y22.836 -X10.476Y22.910 -X10.413Y22.982 -X10.367Y23.051 -X10.337Y23.117 -X10.323Y23.180 -X10.325Y23.240 -X10.344Y23.298 -X10.379Y23.352 -X10.430Y23.403 -X10.497Y23.452 -X10.580Y23.497 -X10.680Y23.538 -X10.795Y23.577 -X10.926Y23.612 -X11.072Y23.644 -X11.233Y23.673 -X11.410Y23.698 -X11.601Y23.719 -X11.807Y23.737 -X12.027Y23.751 -X12.260Y23.762 -X12.507Y23.769 -X12.767Y23.772 -X13.040Y23.771 -X13.325Y23.767 -X13.601Y23.760 -X13.887Y23.749 -X14.182Y23.734 -X14.486Y23.717 -X14.799Y23.696 -X15.120Y23.671 -X15.448Y23.643 -X15.784Y23.612 -X16.126Y23.577 -X16.475Y23.538 -X16.829Y23.496 -X17.188Y23.450 -X17.552Y23.401 -X17.921Y23.348 -X18.667Y23.232 -X19.045Y23.169 -X19.424Y23.102 -X20.187Y22.957 -X20.569Y22.879 -X20.951Y22.797 -X21.712Y22.623 -X22.090Y22.531 -X22.466Y22.435 -X23.208Y22.232 -X23.574Y22.125 -X23.935Y22.015 -X24.641Y21.784 -X24.985Y21.663 -X25.323Y21.538 -X25.977Y21.279 -X26.292Y21.144 -X26.599Y21.006 -X27.186Y20.719 -X27.465Y20.571 -X27.734Y20.419 -X27.993Y20.264 -X28.241Y20.106 -X28.477Y19.944 -X28.702Y19.779 -X29.116Y19.440 -X29.305Y19.266 -X29.481Y19.088 -X29.644Y18.908 -X29.794Y18.724 -X29.930Y18.538 -X30.053Y18.349 -X30.162Y18.156 -X30.258Y17.961 -X30.339Y17.763 -X30.406Y17.563 -X30.459Y17.359 -X30.498Y17.153 -X30.522Y16.944 -X30.532Y16.733 -X30.528Y16.519 -X30.510Y16.303 -X30.474Y16.066 -X30.421Y15.826 -X30.352Y15.583 -X30.266Y15.337 -X30.164Y15.089 -X30.046Y14.839 -X29.912Y14.586 -X29.762Y14.330 -X29.597Y14.073 -X29.417Y13.813 -X29.014Y13.287 -X28.791Y13.021 -X28.555Y12.753 -X28.044Y12.211 -X27.769Y11.938 -X27.483Y11.663 -X26.879Y11.109 -X25.553Y9.985 -X22.573Y7.693 -X22.183Y7.405 -X21.791Y7.116 -X21.005Y6.537 -X19.442Y5.382 -X19.058Y5.094 -X18.678Y4.806 -X17.931Y4.232 -X16.513Y3.095 -X16.178Y2.813 -X15.852Y2.532 -X15.229Y1.974 -X14.933Y1.697 -X14.649Y1.422 -X14.115Y0.876 -X13.867Y0.606 -X13.632Y0.337 -X13.411Y0.071 -X13.204Y-0.194 -X13.010Y-0.457 -X12.832Y-0.717 -X12.668Y-0.976 -X12.520Y-1.232 -X12.395Y-1.469 -X12.284Y-1.703 -X12.188Y-1.936 -X12.105Y-2.167 -X12.036Y-2.395 -X11.982Y-2.621 -X11.942Y-2.844 -X11.916Y-3.065 -X11.905Y-3.284 -X11.908Y-3.500 -X11.926Y-3.713 -X11.959Y-3.924 -X12.005Y-4.132 -X12.067Y-4.338 -X12.142Y-4.540 -X12.232Y-4.740 -X12.336Y-4.937 -X12.453Y-5.131 -X12.584Y-5.322 -X12.729Y-5.510 -X12.887Y-5.695 -X13.059Y-5.877 -X13.243Y-6.055 -X13.439Y-6.231 -X13.648Y-6.403 -X13.869Y-6.572 -X14.101Y-6.738 -X14.345Y-6.901 -X14.599Y-7.060 -X14.864Y-7.216 -X15.423Y-7.518 -X15.717Y-7.664 -X16.020Y-7.806 -X16.650Y-8.080 -X16.976Y-8.212 -X17.309Y-8.340 -X17.994Y-8.586 -X18.344Y-8.704 -X18.700Y-8.818 -X19.423Y-9.035 -X20.902Y-9.426 -X21.276Y-9.515 -X21.650Y-9.600 -X22.396Y-9.759 -X22.767Y-9.833 -X23.137Y-9.903 -X23.868Y-10.033 -X24.228Y-10.092 -X24.584Y-10.148 -X24.936Y-10.200 -X25.282Y-10.249 -X25.622Y-10.294 -X25.956Y-10.336 -X26.604Y-10.408 -X26.910Y-10.438 -X27.208Y-10.465 -X27.498Y-10.489 -X27.779Y-10.509 -X28.051Y-10.527 -X28.313Y-10.540 -X28.565Y-10.551 -X28.807Y-10.558 -X29.038Y-10.562 -X29.258Y-10.563 -X29.466Y-10.561 -X29.663Y-10.556 -X29.848Y-10.547 -X30.020Y-10.536 -X30.180Y-10.522 -X30.327Y-10.504 -X30.462Y-10.484 -X30.583Y-10.461 -X30.690Y-10.435 -X30.784Y-10.406 -X30.865Y-10.374 -X30.932Y-10.340 -X30.984Y-10.303 -X31.023Y-10.263 -X31.048Y-10.221 -X31.058Y-10.176 -X31.055Y-10.128 -X31.037Y-10.078 -X31.006Y-10.026 -X30.960Y-9.971 -X30.900Y-9.914 -X30.827Y-9.855 -X30.739Y-9.794 -X30.638Y-9.730 -X30.524Y-9.664 -X30.396Y-9.596 -X30.255Y-9.527 -X30.100Y-9.455 -X29.754Y-9.306 -X29.562Y-9.228 -X29.359Y-9.149 -X28.917Y-8.986 -X27.902Y-8.642 -X27.624Y-8.553 -X27.336Y-8.462 -X26.734Y-8.278 -X25.440Y-7.896 -X22.592Y-7.100 -X22.191Y-6.990 -X21.787Y-6.879 -X20.978Y-6.659 -X19.371Y-6.218 -X18.976Y-6.109 -X18.584Y-6.000 -X17.814Y-5.783 -X16.349Y-5.360 -X16.002Y-5.257 -X15.664Y-5.155 -X15.016Y-4.954 -X14.708Y-4.856 -X14.410Y-4.759 -X13.850Y-4.569 -X13.589Y-4.477 -X13.340Y-4.387 -X12.883Y-4.212 -X12.675Y-4.127 -X12.482Y-4.045 -X12.140Y-3.886 -X11.991Y-3.810 -X11.859Y-3.737 -X11.741Y-3.665 -X11.640Y-3.597 -X11.555Y-3.531 -X11.486Y-3.467 -X11.433Y-3.406 -X11.397Y-3.348 -X11.377Y-3.293 -X11.373Y-3.241 -X11.386Y-3.191 -X11.415Y-3.145 -X11.460Y-3.101 -X11.522Y-3.061 -X11.600Y-3.024 -X11.694Y-2.990 -X11.803Y-2.959 -X11.928Y-2.932 -X12.068Y-2.908 -X12.223Y-2.887 -X12.393Y-2.870 -X12.578Y-2.856 -X12.776Y-2.846 -X12.989Y-2.840 -X13.214Y-2.837 -X13.453Y-2.838 -X13.704Y-2.842 -X13.967Y-2.850 -X14.242Y-2.862 -X14.527Y-2.878 -X14.824Y-2.897 -X15.130Y-2.921 -X15.425Y-2.946 -X15.727Y-2.975 -X16.037Y-3.007 -X16.353Y-3.042 -X16.676Y-3.081 -X17.005Y-3.124 -X17.678Y-3.219 -X18.021Y-3.272 -X18.368Y-3.329 -X19.071Y-3.452 -X19.426Y-3.519 -X19.783Y-3.590 -X20.499Y-3.742 -X20.857Y-3.823 -X21.214Y-3.908 -X21.925Y-4.088 -X22.277Y-4.183 -X22.626Y-4.282 -X23.314Y-4.491 -X23.652Y-4.600 -X23.984Y-4.713 -X24.632Y-4.949 -X24.947Y-5.073 -X25.254Y-5.199 -X25.846Y-5.463 -X26.129Y-5.600 -X26.404Y-5.740 -X26.669Y-5.884 -X26.925Y-6.031 -X27.170Y-6.181 -X27.405Y-6.334 -X27.842Y-6.650 -X28.043Y-6.813 -X28.232Y-6.979 -X28.409Y-7.149 -X28.573Y-7.321 -X28.725Y-7.496 -X28.863Y-7.674 -X28.989Y-7.855 -X29.101Y-8.039 -X29.199Y-8.226 -X29.283Y-8.416 -X29.353Y-8.609 -X29.409Y-8.804 -X29.451Y-9.002 -X29.479Y-9.203 -X29.492Y-9.406 -X29.491Y-9.612 -X29.475Y-9.820 -X29.445Y-10.031 -X29.401Y-10.244 -X29.342Y-10.459 -X29.269Y-10.677 -X29.181Y-10.897 -X29.080Y-11.119 -X28.964Y-11.344 -X28.823Y-11.589 -X28.666Y-11.837 -X28.493Y-12.087 -X28.305Y-12.340 -X28.102Y-12.594 -X27.883Y-12.851 -X27.403Y-13.370 -X27.142Y-13.632 -X26.868Y-13.897 -X26.281Y-14.430 -X24.969Y-15.514 -X24.615Y-15.788 -X24.252Y-16.064 -X23.501Y-16.617 -X21.917Y-17.734 -X18.570Y-19.985 -X18.148Y-20.266 -X17.729Y-20.547 -X16.897Y-21.108 -X15.285Y-22.222 -X14.896Y-22.498 -X14.515Y-22.774 -X13.775Y-23.321 -X12.409Y-24.400 -X12.095Y-24.666 -X11.792Y-24.930 -X11.223Y-25.453 -X10.958Y-25.712 -X10.707Y-25.968 -X10.246Y-26.475 -X10.038Y-26.725 -X9.845Y-26.973 -X9.667Y-27.218 -X9.505Y-27.461 -X9.359Y-27.702 -X9.229Y-27.940 -X9.115Y-28.175 -X9.017Y-28.407 -X8.938Y-28.632 -X8.874Y-28.855 -X8.827Y-29.074 -X8.796Y-29.291 -X8.781Y-29.505 -X8.782Y-29.716 -X8.799Y-29.923 -X8.833Y-30.128 -X8.882Y-30.329 -X8.947Y-30.527 -X9.028Y-30.722 -X9.125Y-30.914 -X9.236Y-31.102 -X9.363Y-31.286 -X9.505Y-31.467 -X9.661Y-31.645 -X9.832Y-31.819 -X10.016Y-31.989 -X10.214Y-32.155 -X10.425Y-32.318 -X10.649Y-32.477 -X10.885Y-32.633 -X11.393Y-32.932 -X11.664Y-33.076 -X11.945Y-33.215 -X12.536Y-33.483 -X12.846Y-33.611 -X13.163Y-33.735 -X13.821Y-33.971 -X14.160Y-34.082 -X14.504Y-34.190 -X15.209Y-34.393 -X15.568Y-34.488 -X15.930Y-34.579 -X16.661Y-34.748 -X17.029Y-34.827 -X17.397Y-34.901 -X17.766Y-34.971 -X18.134Y-35.037 -X18.501Y-35.099 -X18.865Y-35.157 -X19.585Y-35.260 -X19.940Y-35.305 -X20.290Y-35.346 -X20.634Y-35.383 -X20.973Y-35.416 -X21.305Y-35.444 -X21.630Y-35.469 -X21.947Y-35.490 -X22.256Y-35.506 -X22.556Y-35.519 -X22.847Y-35.527 -X23.128Y-35.532 -X23.398Y-35.532 -X23.657Y-35.529 -X23.904Y-35.522 -X24.140Y-35.511 -X24.363Y-35.496 -X24.559Y-35.479 -X24.745Y-35.459 -X24.918Y-35.435 -X25.079Y-35.408 -X25.228Y-35.378 -X25.364Y-35.345 -X25.487Y-35.309 -X25.597Y-35.269 -X25.694Y-35.227 -X25.777Y-35.182 -X25.847Y-35.133 -X25.902Y-35.082 -X25.944Y-35.028 -X25.972Y-34.972 -X25.986Y-34.912 -X25.986Y-34.850 -X25.971Y-34.785 -X25.942Y-34.717 -X25.899Y-34.647 -X25.842Y-34.575 -X25.771Y-34.499 -X25.685Y-34.422 -X25.586Y-34.342 -X25.472Y-34.260 -X25.345Y-34.175 -X25.204Y-34.088 -X24.883Y-33.909 -X24.702Y-33.815 -X24.509Y-33.720 -X24.085Y-33.525 -X23.855Y-33.424 -X23.613Y-33.321 -X23.095Y-33.112 -X21.933Y-32.673 -X19.198Y-31.738 -X12.952Y-29.747 -X12.533Y-29.612 -X12.117Y-29.477 -X11.302Y-29.208 -X9.752Y-28.680 -X9.384Y-28.550 -X9.026Y-28.422 -X8.340Y-28.168 -X7.104Y-27.677 -X6.826Y-27.559 -X6.561Y-27.442 -X6.073Y-27.213 -X5.850Y-27.102 -X5.643Y-26.992 -X5.272Y-26.780 -X5.111Y-26.677 -X4.965Y-26.577 -X4.835Y-26.479 -X4.721Y-26.383 -X4.623Y-26.290 -X4.542Y-26.199 -X4.478Y-26.112 -X4.430Y-26.026 -X4.398Y-25.944 -X4.384Y-25.865 -X4.385Y-25.788 -X4.403Y-25.714 -X4.438Y-25.644 -X4.489Y-25.576 -X4.556Y-25.512 -X4.639Y-25.450 -X4.738Y-25.392 -X4.852Y-25.337 -X4.981Y-25.286 -X5.126Y-25.238 -X5.285Y-25.193 -X5.458Y-25.152 -X5.646Y-25.115 -X5.847Y-25.080 -X6.061Y-25.050 -X6.287Y-25.023 -X6.527Y-25.000 -X6.777Y-24.980 -X7.040Y-24.964 -X7.313Y-24.952 -X7.596Y-24.944 -X7.889Y-24.939 -X8.191Y-24.939 -X8.502Y-24.942 -X8.820Y-24.949 -X9.146Y-24.960 -X9.478Y-24.975 -X9.817Y-24.994 -X10.161Y-25.017 -X10.510Y-25.044 -X10.839Y-25.072 -X11.171Y-25.104 -X11.506Y-25.140 -X11.842Y-25.179 -X12.180Y-25.221 -X12.519Y-25.267 -X13.196Y-25.370 -X13.534Y-25.427 -X13.870Y-25.487 -X14.204Y-25.550 -X14.535Y-25.617 -X14.864Y-25.688 -X15.188Y-25.762 -X15.824Y-25.920 -X16.134Y-26.004 -X16.438Y-26.092 -X16.736Y-26.183 -X17.027Y-26.277 -X17.311Y-26.375 -X17.587Y-26.476 -X18.113Y-26.689 -X18.362Y-26.800 -X18.602Y-26.914 -X18.832Y-27.032 -X19.052Y-27.152 -X19.260Y-27.276 -X19.457Y-27.403 -X19.643Y-27.534 -X19.817Y-27.667 -X19.979Y-27.803 -X20.128Y-27.943 -X20.264Y-28.085 -X20.387Y-28.230 -X20.497Y-28.379 -X20.594Y-28.530 -X20.676Y-28.684 -X20.745Y-28.840 -X20.800Y-29.000 -X20.841Y-29.162 -X20.867Y-29.327 -X20.879Y-29.494 -X20.876Y-29.664 -X20.859Y-29.837 -X20.828Y-30.012 -X20.781Y-30.189 -X20.721Y-30.369 -X20.645Y-30.551 -X20.556Y-30.735 -X20.452Y-30.922 -X20.333Y-31.110 -X20.201Y-31.301 -X20.055Y-31.494 -X19.894Y-31.688 -X19.721Y-31.885 -X19.533Y-32.084 -X19.120Y-32.486 -X18.893Y-32.690 -X18.655Y-32.896 -X18.142Y-33.311 -X17.874Y-33.517 -X17.595Y-33.724 -X17.007Y-34.142 -X15.720Y-34.991 -X12.798Y-36.727 -X12.410Y-36.947 -X12.018Y-37.167 -X11.225Y-37.607 -X9.621Y-38.487 -X6.455Y-40.236 -X6.074Y-40.452 -X5.697Y-40.668 -X4.960Y-41.096 -X3.566Y-41.941 -X3.237Y-42.149 -X2.916Y-42.356 -X2.302Y-42.766 -X1.194Y-43.568 -X0.944Y-43.764 -X0.706Y-43.959 -X0.264Y-44.342 -X0.062Y-44.531 -X-0.128Y-44.718 -X-0.469Y-45.085 -X-0.620Y-45.266 -X-0.758Y-45.444 -X-0.882Y-45.620 -X-0.993Y-45.794 -X-1.090Y-45.965 -X-1.173Y-46.134 -X-1.243Y-46.301 -X-1.298Y-46.465 -X-1.342Y-46.640 -X-1.371Y-46.812 -X-1.382Y-46.980 -X-1.378Y-47.146 -X-1.357Y-47.308 -X-1.320Y-47.467 -X-1.267Y-47.622 -X-1.198Y-47.775 -X-1.114Y-47.923 -X-1.014Y-48.068 -X-0.899Y-48.210 -X-0.769Y-48.348 -X-0.625Y-48.482 -X-0.466Y-48.612 -X-0.293Y-48.739 -X-0.107Y-48.862 -X0.093Y-48.981 -X0.305Y-49.097 -X0.530Y-49.208 -X0.766Y-49.315 -X1.014Y-49.419 -X1.273Y-49.518 -X1.822Y-49.705 -X2.110Y-49.792 -X2.407Y-49.875 -X2.713Y-49.954 -X3.026Y-50.029 -X3.346Y-50.100 -X3.672Y-50.166 -X4.004Y-50.229 -X4.341Y-50.287 -X4.683Y-50.340 -X5.028Y-50.390 -X5.376Y-50.435 -X5.727Y-50.476 -X6.080Y-50.513 -X6.433Y-50.545 -X6.787Y-50.573 -X7.141Y-50.597 -X7.494Y-50.617 -X7.845Y-50.632 -X8.194Y-50.643 -X8.540Y-50.650 -X8.882Y-50.652 -X9.220Y-50.651 -X9.553Y-50.645 -X9.881Y-50.635 -X10.202Y-50.620 -X10.516Y-50.602 -X10.823Y-50.579 -X11.122Y-50.552 -X11.412Y-50.521 -X11.693Y-50.486 -X11.964Y-50.447 -X12.225Y-50.404 -X12.475Y-50.356 -X12.714Y-50.305 -X12.941Y-50.250 -X13.155Y-50.191 -X13.357Y-50.128 -X13.546Y-50.061 -X13.721Y-49.990 -X13.882Y-49.916 -X14.020Y-49.843 -X14.144Y-49.767 -X14.256Y-49.688 -X14.355Y-49.605 -X14.441Y-49.520 -X14.513Y-49.431 -X14.571Y-49.340 -X14.615Y-49.245 -X14.645Y-49.148 -X14.662Y-49.048 -X14.664Y-48.944 -X14.651Y-48.838 -X14.625Y-48.730 -X14.584Y-48.618 -X14.529Y-48.504 -X14.459Y-48.387 -X14.376Y-48.268 -X14.278Y-48.146 -X14.166Y-48.022 -X14.040Y-47.896 -X13.900Y-47.767 -X13.747Y-47.635 -X13.399Y-47.366 -X13.206Y-47.228 -X12.999Y-47.088 -X12.548Y-46.803 -X11.504Y-46.209 -X11.215Y-46.057 -X10.916Y-45.902 -X10.287Y-45.589 -X8.923Y-44.948 -X5.870Y-43.614 -X5.468Y-43.444 -X5.063Y-43.274 -X4.246Y-42.931 -X2.603Y-42.244 -X-0.599Y-40.871 -X-1.025Y-40.682 -X-1.444Y-40.493 -X-2.257Y-40.118 -X-3.764Y-39.380 -X-4.113Y-39.199 -X-4.450Y-39.019 -X-5.084Y-38.665 -X-5.380Y-38.490 -X-5.662Y-38.317 -X-6.181Y-37.977 -X-6.417Y-37.810 -X-6.637Y-37.645 -X-6.841Y-37.483 -X-7.028Y-37.322 -X-7.199Y-37.165 -X-7.352Y-37.009 -X-7.488Y-36.856 -X-7.607Y-36.706 -X-7.708Y-36.559 -X-7.791Y-36.414 -X-7.856Y-36.272 -X-7.904Y-36.133 -X-7.934Y-35.997 -X-7.946Y-35.864 -X-7.941Y-35.734 -X-7.918Y-35.608 -X-7.877Y-35.484 -X-7.819Y-35.364 -X-7.744Y-35.247 -X-7.652Y-35.134 -X-7.543Y-35.024 -X-7.418Y-34.918 -X-7.277Y-34.815 -X-7.121Y-34.716 -X-6.949Y-34.620 -X-6.762Y-34.528 -X-6.560Y-34.440 -X-6.345Y-34.356 -X-6.116Y-34.276 -X-5.874Y-34.199 -X-5.620Y-34.127 -X-5.353Y-34.058 -X-5.076Y-33.993 -X-4.787Y-33.933 -X-4.489Y-33.876 -X-4.181Y-33.824 -X-3.864Y-33.775 -X-3.539Y-33.731 -X-3.207Y-33.691 -X-2.867Y-33.655 -X-2.522Y-33.623 -X-2.172Y-33.596 -X-1.817Y-33.572 -X-1.458Y-33.553 -X-1.096Y-33.538 -X-0.732Y-33.528 -X-0.366Y-33.521 -X0.000Y-33.519 -G0Z6.000 -G0X37.560Y12.327Z6.000 -G1Z-1.000 -G1Y0.876 -X49.011 -Y12.327 -X37.560 -G0Z6.000 -G0Y0.876 -G1Z-1.000 -G1Y-10.575 -X49.011 -Y0.876 -X37.560 -G0Z6.000 -G0X49.011Y12.327 -G1Z-1.000 -G1X52.084Y15.011 -G0Z6.000 -G0X49.011Y0.876 -G1Z-1.000 -G1X52.084Y6.213 -Y15.011 -X43.286 -X37.560Y12.327 -G0Z6.000 -G0X49.011Y-10.575 -G1Z-1.000 -G1X52.084Y-2.585 -Y6.213 -X49.011Y0.876 -G0Z6.000 -G0Z20.000 -G0X0.000Y0.000 -M30 diff --git a/test/settings/kikigey89.settings b/test/settings/kikigey89.settings deleted file mode 100644 index e367d5011..000000000 --- a/test/settings/kikigey89.settings +++ /dev/null @@ -1,31 +0,0 @@ -(Machine settings provided by @kikigey89) -$0=87.489 (x, step/mm) -$1=87.489 (y, step/mm) -$2=1280.000 (z, step/mm) -$3=1000.000 (x max rate, mm/min) -$4=1000.000 (y max rate, mm/min) -$5=500.000 (z max rate, mm/min) -$6=10.000 (x accel, mm/sec^2) -$7=10.000 (y accel, mm/sec^2) -$8=10.000 (z accel, mm/sec^2) -$9=211.000 (x max travel, mm) -$10=335.000 (y max travel, mm) -$11=70.000 (z max travel, mm) -$12=20 (step pulse, usec) -$13=160 (step port invert mask:10100000) -$14=160 (dir port invert mask:10100000) -$15=50 (step idle delay, msec) -$16=0.010 (junction deviation, mm) -$17=0.002 (arc tolerance, mm) -$19=0 (report inches, bool) -$20=1 (auto start, bool) -$21=0 (invert step enable, bool) -$22=0 (invert limit pins, bool) -$23=0 (soft limits, bool) -$24=0 (hard limits, bool) -$25=0 (homing cycle, bool) -$26=0 (homing dir invert mask:00000000) -$27=50.000 (homing feed, mm/min) -$28=500.000 (homing seek, mm/min) -$29=10 (homing debounce, msec) -$30=3.000 (homing pull-off, mm) \ No newline at end of file diff --git a/test/test.py b/test/test.py deleted file mode 100644 index 41c845c82..000000000 --- a/test/test.py +++ /dev/null @@ -1,25 +0,0 @@ -import random -import serial -import time -ser = serial.Serial('/dev/tty.usbmodem24111', 115200, timeout=0.001) -time.sleep(1) -outstanding = 0 -data = '' -while True: - time.sleep(0.1) - data += ser.read() - pos = data.find('\n') - if pos == -1: - line = '' - else: - line = data[0:pos + 1] - data = data[pos + 1:] - if line == '' and outstanding < 3: - while outstanding < 3: - ser.write("G0 Z%0.3f\n" % (0.01 * (random.random() - 0.5))) - #ser.write("M3\n") - outstanding += 1 - continue - if line == 'ok\r\n': - outstanding -= 1 - print outstanding, repr(line.rstrip()) \ No newline at end of file From bf37ab7e7be6b6f44a86bf03c223113f46facc7a Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 17 Jan 2015 08:12:37 -0700 Subject: [PATCH 18/74] Fully configurable pins for NO or NC switches. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - All pins, which include limits, control command, and probe pins, can now all be configured to trigger as active-low or active-high and whether the pin has its internal pull-up resistor enabled. This should allow for just about all types of NO and NC switch configurations. - The probe pin invert setting hasn’t been added to the Grbl settings, like the others, and will have to wait until v1.0. But for now, it’s available as a compile-time option in config.h. - Fixed a variable spindle bug. --- config.h | 21 ++++++++++++++++++++ cpu_map.h | 50 +++++++++++++++++++++++------------------------ defaults.h | 2 +- limits.c | 8 ++++---- main.c | 2 +- planner.c | 2 +- probe.c | 6 +++--- settings.h | 2 +- spindle_control.c | 2 +- system.c | 38 ++++++++++++++++++++++------------- 10 files changed, 82 insertions(+), 51 deletions(-) diff --git a/config.h b/config.h index 60d240bd3..9a55119dc 100644 --- a/config.h +++ b/config.h @@ -143,6 +143,11 @@ // have the same steps per mm internally. // #define COREXY // Default disabled. Uncomment to enable. +// Inverts pin logic of the control command pins. This essentially means when this option is enabled +// you can use normally-closed switches, rather than the default normally-open switches. +// NOTE: Will eventually be added to Grbl settings in v1.0. +// #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: @@ -162,6 +167,22 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +// By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors +// enabled. This simplifies the wiring for users by requiring only a switch connected to ground, +// although its recommended that users take the extra step of wiring in low-pass filter to reduce +// electrical noise detected by the pin. If the user inverts the pin in Grbl settings, this just flips +// which high or low reading indicates an active signal. In normal operation, this means the user +// needs to connect a normal-open switch, but if inverted, this means the user should connect a +// normal-closed switch. +// The following options disable the internal pull-up resistors, sets the pins to a normal-low +// operation, and switches much be now connect to Vcc instead of ground. This also flips the meaning +// of the invert pin Grbl setting, where an inverted setting now means the user should connect a +// normal-open switch and vice versa. +// WARNING: When the pull-ups are disabled, this requires additional wiring with pull-down resistors! +//#define DISABLE_LIMIT_PIN_PULL_UP +//#define DISABLE_PROBE_PIN_PULL_UP +//#define DISABLE_CONTROL_PIN_PULL_UP + // Sets which axis the tool length offset is applied. Assumes the spindle is always parallel with // the selected axis with the tool oriented toward the negative direction. In other words, a positive // tool length offset value is subtracted from the current location. diff --git a/cpu_map.h b/cpu_map.h index 3e46c3092..4bdb61a20 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -60,7 +60,7 @@ #define STEPPERS_DISABLE_MASK (1< 0); // The active cycle axes should now be homed and machine limits have been located. By - // default, grbl defines machine space as all negative, as do most CNCs. Since limit switches + // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, // set up pull-off maneuver from axes limit switches that have been homed. This provides // some initial clearance off the switches and should also help prevent them from falsely diff --git a/main.c b/main.c index cd8347817..bdda1e7e0 100644 --- a/main.c +++ b/main.c @@ -47,7 +47,7 @@ int main(void) { // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts - settings_init(); // Load grbl settings from EEPROM + settings_init(); // Load Grbl settings from EEPROM stepper_init(); // Configure stepper pins and interrupt timers system_init(); // Configure pinout pins and pin-change interrupt diff --git a/planner.c b/planner.c index cc41535fd..c0b17423a 100644 --- a/planner.c +++ b/planner.c @@ -371,7 +371,7 @@ uint8_t plan_check_full_buffer() colinear with the circle center. The circular segment joining the two paths represents the path of centripetal acceleration. Solve for max velocity based on max acceleration about the radius of the circle, defined indirectly by junction deviation. This may be also viewed as - path width or max_jerk in the previous grbl version. This approach does not actually deviate + path width or max_jerk in the previous Grbl version. This approach does not actually deviate from path, but used as a robust way to compute cornering speeds, as it takes into account the nonlinearities of both the junction angle and junction velocity. diff --git a/probe.c b/probe.c index e7063b0b4..5d0224fb8 100644 --- a/probe.c +++ b/probe.c @@ -30,11 +30,11 @@ uint8_t probe_invert_mask; void probe_init() { PROBE_DDR &= ~(PROBE_MASK); // Configure as input pins - if (bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)) { + #ifdef DISABLE_PROBE_PIN_PULL_UP PROBE_PORT &= ~(PROBE_MASK); // Normal low operation. Requires external pull-down. - } else { + #else PROBE_PORT |= PROBE_MASK; // Enable internal pull-up resistors. Normal high operation. - } + #endif // probe_configure_invert_mask(false); // Initialize invert mask. Not required. Updated when in-use. } diff --git a/settings.h b/settings.h index c201ad72a..426ea40bc 100644 --- a/settings.h +++ b/settings.h @@ -29,7 +29,7 @@ #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150114" +#define GRBL_VERSION_BUILD "20150117" // 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 diff --git a/spindle_control.c b/spindle_control.c index 84b861242..b928adaf2 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -113,7 +113,7 @@ void spindle_set_state(uint8_t state, float rpm) void spindle_run(uint8_t state, float rpm) { - if (sys.state != STATE_CHECK_MODE) { return; } + if (sys.state == STATE_CHECK_MODE) { return; } protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed. spindle_set_state(state, rpm); } diff --git a/system.c b/system.c index 046b72bcf..9c4284559 100644 --- a/system.c +++ b/system.c @@ -30,10 +30,14 @@ void system_init() { - PINOUT_DDR &= ~(PINOUT_MASK); // Configure as input pins - PINOUT_PORT |= PINOUT_MASK; // Enable internal pull-up resistors. Normal high operation. - PINOUT_PCMSK |= PINOUT_MASK; // Enable specific pins of the Pin Change Interrupt - PCICR |= (1 << PINOUT_INT); // Enable Pin Change Interrupt + CONTROL_DDR &= ~(CONTROL_MASK); // Configure as input pins + #ifdef DISABLE_CONTROL_PIN_PULL_UP + CONTROL_PORT &= ~(CONTROL_MASK); // Normal low operation. Requires external pull-down. + #else + CONTROL_PORT |= CONTROL_MASK; // Enable internal pull-up resistors. Normal high operation. + #endif + CONTROL_PCMSK |= CONTROL_MASK; // Enable specific pins of the Pin Change Interrupt + PCICR |= (1 << CONTROL_INT); // Enable Pin Change Interrupt } @@ -41,15 +45,19 @@ void system_init() // only the realtime command execute variable to have the main program execute these when // its ready. This works exactly like the character-based realtime commands when picked off // directly from the incoming serial data stream. -ISR(PINOUT_INT_vect) +ISR(CONTROL_INT_vect) { - // Enter only if any pinout pin is actively low. - if ((PINOUT_PIN & PINOUT_MASK) ^ PINOUT_MASK) { - if (bit_isfalse(PINOUT_PIN,bit(PIN_RESET))) { + uint8_t pin = (CONTROL_PIN & CONTROL_MASK); + #ifndef INVERT_CONTROL_PIN + pin ^= CONTROL_MASK; + #endif + // Enter only if any CONTROL pin is detected as active. + if (pin) { + if (bit_istrue(pin,bit(RESET_BIT))) { mc_reset(); - } else if (bit_isfalse(PINOUT_PIN,bit(PIN_FEED_HOLD))) { + } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); - } else if (bit_isfalse(PINOUT_PIN,bit(PIN_CYCLE_START))) { + } else if (bit_istrue(pin,bit(CYCLE_START_BIT))) { bit_true(sys.rt_exec_state, EXEC_CYCLE_START); } } @@ -208,15 +216,17 @@ uint8_t system_execute_line(char *line) float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) { + float pos; #ifdef COREXY if (idx==A_MOTOR) { - return((0.5*(steps[A_MOTOR] + steps[B_MOTOR]))/settings.steps_per_mm[idx]); - } else if (idx==B_MOTOR) { - return((0.5*(steps[A_MOTOR] - steps[B_MOTOR]))/settings.steps_per_mm[idx]); + pos = 0.5*((steps[A_MOTOR] + steps[B_MOTOR])/settings.steps_per_mm[idx]); + } else { // (idx==B_MOTOR) + pos = 0.5*((steps[A_MOTOR] - steps[B_MOTOR])/settings.steps_per_mm[idx]); } #else - return((float)steps[idx]/settings.steps_per_mm[idx]); + pos = steps[idx]/settings.steps_per_mm[idx]; #endif + return(pos); } From a358c6de0bbd55463d0914b2d23dfbfd12624b78 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 4 Feb 2015 19:12:30 -0700 Subject: [PATCH 19/74] Rare planner bug fix and added simulator defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Planner bug when moving along a diagonal back and forth on the same path. Rare for the fact that most CAM programs don’t program this type of motion, neither does jogging. Fixed in this update. - Added grbl_sim defaults for testing purposes. --- defaults.h | 36 ++++++++++++++++++++++++++++++++++++ planner.c | 1 + settings.h | 2 +- system.c | 3 +++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/defaults.h b/defaults.h index 7f4bce19b..06dc0f7ba 100644 --- a/defaults.h +++ b/defaults.h @@ -263,4 +263,40 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #endif +#ifdef DEFAULTS_SIMULATOR + // Settings only for Grbl Simulator (www.github.com/grbl/grbl-sim) + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 1000.0 + #define DEFAULT_Y_STEPS_PER_MM 1000.0 + #define DEFAULT_Z_STEPS_PER_MM 1000.0 + #define DEFAULT_X_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min + #define DEFAULT_X_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) + #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_AUTO_START 1 // true + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm +#endif + #endif diff --git a/planner.c b/planner.c index c0b17423a..44ab051f1 100644 --- a/planner.c +++ b/planner.c @@ -388,6 +388,7 @@ uint8_t plan_check_full_buffer() change the overall maximum entry speed conditions of all blocks. */ // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta). + junction_cos_theta = min(junction_cos_theta, 1.0); // Check for numerical round-off. float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the diff --git a/settings.h b/settings.h index 426ea40bc..df7090638 100644 --- a/settings.h +++ b/settings.h @@ -29,7 +29,7 @@ #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150117" +#define GRBL_VERSION_BUILD "20150204" // 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 diff --git a/system.c b/system.c index 9c4284559..12838ae09 100644 --- a/system.c +++ b/system.c @@ -214,6 +214,9 @@ uint8_t system_execute_line(char *line) } +// Returns machine position of axis 'idx'. Must be sent a 'step' array. +// NOTE: If motor steps and machine position are not in the same coordinate frame, this function +// serves as a central place to compute the transformation. float system_convert_axis_steps_to_mpos(int32_t *steps, uint8_t idx) { float pos; From 23c1e154aae3232deb9bacafca293a8cc154c26e Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 6 Feb 2015 20:02:34 -0700 Subject: [PATCH 20/74] Limit/control pin state reporting option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - As a setup feature, users can compile-in input pin status reporting. Doesn’t do anything special, just prints the binary for the port. 0’s and 1’s indicate low and high signals on the pins. It’s a bit cryptic right now, but it’s just a start. - Added a max step rate check when writing step/mm and max rate settings. Should help avoid people misdiagnosing problems associated with going over the 30kHz step rate limit. Right now not enabled. Takes up over 100k of flash. Need that room for other things right now. --- config.h | 11 +++++++++++ report.c | 9 +++++++++ report.h | 1 + settings.c | 10 ++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index 9a55119dc..601457e40 100644 --- a/config.h +++ b/config.h @@ -148,6 +148,12 @@ // NOTE: Will eventually be added to Grbl settings in v1.0. // #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. +// Enable input pin states feedback in status reports. The data is presented as a binary value with +// the bits in the appropriate input pin ports being 0(low) or 1(high). Useful for setting up a new +// CNC machine, but do not recommend keeping this option by default, as it will consume CPU resources +// with little to no benefit during normal operation. +// #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: @@ -167,6 +173,11 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. +// Sets the maximum step rate allowed to be written as a Grbl setting. This value is strictly limited +// by the CPU speed and will change if something other than an AVR running at 16MHz is used. +// NOTE: For now disabled, will enable if flash space permits. +// #define MAX_STEP_RATE_HZ 30000 // Hz + // By default, Grbl sets all input pins to normal-high operation with their internal pull-up resistors // enabled. This simplifies the wiring for users by requiring only a switch connected to ground, // although its recommended that users take the extra step of wiring in low-pass filter to reduce diff --git a/report.c b/report.c index fd47e902b..6e0d2dabf 100644 --- a/report.c +++ b/report.c @@ -75,6 +75,8 @@ void report_status_message(uint8_t status_code) printPgmString(PSTR("Homing not enabled")); break; case STATUS_OVERFLOW: printPgmString(PSTR("Line overflow")); break; + // case STATUS_MAX_STEP_RATE_EXCEEDED: + // printPgmString(PSTR("Step rate > 30kHz")); break; // Common g-code parser errors. case STATUS_GCODE_MODAL_GROUP_VIOLATION: @@ -449,5 +451,12 @@ void report_realtime_status() printFloat_RateValue(st_get_realtime_rate()); #endif + #ifdef REPORT_INPUT_PIN_STATES + printPgmString(PSTR(",Lim:")); + print_uint8_base2(LIMIT_PIN & LIMIT_MASK); + printPgmString(PSTR(",Ctl:")); + print_uint8_base2(CONTROL_PIN & CONTROL_MASK); + #endif + printPgmString(PSTR(">\r\n")); } diff --git a/report.h b/report.h index e770469d0..c0916aa52 100644 --- a/report.h +++ b/report.h @@ -33,6 +33,7 @@ #define STATUS_ALARM_LOCK 9 #define STATUS_SOFT_LIMIT_ERROR 10 #define STATUS_OVERFLOW 11 +// #define STATUS_MAX_STEP_RATE_EXCEEDED 12 #define STATUS_GCODE_UNSUPPORTED_COMMAND 20 #define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 diff --git a/settings.c b/settings.c index 56e2fab8a..a81e0e848 100644 --- a/settings.c +++ b/settings.c @@ -200,8 +200,14 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { if (parameter < N_AXIS) { // Valid axis setting found. switch (set_idx) { - case 0: settings.steps_per_mm[parameter] = value; break; - case 1: settings.max_rate[parameter] = value; break; + case 0: + // if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + settings.steps_per_mm[parameter] = value; + break; + case 1: + // if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + settings.max_rate[parameter] = value; + break; case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 3: settings.max_travel[parameter] = -value; break; // Store as negative for grbl internal use. } From 3b468f602b031a7f353fb7a5c986d829d1d14a52 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 08:25:09 -0700 Subject: [PATCH 21/74] Bug fix for certain motions. Re-org of includes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Critical bug fix for diagonal motions that continue on the same direction or return in the exact opposite direction. This issue could cause Grbl to crash intermittently due to a numerical round-off error. Grbl versions prior to v0.9g shouldn’t have this issue. - Reorganized all of the includes used by Grbl. Centralized it into a single “grbl.h” include. This will help simplify the compiling and uploading process through the Arduino IDE. - Added an example .INO file for users to simply open and run when compiling and uploading through the IDE. More to come later. --- config.h | 1 - coolant_control.c | 5 +---- examples/Grbl/Grbl.ino | 22 ++++++++++++++++++++++ gcode.c | 10 +--------- grbl.h | 28 ++++++++++++++++++++++------ limits.c | 10 ++-------- main.c | 14 +------------- motion_control.c | 13 +------------ motion_control.h | 2 +- nuts_bolts.c | 3 +-- planner.c | 25 +++++++++++++------------ print.c | 4 +--- probe.c | 5 ++--- protocol.c | 10 +--------- report.c | 11 +---------- serial.c | 6 +----- settings.c | 8 +------- settings.h | 3 +-- spindle_control.c | 5 +---- stepper.c | 7 +------ system.c | 9 +-------- system.h | 20 +------------------- 22 files changed, 77 insertions(+), 144 deletions(-) create mode 100644 examples/Grbl/Grbl.ino diff --git a/config.h b/config.h index 601457e40..0a0d8861b 100644 --- a/config.h +++ b/config.h @@ -32,7 +32,6 @@ #ifndef config_h #define config_h -#include "system.h" // Default settings. Used when resetting EEPROM. Change to desired name in defaults.h diff --git a/coolant_control.c b/coolant_control.c index d8336d5be..f94f51ad2 100644 --- a/coolant_control.c +++ b/coolant_control.c @@ -18,10 +18,7 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "coolant_control.h" -#include "protocol.h" -#include "gcode.h" +#include "grbl.h" void coolant_init() diff --git a/examples/Grbl/Grbl.ino b/examples/Grbl/Grbl.ino new file mode 100644 index 000000000..caf26fd27 --- /dev/null +++ b/examples/Grbl/Grbl.ino @@ -0,0 +1,22 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include diff --git a/gcode.c b/gcode.c index 69d58e0ad..ec5b44ae3 100644 --- a/gcode.c +++ b/gcode.c @@ -24,15 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "motion_control.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // NOTE: Max line number is defined by the g-code standard to be 99999. It seems to be an // arbitrary value, and some GUIs may require more. So we increased it based on a max safe diff --git a/grbl.h b/grbl.h index 913e4f5f0..6295e7c34 100644 --- a/grbl.h +++ b/grbl.h @@ -25,25 +25,41 @@ #ifndef grbl_h #define grbl_h -// All of the Grbl system include files. +#define GRBL_VERSION "0.9h" +#define GRBL_VERSION_BUILD "20150210" + +// Define standard libraries used by Grbl. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Define the Grbl system include files. #include "config.h" -#include "coolant_control.h" -#include "cpu_map.h" +#include "nuts_bolts.h" +#include "settings.h" +#include "system.h" #include "defaults.h" +#include "cpu_map.h" +#include "coolant_control.h" #include "eeprom.h" #include "gcode.h" #include "limits.h" #include "motion_control.h" -#include "nuts_bolts.h" #include "planner.h" #include "print.h" #include "probe.h" #include "protocol.h" #include "report.h" #include "serial.h" -#include "settings.h" #include "spindle_control.h" #include "stepper.h" -#include "system.h" #endif diff --git a/limits.c b/limits.c index 0a5e391a5..a8a258349 100644 --- a/limits.c +++ b/limits.c @@ -24,14 +24,8 @@ Copyright (c) 2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "limits.h" -#include "report.h" +#include "grbl.h" + // Homing axis search distance multiplier. Computed by this value times the axis max travel. #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. diff --git a/main.c b/main.c index bdda1e7e0..f3557c597 100644 --- a/main.c +++ b/main.c @@ -24,19 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "motion_control.h" -#include "limits.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // Declare system global variable structure diff --git a/motion_control.c b/motion_control.c index 1cd9d0566..4a0fdb99a 100644 --- a/motion_control.c +++ b/motion_control.c @@ -25,18 +25,7 @@ Copyright (c) 2011 Jens Geisler */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "spindle_control.h" -#include "coolant_control.h" -#include "limits.h" -#include "probe.h" -#include "report.h" +#include "grbl.h" // Execute linear motion in absolute millimeter coordinates. Feed rate given in millimeters/second diff --git a/motion_control.h b/motion_control.h index 285a92856..1cd1b2e80 100644 --- a/motion_control.h +++ b/motion_control.h @@ -26,7 +26,7 @@ #ifndef motion_control_h #define motion_control_h -#include "gcode.h" + #define HOMING_CYCLE_LINE_NUMBER -1 diff --git a/nuts_bolts.c b/nuts_bolts.c index d620a627c..7da9d7e7c 100644 --- a/nuts_bolts.c +++ b/nuts_bolts.c @@ -24,8 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "print.h" +#include "grbl.h" #define MAX_INT_DIGITS 8 // Maximum number of digits in int32 (and float) diff --git a/planner.c b/planner.c index 44ab051f1..0946ce121 100644 --- a/planner.c +++ b/planner.c @@ -25,12 +25,7 @@ Copyright (c) 2011 Jens Geisler */ -#include "system.h" -#include "planner.h" -#include "protocol.h" -#include "stepper.h" -#include "settings.h" - +#include "grbl.h" #define SOME_LARGE_VALUE 1.0E+38 // Used by rapids and acceleration maximization calculations. Just needs // to be larger than any feasible (mm/min)^2 or mm/sec^2 value. @@ -388,13 +383,19 @@ uint8_t plan_check_full_buffer() change the overall maximum entry speed conditions of all blocks. */ // NOTE: Computed without any expensive trig, sin() or acos(), by trig half angle identity of cos(theta). - junction_cos_theta = min(junction_cos_theta, 1.0); // Check for numerical round-off. - float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. + if (junction_cos_theta > 0.99) { + // For a 0 degree acute junction, just set minimum junction speed. + block->max_junction_speed_sqr = MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED; + } else { + junction_cos_theta = max(junction_cos_theta,-0.99); // Check for numerical round-off to avoid divide by zero. + float sin_theta_d2 = sqrt(0.5*(1.0-junction_cos_theta)); // Trig half angle identity. Always positive. + + // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the + // two junctions. However, this shouldn't be a significant problem except in extreme circumstances. + block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, + (block->acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); - // TODO: Technically, the acceleration used in calculation needs to be limited by the minimum of the - // two junctions. However, this shouldn't be a significant problem except in extreme circumstances. - block->max_junction_speed_sqr = max( MINIMUM_JUNCTION_SPEED*MINIMUM_JUNCTION_SPEED, - (block->acceleration * settings.junction_deviation * sin_theta_d2)/(1.0-sin_theta_d2) ); + } } // Store block nominal speed diff --git a/print.c b/print.c index 65fb9756c..781cedcaf 100644 --- a/print.c +++ b/print.c @@ -24,9 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" +#include "grbl.h" void printString(const char *s) diff --git a/probe.c b/probe.c index 5d0224fb8..74121e804 100644 --- a/probe.c +++ b/probe.c @@ -18,9 +18,8 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "settings.h" -#include "probe.h" +#include "grbl.h" + // Inverts the probe pin state depending on user settings and probing cycle mode. uint8_t probe_invert_mask; diff --git a/protocol.c b/protocol.c index 1c2651afd..239bb1639 100644 --- a/protocol.c +++ b/protocol.c @@ -24,15 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "serial.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "planner.h" -#include "stepper.h" -#include "motion_control.h" -#include "report.h" +#include "grbl.h" static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. diff --git a/report.c b/report.c index 6e0d2dabf..c611452b2 100644 --- a/report.c +++ b/report.c @@ -26,16 +26,7 @@ methods to accomodate their needs. */ -#include "system.h" -#include "report.h" -#include "print.h" -#include "settings.h" -#include "gcode.h" -#include "coolant_control.h" -#include "planner.h" -#include "spindle_control.h" -#include "stepper.h" -#include "serial.h" +#include "grbl.h" // Handles the primary confirmation protocol response for streaming interfaces and human-feedback. diff --git a/serial.c b/serial.c index 7b2339cc4..e4a63d224 100644 --- a/serial.c +++ b/serial.c @@ -24,11 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include -#include "system.h" -#include "serial.h" -#include "motion_control.h" -#include "protocol.h" +#include "grbl.h" uint8_t serial_rx_buffer[RX_BUFFER_SIZE]; diff --git a/settings.c b/settings.c index a81e0e848..d018fef54 100644 --- a/settings.c +++ b/settings.c @@ -24,13 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "settings.h" -#include "eeprom.h" -#include "protocol.h" -#include "report.h" -#include "limits.h" -#include "stepper.h" +#include "grbl.h" settings_t settings; diff --git a/settings.h b/settings.h index df7090638..a86c0e9c6 100644 --- a/settings.h +++ b/settings.h @@ -27,9 +27,8 @@ #ifndef settings_h #define settings_h +#include "grbl.h" -#define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150204" // 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 diff --git a/spindle_control.c b/spindle_control.c index b928adaf2..abad6c27d 100644 --- a/spindle_control.c +++ b/spindle_control.c @@ -24,10 +24,7 @@ Copyright (c) 2012 Sungeun K. Jeon */ -#include "system.h" -#include "spindle_control.h" -#include "protocol.h" -#include "gcode.h" +#include "grbl.h" void spindle_init() diff --git a/stepper.c b/stepper.c index fbc042625..cd71aa054 100644 --- a/stepper.c +++ b/stepper.c @@ -24,12 +24,7 @@ Copyright (c) 2011-2012 Sungeun K. Jeon */ -#include "system.h" -#include "nuts_bolts.h" -#include "stepper.h" -#include "settings.h" -#include "planner.h" -#include "probe.h" +#include "grbl.h" // Some useful constants. diff --git a/system.c b/system.c index 12838ae09..bec36d6c2 100644 --- a/system.c +++ b/system.c @@ -18,14 +18,7 @@ along with Grbl. If not, see . */ -#include "system.h" -#include "settings.h" -#include "protocol.h" -#include "gcode.h" -#include "motion_control.h" -#include "stepper.h" -#include "report.h" -#include "print.h" +#include "grbl.h" void system_init() diff --git a/system.h b/system.h index 94139becc..2c2a89d9c 100644 --- a/system.h +++ b/system.h @@ -21,25 +21,7 @@ #ifndef system_h #define system_h -// Define system header files and standard libraries used by Grbl -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Define Grbl configuration and shared header files -#include "config.h" -#include "defaults.h" -#include "cpu_map.h" -#include "nuts_bolts.h" - +#include "grbl.h" // Define system executor bit map. Used internally by realtime protocol as realtime command flags, // which notifies the main program to execute the specified realtime command asynchronously. From b237ad566ad25a1503e14fa5f487c34f88bec01f Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 19:30:40 -0700 Subject: [PATCH 22/74] File re-organization. New Makefile. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Re-organized source code files into a ‘grbl’ directory to lessen one step in compiling Grbl through the Arduino IDE. - Added an ‘examples’ directory with an upload .INO sketch to further simplify compiling and uploading Grbl via the Arduino IDE. - Updated the Makefile with regard to the source code no longer being in the root directory. All files generated by compiling is placed in a separate ‘build’ directory to keep things tidy. The makefile should operate in the same way as it did before. --- Makefile | 40 +++++++++++---------- README.md | 3 ++ examples/Grbl/Grbl.ino | 22 ------------ config.h => grbl/config.h | 5 +-- coolant_control.c => grbl/coolant_control.c | 0 coolant_control.h => grbl/coolant_control.h | 0 cpu_map.h => grbl/cpu_map.h | 0 defaults.h => grbl/defaults.h | 0 eeprom.c => grbl/eeprom.c | 0 eeprom.h => grbl/eeprom.h | 0 grbl/examples/grblUpload/grblUpload.ino | 29 +++++++++++++++ grbl/examples/grblUpload/license.txt | 21 +++++++++++ gcode.c => grbl/gcode.c | 0 gcode.h => grbl/gcode.h | 0 grbl.h => grbl/grbl.h | 9 ++--- limits.c => grbl/limits.c | 10 +++--- limits.h => grbl/limits.h | 0 main.c => grbl/main.c | 0 motion_control.c => grbl/motion_control.c | 0 motion_control.h => grbl/motion_control.h | 0 nuts_bolts.c => grbl/nuts_bolts.c | 0 nuts_bolts.h => grbl/nuts_bolts.h | 0 planner.c => grbl/planner.c | 0 planner.h => grbl/planner.h | 0 print.c => grbl/print.c | 0 print.h => grbl/print.h | 0 probe.c => grbl/probe.c | 0 probe.h => grbl/probe.h | 0 protocol.c => grbl/protocol.c | 0 protocol.h => grbl/protocol.h | 0 report.c => grbl/report.c | 0 report.h => grbl/report.h | 0 serial.c => grbl/serial.c | 0 serial.h => grbl/serial.h | 0 settings.c => grbl/settings.c | 0 settings.h => grbl/settings.h | 0 spindle_control.c => grbl/spindle_control.c | 0 spindle_control.h => grbl/spindle_control.h | 0 stepper.c => grbl/stepper.c | 0 stepper.h => grbl/stepper.h | 0 system.c => grbl/system.c | 0 system.h => grbl/system.h | 0 42 files changed, 86 insertions(+), 53 deletions(-) delete mode 100644 examples/Grbl/Grbl.ino rename config.h => grbl/config.h (98%) rename coolant_control.c => grbl/coolant_control.c (100%) rename coolant_control.h => grbl/coolant_control.h (100%) rename cpu_map.h => grbl/cpu_map.h (100%) rename defaults.h => grbl/defaults.h (100%) rename eeprom.c => grbl/eeprom.c (100%) rename eeprom.h => grbl/eeprom.h (100%) create mode 100644 grbl/examples/grblUpload/grblUpload.ino create mode 100644 grbl/examples/grblUpload/license.txt rename gcode.c => grbl/gcode.c (100%) rename gcode.h => grbl/gcode.h (100%) rename grbl.h => grbl/grbl.h (82%) rename limits.c => grbl/limits.c (99%) rename limits.h => grbl/limits.h (100%) rename main.c => grbl/main.c (100%) rename motion_control.c => grbl/motion_control.c (100%) rename motion_control.h => grbl/motion_control.h (100%) rename nuts_bolts.c => grbl/nuts_bolts.c (100%) rename nuts_bolts.h => grbl/nuts_bolts.h (100%) rename planner.c => grbl/planner.c (100%) rename planner.h => grbl/planner.h (100%) rename print.c => grbl/print.c (100%) rename print.h => grbl/print.h (100%) rename probe.c => grbl/probe.c (100%) rename probe.h => grbl/probe.h (100%) rename protocol.c => grbl/protocol.c (100%) rename protocol.h => grbl/protocol.h (100%) rename report.c => grbl/report.c (100%) rename report.h => grbl/report.h (100%) rename serial.c => grbl/serial.c (100%) rename serial.h => grbl/serial.h (100%) rename settings.c => grbl/settings.c (100%) rename settings.h => grbl/settings.h (100%) rename spindle_control.c => grbl/spindle_control.c (100%) rename spindle_control.h => grbl/spindle_control.h (100%) rename stepper.c => grbl/stepper.c (100%) rename stepper.h => grbl/stepper.h (100%) rename system.c => grbl/system.c (100%) rename system.h => grbl/system.h (100%) diff --git a/Makefile b/Makefile index 9bc561595..d825ee506 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Part of Grbl # # Copyright (c) 2009-2011 Simen Svale Skogsrud -# Copyright (c) 2012 Sungeun K. Jeon +# Copyright (c) 2012-2015 Sungeun K. Jeon # # Grbl is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,9 +31,11 @@ DEVICE ?= atmega328p CLOCK = 16000000 PROGRAMMER ?= -c avrisp2 -P usb -OBJECTS = main.o motion_control.o gcode.o spindle_control.o coolant_control.o serial.o \ - protocol.o stepper.o eeprom.o settings.o planner.o nuts_bolts.o limits.o \ - print.o probe.o report.o system.o +SOURCE = main.c motion_control.c gcode.c spindle_control.c coolant_control.c serial.c \ + protocol.c stepper.c eeprom.c settings.c planner.c nuts_bolts.c limits.c \ + print.c probe.c report.c system.c +BUILDDIR = build +SOURCEDIR = grbl # FUSES = -U hfuse:w:0xd9:m -U lfuse:w:0x24:m FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m @@ -42,22 +44,24 @@ FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I. -ffunction-sections +OBJECTS = $(addprefix $(BUILDDIR)/,$(notdir $(SOURCE:.c=.o))) + # symbolic targets: all: grbl.hex -.c.o: +$(BUILDDIR)/%.o: $(SOURCEDIR)/%.c $(COMPILE) -c $< -o $@ - @$(COMPILE) -MM $< > $*.d + @$(COMPILE) -MM $< > $(BUILDDIR)/$*.d .S.o: - $(COMPILE) -x assembler-with-cpp -c $< -o $@ + $(COMPILE) -x assembler-with-cpp -c $< -o $(BUILDDIR)/$@ # "-x assembler-with-cpp" should not be necessary since this is the default # file type for the .S (with capital S) extension. However, upper case # characters are not always preserved on Windows. To ensure WinAVR # compatibility define the file type manually. -.c.s: - $(COMPILE) -S $< -o $@ +#.c.s: + $(COMPILE) -S $< -o $(BUILDDIR)/$@ flash: all $(AVRDUDE) -U flash:w:grbl.hex:i @@ -73,25 +77,25 @@ load: all bootloadHID grbl.hex clean: - rm -f grbl.hex main.elf $(OBJECTS) $(OBJECTS:.o=.d) + rm -f grbl.hex $(BUILDDIR)/* # file targets: -main.elf: $(OBJECTS) - $(COMPILE) -o main.elf $(OBJECTS) -lm -Wl,--gc-sections +$(BUILDDIR)/main.elf: $(OBJECTS) + $(COMPILE) -o $(BUILDDIR)/main.elf $(OBJECTS) -lm -Wl,--gc-sections -grbl.hex: main.elf +grbl.hex: $(BUILDDIR)/main.elf rm -f grbl.hex - avr-objcopy -j .text -j .data -O ihex main.elf grbl.hex - avr-size --format=berkeley main.elf + avr-objcopy -j .text -j .data -O ihex $(BUILDDIR)/main.elf grbl.hex + avr-size --format=berkeley $(BUILDDIR)/main.elf # If you have an EEPROM section, you must also create a hex file for the # EEPROM and add it to the "flash" target. # Targets for code debugging and analysis: disasm: main.elf - avr-objdump -d main.elf + avr-objdump -d $(BUILDDIR)/main.elf cpp: - $(COMPILE) -E main.c + $(COMPILE) -E $(SOURCEDIR)/main.c # include generated header dependencies --include $(OBJECTS:.o=.d) +-include $(BUILDDIR)/$(OBJECTS:.o=.d) diff --git a/README.md b/README.md index 1183789ba..1cfa679ce 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,8 @@ _**Archives:**_ - **New Grbl SIMULATOR! (by @jgeisler and @ashelly):** A completely independent wrapper of the Grbl main source code that may be compiled as an executable on a computer. No Arduino required. Simply simulates the responses of Grbl as if it was on an Arduino. May be used for many things: checking out how Grbl works, pre-process moves for GUI graphics, debugging of new features, etc. Much left to do, but potentially very powerful, as the dummy AVR variables can be written to output anything you need. - **Configurable Real-time Status Reporting:** Users can now customize the type of real-time data Grbl reports back when they issue a '?' status report. This includes data such as: machine position, work position, planner buffer usage, serial RX buffer usage. - **Updated Homing Routine:** Sets workspace volume in all negative space regardless of limit switch position. Common on pro CNCs. But, the behavior may be changed by a compile-time option though. Now tied directly into the main planner and stepper modules to reduce flash space and allow maximum speeds during seeking. + - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! + - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - **Optional Limit Pin Sharing:** Limit switches can be combined to share the same pins to free up precious I/O pins for other purposes. When combined, users must adjust the homing cycle mask in config.h to not home the axes on a shared pin at the same time. Don't worry; hard limits and the homing cycle still work just like they did before. - **Optional Variable Spindle Speed Output:** Available only as a compile-time option through the config.h file. Enables PWM output for 'S' g-code commands. Enabling this feature will swap the Z-limit D11 pin and spindle enable D12 pin to access the hardware PWM on pin D12. The Z-limit pin, now on D12, should work just as it did before. - **Additional Compile-Time Feature Options:** Line number tracking, real-time feed rate reporting. @@ -68,6 +70,7 @@ List of Supported G-Codes in Grbl v0.9 - Distance Modes: G90, G91 - Plane Select Modes: G17, G18, G19 - Tool Length Offset Modes: G43.1, G49 + - Cutter Compensation Modes: G40 - Coordinate System Modes: G54, G55, G56, G57, G58, G59 - Program Flow: M0, M1, M2, M30* - Coolant Control: M7*, M8, M9 diff --git a/examples/Grbl/Grbl.ino b/examples/Grbl/Grbl.ino deleted file mode 100644 index caf26fd27..000000000 --- a/examples/Grbl/Grbl.ino +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include diff --git a/config.h b/grbl/config.h similarity index 98% rename from config.h rename to grbl/config.h index 0a0d8861b..a5c7f4ee8 100644 --- a/config.h +++ b/grbl/config.h @@ -185,9 +185,10 @@ // needs to connect a normal-open switch, but if inverted, this means the user should connect a // normal-closed switch. // The following options disable the internal pull-up resistors, sets the pins to a normal-low -// operation, and switches much be now connect to Vcc instead of ground. This also flips the meaning +// operation, and switches must be now connect to Vcc instead of ground. This also flips the meaning // of the invert pin Grbl setting, where an inverted setting now means the user should connect a // normal-open switch and vice versa. +// NOTE: All pins associated with the feature are disabled, i.e. XYZ limit pins, not individual axes. // WARNING: When the pull-ups are disabled, this requires additional wiring with pull-down resistors! //#define DISABLE_LIMIT_PIN_PULL_UP //#define DISABLE_PROBE_PIN_PULL_UP @@ -202,7 +203,7 @@ // enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled. // NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch! // The hardware PWM output on pin D11 is required for variable spindle output voltages. -// #define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. +#define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. // Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and diff --git a/coolant_control.c b/grbl/coolant_control.c similarity index 100% rename from coolant_control.c rename to grbl/coolant_control.c diff --git a/coolant_control.h b/grbl/coolant_control.h similarity index 100% rename from coolant_control.h rename to grbl/coolant_control.h diff --git a/cpu_map.h b/grbl/cpu_map.h similarity index 100% rename from cpu_map.h rename to grbl/cpu_map.h diff --git a/defaults.h b/grbl/defaults.h similarity index 100% rename from defaults.h rename to grbl/defaults.h diff --git a/eeprom.c b/grbl/eeprom.c similarity index 100% rename from eeprom.c rename to grbl/eeprom.c diff --git a/eeprom.h b/grbl/eeprom.h similarity index 100% rename from eeprom.h rename to grbl/eeprom.h diff --git a/grbl/examples/grblUpload/grblUpload.ino b/grbl/examples/grblUpload/grblUpload.ino new file mode 100644 index 000000000..581b6b3d7 --- /dev/null +++ b/grbl/examples/grblUpload/grblUpload.ino @@ -0,0 +1,29 @@ +/*********************************************************************** +This sketch compiles and uploads Grbl to your 328p-based Arduino! + +To use: +- First make sure you have imported Grbl source code into your Arduino + IDE. There are details on our Github website on how to do this. + +- Select your Arduino Board and Serial Port in the Tools drop-down menu. + NOTE: Grbl only officially supports 328p-based Arduinos, like the Uno. + Using other boards will likely not work! + +- Then just click 'Upload'. That's it! + +For advanced users: + If you'd like to see what else Grbl can do, there are some additional + options for customization and features you can enable or disable. + Navigate your file system to where the Arduino IDE has stored the Grbl + source code files, open the 'config.h' file in your favorite text + editor. Inside are dozens of feature descriptions and #defines. Simply + comment or uncomment the #defines or alter their assigned values, save + your changes, and then click 'Upload' here. + +Copyright (c) 2015 Sungeun K. Jeon +Released under the MIT-license. See license.txt for details. +***********************************************************************/ + +#include + +// Do not alter this file! diff --git a/grbl/examples/grblUpload/license.txt b/grbl/examples/grblUpload/license.txt new file mode 100644 index 000000000..1abcdb959 --- /dev/null +++ b/grbl/examples/grblUpload/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2015 Sungeun K. Jeon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/gcode.c b/grbl/gcode.c similarity index 100% rename from gcode.c rename to grbl/gcode.c diff --git a/gcode.h b/grbl/gcode.h similarity index 100% rename from gcode.h rename to grbl/gcode.h diff --git a/grbl.h b/grbl/grbl.h similarity index 82% rename from grbl.h rename to grbl/grbl.h index 6295e7c34..dc331bfd0 100644 --- a/grbl.h +++ b/grbl/grbl.h @@ -1,5 +1,5 @@ /* - grbl.h - include file + grbl.h - main Grbl include file Part of Grbl v0.9 Copyright (c) 2015 Sungeun K. Jeon @@ -18,13 +18,10 @@ along with Grbl. If not, see . */ -// NOTE: This is not used by the 'make' compiling method. This is currently only used for -// simplifying compiling through the Arduino IDE at the moment. However, it may eventually -// turn into a central include file for the overall system. - #ifndef grbl_h #define grbl_h +// Grbl versioning system #define GRBL_VERSION "0.9h" #define GRBL_VERSION_BUILD "20150210" @@ -41,7 +38,7 @@ #include #include -// Define the Grbl system include files. +// Define the Grbl system include files. NOTE: Do not alter organization. #include "config.h" #include "nuts_bolts.h" #include "settings.h" diff --git a/limits.c b/grbl/limits.c similarity index 99% rename from limits.c rename to grbl/limits.c index a8a258349..a8b299695 100644 --- a/limits.c +++ b/grbl/limits.c @@ -161,14 +161,14 @@ void limits_go_home(uint8_t cycle_mask) // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; - if (!approach) { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } - else { target[idx] -= max_travel; } - } else { + if (approach) { // Set target direction based on cycle mask if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] -= max_travel; } else { target[idx] += max_travel; } + } else { + // Set target direction based on cycle mask + if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } + else { target[idx] -= max_travel; } } } diff --git a/limits.h b/grbl/limits.h similarity index 100% rename from limits.h rename to grbl/limits.h diff --git a/main.c b/grbl/main.c similarity index 100% rename from main.c rename to grbl/main.c diff --git a/motion_control.c b/grbl/motion_control.c similarity index 100% rename from motion_control.c rename to grbl/motion_control.c diff --git a/motion_control.h b/grbl/motion_control.h similarity index 100% rename from motion_control.h rename to grbl/motion_control.h diff --git a/nuts_bolts.c b/grbl/nuts_bolts.c similarity index 100% rename from nuts_bolts.c rename to grbl/nuts_bolts.c diff --git a/nuts_bolts.h b/grbl/nuts_bolts.h similarity index 100% rename from nuts_bolts.h rename to grbl/nuts_bolts.h diff --git a/planner.c b/grbl/planner.c similarity index 100% rename from planner.c rename to grbl/planner.c diff --git a/planner.h b/grbl/planner.h similarity index 100% rename from planner.h rename to grbl/planner.h diff --git a/print.c b/grbl/print.c similarity index 100% rename from print.c rename to grbl/print.c diff --git a/print.h b/grbl/print.h similarity index 100% rename from print.h rename to grbl/print.h diff --git a/probe.c b/grbl/probe.c similarity index 100% rename from probe.c rename to grbl/probe.c diff --git a/probe.h b/grbl/probe.h similarity index 100% rename from probe.h rename to grbl/probe.h diff --git a/protocol.c b/grbl/protocol.c similarity index 100% rename from protocol.c rename to grbl/protocol.c diff --git a/protocol.h b/grbl/protocol.h similarity index 100% rename from protocol.h rename to grbl/protocol.h diff --git a/report.c b/grbl/report.c similarity index 100% rename from report.c rename to grbl/report.c diff --git a/report.h b/grbl/report.h similarity index 100% rename from report.h rename to grbl/report.h diff --git a/serial.c b/grbl/serial.c similarity index 100% rename from serial.c rename to grbl/serial.c diff --git a/serial.h b/grbl/serial.h similarity index 100% rename from serial.h rename to grbl/serial.h diff --git a/settings.c b/grbl/settings.c similarity index 100% rename from settings.c rename to grbl/settings.c diff --git a/settings.h b/grbl/settings.h similarity index 100% rename from settings.h rename to grbl/settings.h diff --git a/spindle_control.c b/grbl/spindle_control.c similarity index 100% rename from spindle_control.c rename to grbl/spindle_control.c diff --git a/spindle_control.h b/grbl/spindle_control.h similarity index 100% rename from spindle_control.h rename to grbl/spindle_control.h diff --git a/stepper.c b/grbl/stepper.c similarity index 100% rename from stepper.c rename to grbl/stepper.c diff --git a/stepper.h b/grbl/stepper.h similarity index 100% rename from stepper.h rename to grbl/stepper.h diff --git a/system.c b/grbl/system.c similarity index 100% rename from system.c rename to grbl/system.c diff --git a/system.h b/grbl/system.h similarity index 100% rename from system.h rename to grbl/system.h From 20c7750dabf3491df373b94b6527c1544a7e5716 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 10 Feb 2015 22:10:03 -0700 Subject: [PATCH 23/74] Git fix for empty directory. Makefile updated. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ‘build’ directory was not being synced by git because it was empty. Added a .gitignore file in the ‘build’ directory to force git to sync it but keep it empty. - Updated the Makefile to not erase the .gitignore. --- Makefile | 2 +- build/.gitignore | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 build/.gitignore diff --git a/Makefile b/Makefile index d825ee506..504bb9903 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ load: all bootloadHID grbl.hex clean: - rm -f grbl.hex $(BUILDDIR)/* + rm -f grbl.hex $(BUILDDIR)/*.o $(BUILDDIR)/*.d $(BUILDDIR)/*.elf # file targets: $(BUILDDIR)/main.elf: $(OBJECTS) diff --git a/build/.gitignore b/build/.gitignore new file mode 100644 index 000000000..86d0cb272 --- /dev/null +++ b/build/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file From 4bdc20ffb94f70eaf99ad2c19d96f6c951f191c5 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 11 Feb 2015 21:19:00 -0700 Subject: [PATCH 24/74] Overhauled state machine. New safety door feature. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Overhauled the state machine and cleaned up its overall operation. This involved creating a new ‘suspend’ state for what all external commands, except real-time commands, are ignored. All hold type states enter this suspend state. - Removed ‘auto cycle start’ setting from Grbl. This was not used by users in its intended way and is somewhat redundant, as GUI manage the cycle start by streaming. It also muddled up how Grbl should interpret how and when to execute a g-code block. Removing it made everything much much simpler. - Fixed a program pause bug when used with other buffer_sync commands. - New safety door feature for OEMs. Immediately forces a feed hold and then de-energizes the machine. Resuming is blocked until the door is closed. When it is, it re-energizes the system and then resumes on the normal toolpath. - Safety door input pin is optional and uses the feed hold pin on A1. Enabled by config.h define. - Spindle and coolant re-energizing upon a safety door resume has a programmable delay time to allow for complete spin up to rpm and turning on the coolant before resuming motion. - Safety door-style feed holds can be used instead of regular feed hold (doesn’t de-energize the machine) with a ‘@‘ character. If the safety door input pin is not enabled, the system can be resumed at any time. --- grbl/config.h | 13 ++++ grbl/cpu_map.h | 3 +- grbl/gcode.c | 6 +- grbl/limits.c | 10 ++- grbl/main.c | 3 +- grbl/motion_control.c | 14 +--- grbl/probe.c | 2 +- grbl/protocol.c | 159 ++++++++++++++++++++++++++++++++---------- grbl/report.c | 8 ++- grbl/report.h | 1 + grbl/serial.c | 1 + grbl/settings.c | 5 -- grbl/settings.h | 2 +- grbl/stepper.c | 31 ++++---- grbl/system.c | 37 +++++++++- grbl/system.h | 30 +++++--- 16 files changed, 235 insertions(+), 90 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index a5c7f4ee8..0635c6594 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -54,6 +54,7 @@ #define CMD_FEED_HOLD '!' #define CMD_CYCLE_START '~' #define CMD_RESET 0x18 // ctrl-x. +#define CMD_SAFETY_DOOR '@' //0x13 // ctrl-s // If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces // the user to perform the homing cycle (or override the locks) before doing anything else. This is @@ -133,6 +134,18 @@ // NOTE: The M8 flood coolant control pin on analog pin 4 will still be functional regardless. // #define ENABLE_M7 // Disabled by default. Uncomment to enable. +// This option causes the feed hold input to act as a safety door switch. A safety door, when triggered, +// immediately forces a feed hold and then safely de-energizes the machine. Resuming is blocked until +// the safety door is re-engaged. When it is, Grbl will re-energize the machine and then resume on the +// previous tool path, as if nothing happened. +// #define ENABLE_SAFETY_DOOR_INPUT_PIN // Default disabled. Uncomment to enable. + +// After the safety door switch has been toggled and restored, this setting sets the power-up delay +// between restoring the spindle and coolant and resuming the cycle. +// NOTE: Delay value is defined in milliseconds from zero to 65,535. +#define SAFETY_DOOR_SPINDLE_DELAY 4000 // Disabled by default. Comment to enable. +#define SAFETY_DOOR_COOLANT_DELAY 1000 // Disabled by default. Comment to enable. + // Enable CoreXY kinematics. Use ONLY with CoreXY machines. // IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to // #define HOMING_CYCLE_0 (1<entry_speed_sqr = prep.exit_speed*prep.exit_speed; @@ -587,7 +593,7 @@ void st_prep_buffer() */ prep.mm_complete = 0.0; // Default velocity profile complete at 0.0mm from end of block. float inv_2_accel = 0.5/pl_block->acceleration; - if (sys.state == STATE_HOLD) { // [Forced Deceleration to Zero Velocity] + if (sys.state & (STATE_HOLD|STATE_MOTION_CANCEL|STATE_SAFETY_DOOR)) { // [Forced Deceleration to Zero Velocity] // Compute velocity profile parameters for a feed hold in-progress. This profile overrides // the planner block profile, enforcing a deceleration to zero speed. prep.ramp_type = RAMP_DECEL; @@ -746,16 +752,14 @@ void st_prep_buffer() // Bail if we are at the end of a feed hold and don't have a step to execute. if (prep_segment->n_step == 0) { - if (sys.state == STATE_HOLD) { - + if (sys.state & (STATE_HOLD|STATE_MOTION_CANCEL|STATE_SAFETY_DOOR)) { // Less than one step to decelerate to zero speed, but already very close. AMASS // requires full steps to execute. So, just bail. - prep.current_speed = 0.0; + prep.current_speed = 0.0; // NOTE: (=0.0) Used to indicate completed segment calcs for hold. prep.dt_remainder = 0.0; prep.steps_remaining = n_steps_remaining; pl_block->millimeters = prep.steps_remaining/prep.step_per_mm; // Update with full steps. plan_cycle_reinitialize(); - sys.state = STATE_QUEUED; return; // Segment not generated, but current step data still retained. } } @@ -818,21 +822,18 @@ void st_prep_buffer() } else { // End of planner block or forced-termination. No more distance to be executed. if (mm_remaining > 0.0) { // At end of forced-termination. - // Reset prep parameters for resuming and then bail. - // NOTE: Currently only feed holds qualify for this scenario. May change with overrides. - prep.current_speed = 0.0; + // Reset prep parameters for resuming and then bail. Allow the stepper ISR to complete + // 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. + prep.current_speed = 0.0; // NOTE: (=0.0) Used to indicate completed segment calcs for hold. prep.dt_remainder = 0.0; prep.steps_remaining = ceil(steps_remaining); pl_block->millimeters = prep.steps_remaining/prep.step_per_mm; // Update with full steps. plan_cycle_reinitialize(); - sys.state = STATE_QUEUED; // End cycle. - return; // Bail! -// TODO: Try to move QUEUED setting into cycle re-initialize. - } else { // End of planner block // The planner block is complete. All steps are set to be executed in the segment buffer. - pl_block = NULL; + pl_block = NULL; // Set pointer to indicate check and load next planner block. plan_discard_current_block(); } } @@ -848,7 +849,7 @@ void st_prep_buffer() #ifdef REPORT_REALTIME_RATE float st_get_realtime_rate() { - if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD)){ + if (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_HOLD | STATE_MOTION_CANCEL | STATE_SAFETY_DOOR)){ return prep.current_speed; } return 0.0f; diff --git a/grbl/system.c b/grbl/system.c index bec36d6c2..7a0916247 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -48,15 +48,35 @@ ISR(CONTROL_INT_vect) if (pin) { if (bit_istrue(pin,bit(RESET_BIT))) { mc_reset(); - } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { - bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); } else if (bit_istrue(pin,bit(CYCLE_START_BIT))) { bit_true(sys.rt_exec_state, EXEC_CYCLE_START); + #ifndef ENABLE_SAFETY_DOOR_INPUT_PIN + } else if (bit_istrue(pin,bit(FEED_HOLD_BIT))) { + bit_true(sys.rt_exec_state, EXEC_FEED_HOLD); + #else + } else if (bit_istrue(pin,bit(SAFETY_DOOR_BIT))) { + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + #endif } } } +// Returns if safety door is ajar(T) or closed(F), based on pin state. +uint8_t system_check_safety_door_ajar() +{ + #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN + #ifdef INVERT_CONTROL_PIN + return(bit_istrue(CONTROL_PIN,bit(SAFETY_DOOR_BIT))); + #else + return(bit_isfalse(CONTROL_PIN,bit(SAFETY_DOOR_BIT))); + #endif + #else + return(false); // Input pin not enabled, so just return that it's closed. + #endif +} + + // Executes user startup script, if stored. void system_execute_startup(char *line) { @@ -95,6 +115,7 @@ uint8_t system_execute_line(char *line) else { report_grbl_settings(); } break; case 'G' : // Prints gcode parser state + // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } else { report_gcode_modes(); } break; @@ -118,6 +139,10 @@ uint8_t system_execute_line(char *line) report_feedback_message(MESSAGE_ALARM_UNLOCK); sys.state = STATE_IDLE; // Don't run startup script. Prevents stored moves in startup from causing accidents. + if (system_check_safety_door_ajar()) { // Check safety door switch before returning. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } } // Otherwise, no effect. break; // case 'J' : break; // Jogging methods @@ -144,6 +169,14 @@ uint8_t system_execute_line(char *line) if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_HOMING; // Set system state variable // Only perform homing if Grbl is idle or lost. + + // TODO: Likely not required. + if (system_check_safety_door_ajar()) { // Check safety door switch before homing. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } + + mc_homing_cycle(); if (!sys.abort) { // Execute startup scripts after successful homing. sys.state = STATE_IDLE; // Set to IDLE when complete. diff --git a/grbl/system.h b/grbl/system.h index 2c2a89d9c..58b67d116 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -33,6 +33,8 @@ #define EXEC_CYCLE_STOP bit(2) // bitmask 00000100 #define EXEC_FEED_HOLD bit(3) // bitmask 00001000 #define EXEC_RESET bit(4) // bitmask 00010000 +#define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000 +#define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000 // Alarm executor bit map. // NOTE: EXEC_CRITICAL_EVENT is an optional flag that must be set with an alarm flag. When enabled, @@ -47,27 +49,34 @@ // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for // critical events. -#define STATE_IDLE 0 // Must be zero. No flags. -#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. -#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. -#define STATE_HOMING bit(2) // Performing homing cycle -#define STATE_QUEUED bit(3) // Indicates buffered blocks, awaiting cycle start. -#define STATE_CYCLE bit(4) // Cycle is running -#define STATE_HOLD bit(5) // Executing feed hold -// #define STATE_JOG bit(6) // Jogging mode is unique like homing. +#define STATE_IDLE 0 // Must be zero. No flags. +#define STATE_ALARM bit(0) // In alarm state. Locks out all g-code processes. Allows settings access. +#define STATE_CHECK_MODE bit(1) // G-code check mode. Locks out planner and motion only. +#define STATE_HOMING bit(2) // Performing homing cycle +#define STATE_CYCLE bit(3) // Cycle is running or motions are being executed. +#define STATE_HOLD bit(4) // Active feed hold +#define STATE_SAFETY_DOOR bit(5) // Safety door is ajar. Feed holds and de-energizes system. +#define STATE_MOTION_CANCEL bit(6) // Motion cancel by feed hold and return to idle. + +// Define system suspend states. +#define SUSPEND_DISABLE 0 // Must be zero. +#define SUSPEND_ENABLE_HOLD bit(0) // Enabled. Indicates the cycle is active and currently undergoing a hold. +#define SUSPEND_ENABLE_READY bit(1) // Ready to resume with a cycle start command. +#define SUSPEND_ENERGIZE bit(2) // Re-energizes output before resume. +#define SUSPEND_MOTION_CANCEL bit(3) // Cancels resume motion. Used by probing routine. // Define global system variables typedef struct { uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t state; // Tracks the current state of Grbl. + uint8_t suspend; // System suspend flag. Allows only realtime commands. Used primarily for holds. volatile uint8_t rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. int32_t position[N_AXIS]; // Real-time machine (aka home) position vector in steps. // NOTE: This may need to be a volatile variable, if problems arise. - uint8_t auto_start; // Planner auto-start flag. Toggled off during feed hold. Defaulted by settings. uint8_t homing_axis_lock; // Locks axes when limits engage. Used as an axis motion mask in the stepper ISR. volatile uint8_t probe_state; // Probing state value. Used to coordinate the probing cycle with stepper ISR. @@ -80,6 +89,9 @@ extern system_t sys; // Initialize the serial protocol void system_init(); +// Returns if safety door is open or closed, based on pin state. +uint8_t system_check_safety_door_ajar(); + // Executes an internal system command, defined as a string starting with a '$' uint8_t system_execute_line(char *line); From fe16b7db5ca79e814b34db24117ad68ca8773fed Mon Sep 17 00:00:00 2001 From: Rob Brown Date: Fri, 13 Feb 2015 16:17:07 +0800 Subject: [PATCH 25/74] Safety Door Update for Mega2560 --- grbl/cpu_map.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index a10568e56..6c9134cc5 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -222,16 +222,17 @@ #define RESET_BIT 0 // MEGA2560 Analog Pin 8 #define FEED_HOLD_BIT 1 // MEGA2560 Analog Pin 9 #define CYCLE_START_BIT 2 // MEGA2560 Analog Pin 10 + #define SAFETY_DOOR_BIT 3 // MEGA2560 Analog Pin 11 #define CONTROL_INT PCIE2 // Pin change interrupt enable pin #define CONTROL_INT_vect PCINT2_vect #define CONTROL_PCMSK PCMSK2 // Pin change interrupt register - #define CONTROL_MASK ((1< Date: Fri, 13 Feb 2015 22:50:07 +0100 Subject: [PATCH 26/74] Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error. --- grbl/system.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grbl/system.h b/grbl/system.h index 58b67d116..d6e190ed3 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -41,10 +41,10 @@ // this halts Grbl into an infinite loop until the user aknowledges the problem and issues a soft- // reset command. For example, a hard limit event needs this type of halt and aknowledgement. #define EXEC_CRITICAL_EVENT bit(0) // bitmask 00000001 (SPECIAL FLAG. See NOTE:) -#define EXEC_ALARM_HARD_LIMIT bit(0) // bitmask 00000010 -#define EXEC_ALARM_SOFT_LIMIT bit(1) // bitmask 00000100 -#define EXEC_ALARM_ABORT_CYCLE bit(2) // bitmask 00001000 -#define EXEC_ALARM_PROBE_FAIL bit(3) // bitmask 00010000 +#define EXEC_ALARM_HARD_LIMIT bit(1) // bitmask 00000010 +#define EXEC_ALARM_SOFT_LIMIT bit(2) // bitmask 00000100 +#define EXEC_ALARM_ABORT_CYCLE bit(3) // bitmask 00001000 +#define EXEC_ALARM_PROBE_FAIL bit(4) // bitmask 00010000 // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for From cff926f86159575ca29c75ec8571727a6a2e7049 Mon Sep 17 00:00:00 2001 From: Martin Poelstra Date: Fri, 13 Feb 2015 22:53:59 +0100 Subject: [PATCH 27/74] Fix generating header dependencies, merge with 'normal' compile, force recompile when files are removed. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 504bb9903..79fb3bf0d 100644 --- a/Makefile +++ b/Makefile @@ -50,8 +50,7 @@ OBJECTS = $(addprefix $(BUILDDIR)/,$(notdir $(SOURCE:.c=.o))) all: grbl.hex $(BUILDDIR)/%.o: $(SOURCEDIR)/%.c - $(COMPILE) -c $< -o $@ - @$(COMPILE) -MM $< > $(BUILDDIR)/$*.d + $(COMPILE) -MMD -MP -c $< -o $@ .S.o: $(COMPILE) -x assembler-with-cpp -c $< -o $(BUILDDIR)/$@ From 56c4bfc7b97a8c9304f405f15d3639702f03ef18 Mon Sep 17 00:00:00 2001 From: Martin Poelstra Date: Fri, 13 Feb 2015 22:57:11 +0100 Subject: [PATCH 28/74] Fix function signature of print_uint32_base10(), necessary for compiling simulator. --- grbl/print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grbl/print.c b/grbl/print.c index 781cedcaf..35d1c1cb1 100644 --- a/grbl/print.c +++ b/grbl/print.c @@ -100,7 +100,7 @@ void print_uint8_base10(uint8_t n) } -void print_uint32_base10(unsigned long n) +void print_uint32_base10(uint32_t n) { if (n == 0) { serial_write('0'); From 565519c1449173d8a91b5b39decbb2f8a1487ff2 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:39:37 -0700 Subject: [PATCH 29/74] Doc re-org. New Grbl Logos! --- doc/logo/Grbl Logo 150px.png | Bin 0 -> 10481 bytes doc/logo/Grbl Logo 320px.png | Bin 0 -> 58580 bytes doc/logo/Grbl Logo 640px.png | Bin 0 -> 48868 bytes doc/logo/Grbl Logo.pdf | Bin 0 -> 4837 bytes doc/logo/Grbl Logo.svg | 134 ++++++++++++++++++++++++ {script => doc/script}/simple_stream.py | 0 {script => doc/script}/stream.py | 0 grbl/config.h | 6 +- 8 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 doc/logo/Grbl Logo 150px.png create mode 100644 doc/logo/Grbl Logo 320px.png create mode 100644 doc/logo/Grbl Logo 640px.png create mode 100644 doc/logo/Grbl Logo.pdf create mode 100644 doc/logo/Grbl Logo.svg rename {script => doc/script}/simple_stream.py (100%) rename {script => doc/script}/stream.py (100%) diff --git a/doc/logo/Grbl Logo 150px.png b/doc/logo/Grbl Logo 150px.png new file mode 100644 index 0000000000000000000000000000000000000000..999886e6cb8cb83f97ad83b22c9300f42d83f506 GIT binary patch literal 10481 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/logo/Grbl Logo 640px.png b/doc/logo/Grbl Logo 640px.png new file mode 100644 index 0000000000000000000000000000000000000000..96a386a11e466452e8acc902f7b156a77fc280a5 GIT binary patch literal 48868 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 w;Fm~``jsYYKs7P9%_QhyVry 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 + + + + + image/svg+xml + + + + + + + /Users/chamnit/Dropbox/documents/OHS/Logo/Grbl.DXF - scale = 58.043118, origin = (0.000000, 0.000000), auto = True + + + + + + + + + + + + + + + + + + + + + + + diff --git a/script/simple_stream.py b/doc/script/simple_stream.py similarity index 100% rename from script/simple_stream.py rename to doc/script/simple_stream.py diff --git a/script/stream.py b/doc/script/stream.py similarity index 100% rename from script/stream.py rename to doc/script/stream.py diff --git a/grbl/config.h b/grbl/config.h index 0635c6594..946e25a22 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -54,7 +54,7 @@ #define CMD_FEED_HOLD '!' #define CMD_CYCLE_START '~' #define CMD_RESET 0x18 // ctrl-x. -#define CMD_SAFETY_DOOR '@' //0x13 // ctrl-s +#define CMD_SAFETY_DOOR '@' // If homing is enabled, homing init lock sets Grbl into an alarm state upon power up. This forces // the user to perform the homing cycle (or override the locks) before doing anything else. This is @@ -143,8 +143,8 @@ // After the safety door switch has been toggled and restored, this setting sets the power-up delay // between restoring the spindle and coolant and resuming the cycle. // NOTE: Delay value is defined in milliseconds from zero to 65,535. -#define SAFETY_DOOR_SPINDLE_DELAY 4000 // Disabled by default. Comment to enable. -#define SAFETY_DOOR_COOLANT_DELAY 1000 // Disabled by default. Comment to enable. +#define SAFETY_DOOR_SPINDLE_DELAY 4000 +#define SAFETY_DOOR_COOLANT_DELAY 1000 // Enable CoreXY kinematics. Use ONLY with CoreXY machines. // IMPORTANT: If homing is enabled, you must reconfigure the homing cycle #defines above to From 5a547dbb3396dff01d2fd4f8fdfa7255a6a3be44 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:45:55 -0700 Subject: [PATCH 30/74] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1cfa679ce..ae6b692ef 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -#Grbl - An embedded g-code interpreter and motion-controller for the Arduino/AVR328 microcontroller +![GitHub Logo](/doc/logo/Grbl Logo 320px.png) + *** From fd02c3a47ec4eab48ffd87ac1720e81ca03c0cfb Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 13 Feb 2015 18:48:15 -0700 Subject: [PATCH 31/74] Updated README with new logo sized for github. --- README.md | 2 +- doc/logo/Grbl Logo 250px.png | Bin 0 -> 42049 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 doc/logo/Grbl Logo 250px.png diff --git a/README.md b/README.md index ae6b692ef..e03cc0f45 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![GitHub Logo](/doc/logo/Grbl Logo 320px.png) +![GitHub Logo](/doc/logo/Grbl Logo 250px.png) *** diff --git a/doc/logo/Grbl Logo 250px.png b/doc/logo/Grbl Logo 250px.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9319b3d7c5593ea2b521ca856b2685297d2fc6 GIT binary patch literal 42049 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 Date: Sun, 15 Feb 2015 17:36:08 -0700 Subject: [PATCH 32/74] Homing alarm upon no switch. Licensing update. - Homing cycle failure reports alarm feedback when the homing cycle is exited via a reset, interrupted by a safety door switch, or does not find the limit switch. - Homing cycle bug fix when not finding the limit switch. It would just idle before, but now will exit with an alarm. - Licensing update. Corrected licensing according to lawyer recommendations. Removed references to other Grbl versions. --- COPYING | 45 +++++++++--------------------------------- grbl/config.h | 11 +++-------- grbl/coolant_control.c | 2 +- grbl/coolant_control.h | 2 +- grbl/cpu_map.h | 2 +- grbl/defaults.h | 2 +- grbl/eeprom.h | 28 ++++++++++---------------- grbl/gcode.c | 13 ++++-------- grbl/gcode.h | 11 +++-------- grbl/grbl.h | 2 +- grbl/limits.c | 16 ++++++--------- grbl/limits.h | 10 +++------- grbl/main.c | 13 ++++-------- grbl/motion_control.c | 16 ++++++--------- grbl/motion_control.h | 11 +++-------- grbl/nuts_bolts.c | 11 +++-------- grbl/nuts_bolts.h | 11 +++-------- grbl/planner.c | 13 ++++-------- grbl/planner.h | 11 +++-------- grbl/print.c | 11 +++-------- grbl/print.h | 11 +++-------- grbl/probe.c | 2 +- grbl/probe.h | 2 +- grbl/protocol.c | 15 ++++++-------- grbl/protocol.h | 11 +++-------- grbl/report.c | 4 +++- grbl/report.h | 3 ++- grbl/serial.c | 11 +++-------- grbl/serial.h | 11 +++-------- grbl/settings.c | 11 +++-------- grbl/settings.h | 11 +++-------- grbl/spindle_control.c | 9 ++------- grbl/spindle_control.h | 9 ++------- grbl/stepper.c | 11 +++-------- grbl/stepper.h | 11 +++-------- grbl/system.c | 2 +- grbl/system.h | 3 ++- 37 files changed, 116 insertions(+), 262 deletions(-) diff --git a/COPYING b/COPYING index 8bc83929b..cdf88d6a9 100644 --- a/COPYING +++ b/COPYING @@ -1,56 +1,31 @@ ------------------------------------------------------------------------------ -COPYRIGHT NOTICE FOR GRBL v0.9: +COPYRIGHT NOTICE FOR GRBL: ------------------------------------------------------------------------------ -GRBL v0.9 - Embedded CNC g-code interpreter and motion-controller -Copyright (c) 2012-2014 Sungeun K. Jeon +Grbl - Embedded CNC g-code interpreter and motion-controller -This program is free software: you can redistribute it and/or modify +Copyright (c) 2011-2015 Sungeun K. Jeon +Copyright (c) 2009-2011 Simen Svale Skogsrud +Copyright (c) 2011 Jens Geisler + +Grbl 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. -This program is distributed in the hope that it will be useful, +Grbl 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 this program. If not, see . - +along with Grbl. If not, see . ------------------------------------------------------------------------------ COPYRIGHT NOTICE(S) FOR WORK CONTAINED IN THIS SOFTWARE: ------------------------------------------------------------------------------ -The MIT License (MIT) - -GRBL(tm) v0.8 - Embedded CNC g-code interpreter and motion-controller -Copyright (c) 2009-2011 Simen Svale Skogsrud -Copyright (c) 2011-2013 Sungeun K. Jeon -Copyright (c) 2011 Jens Geisler - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - -------------- - Copyright (c) 2008, Atmel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -704,5 +679,3 @@ Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS - ------------------------------------------------------------------------------- diff --git a/grbl/config.h b/grbl/config.h index 946e25a22..e51b27c6a 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -1,8 +1,9 @@ /* config.h - compile time configuration - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2013-2015 Sungeun K. Jeon + Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2013 Sungeun K. Jeon -*/ // This file contains compile-time configurations for Grbl's internal system. For the most part, // users will not need to directly modify these, but they are here for specific needs, i.e. diff --git a/grbl/coolant_control.c b/grbl/coolant_control.c index f94f51ad2..4429dd4f2 100644 --- a/grbl/coolant_control.c +++ b/grbl/coolant_control.c @@ -1,6 +1,6 @@ /* coolant_control.c - coolant control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/coolant_control.h b/grbl/coolant_control.h index f093cee29..7694a78d9 100644 --- a/grbl/coolant_control.h +++ b/grbl/coolant_control.h @@ -1,6 +1,6 @@ /* coolant_control.h - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 6c9134cc5..64696163b 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -1,6 +1,6 @@ /* cpu_map.h - CPU and pin mapping configuration file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/defaults.h b/grbl/defaults.h index 06dc0f7ba..f21b31e24 100644 --- a/grbl/defaults.h +++ b/grbl/defaults.h @@ -1,6 +1,6 @@ /* defaults.h - defaults settings configuration file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon diff --git a/grbl/eeprom.h b/grbl/eeprom.h index 0743425a8..c9718a2b6 100644 --- a/grbl/eeprom.h +++ b/grbl/eeprom.h @@ -2,28 +2,20 @@ eeprom.h - EEPROM methods Part of Grbl - The MIT License (MIT) - - GRBL(tm) - Embedded CNC g-code interpreter and motion-controller Copyright (c) 2009-2011 Simen Svale Skogsrud - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Grbl 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. - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. + Grbl 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. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. + You should have received a copy of the GNU General Public License + along with Grbl. If not, see . */ #ifndef eeprom_h diff --git a/grbl/gcode.c b/grbl/gcode.c index 4b215e0cf..b915e486d 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1,9 +1,10 @@ /* gcode.c - rs274/ngc parser. - Part of Grbl v0.9 + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012-2015 Sungeun K. Jeon - Grbl 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/gcode.h b/grbl/gcode.h index d1ee3d5e3..0b478d073 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -1,8 +1,9 @@ /* gcode.h - rs274/ngc parser. - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef gcode_h #define gcode_h diff --git a/grbl/grbl.h b/grbl/grbl.h index dc331bfd0..42e2fcfb9 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -1,6 +1,6 @@ /* grbl.h - main Grbl include file - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2015 Sungeun K. Jeon diff --git a/grbl/limits.c b/grbl/limits.c index 84374f31d..57de228bd 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -1,9 +1,10 @@ /* limits.c - code pertaining to limit-switches and performing the homing cycle - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon - + Copyright (c) 2009-2011 Simen Svale Skogsrud + Grbl 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon -*/ #include "grbl.h" @@ -202,8 +197,9 @@ void limits_go_home(uint8_t cycle_mask) st_prep_buffer(); // Check and prep segment buffer. NOTE: Should take no longer than 200us. // Check only for user reset. No time to run protocol_execute_realtime() in this loop. - if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET)) { // Abort homing and alarm upon safety door. - if (sys.rt_exec_state & EXEC_SAFETY_DOOR) { mc_reset(); } + // Exit routines: User abort homing and alarm upon safety door or no limit switch found. + if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_RESET | EXEC_CYCLE_STOP)) { + if (sys.rt_exec_state & (EXEC_SAFETY_DOOR | EXEC_CYCLE_STOP)) { mc_reset(); } protocol_execute_realtime(); return; } diff --git a/grbl/limits.h b/grbl/limits.h index 4c96a5de6..0a5084a95 100644 --- a/grbl/limits.h +++ b/grbl/limits.h @@ -1,9 +1,10 @@ /* limits.h - code pertaining to limit-switches and performing the homing cycle - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon - + Copyright (c) 2009-2011 Simen Svale Skogsrud + Grbl 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 @@ -17,11 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud -*/ #ifndef limits_h #define limits_h diff --git a/grbl/main.c b/grbl/main.c index 080d224ef..ef63659e2 100644 --- a/grbl/main.c +++ b/grbl/main.c @@ -1,9 +1,10 @@ /* main.c - An embedded CNC Controller with rs274/ngc (g-code) support - Part of Grbl v0.9 + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012-2015 Sungeun K. Jeon - Grbl 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 @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/motion_control.c b/grbl/motion_control.c index 2a34af62a..bfd42d7b0 100644 --- a/grbl/motion_control.c +++ b/grbl/motion_control.c @@ -1,8 +1,10 @@ /* motion_control.c - high level interface for issuing motion commands - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +19,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon - Copyright (c) 2011 Jens Geisler -*/ #include "grbl.h" @@ -361,7 +356,8 @@ void mc_reset() // the steppers enabled by avoiding the go_idle call altogether, unless the motion state is // violated, by which, all bets are off. if ((sys.state & (STATE_CYCLE | STATE_HOMING)) || (sys.suspend == SUSPEND_ENABLE_HOLD)) { - bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); + if (sys.state == STATE_HOMING) { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_HOMING_FAIL); } + else { bit_true_atomic(sys.rt_exec_alarm, EXEC_ALARM_ABORT_CYCLE); } st_go_idle(); // Force kill steppers. Position has likely been lost. } } diff --git a/grbl/motion_control.h b/grbl/motion_control.h index 1cd1b2e80..584d231f6 100644 --- a/grbl/motion_control.h +++ b/grbl/motion_control.h @@ -1,8 +1,9 @@ /* motion_control.h - high level interface for issuing motion commands - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef motion_control_h #define motion_control_h diff --git a/grbl/nuts_bolts.c b/grbl/nuts_bolts.c index 7da9d7e7c..b33e2306d 100644 --- a/grbl/nuts_bolts.c +++ b/grbl/nuts_bolts.c @@ -1,8 +1,9 @@ /* nuts_bolts.c - Shared functions - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/nuts_bolts.h b/grbl/nuts_bolts.h index 5f11eb20c..882d33733 100644 --- a/grbl/nuts_bolts.h +++ b/grbl/nuts_bolts.h @@ -1,8 +1,9 @@ /* nuts_bolts.h - Header file for shared definitions, variables, and functions - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef nuts_bolts_h #define nuts_bolts_h diff --git a/grbl/planner.c b/grbl/planner.c index 0946ce121..dcf50ece2 100644 --- a/grbl/planner.c +++ b/grbl/planner.c @@ -1,8 +1,10 @@ /* planner.c - buffers movement commands and manages the acceleration profile plan - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2011 Jens Geisler Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,13 +19,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon - Copyright (c) 2011 Jens Geisler -*/ #include "grbl.h" diff --git a/grbl/planner.h b/grbl/planner.h index 8209c024c..02258dd4e 100644 --- a/grbl/planner.h +++ b/grbl/planner.h @@ -1,8 +1,9 @@ /* planner.h - buffers movement commands and manages the acceleration profile plan - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef planner_h #define planner_h diff --git a/grbl/print.c b/grbl/print.c index 35d1c1cb1..1dd8d7bca 100644 --- a/grbl/print.c +++ b/grbl/print.c @@ -1,8 +1,9 @@ /* print.c - Functions for formatting output strings - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/print.h b/grbl/print.h index 7b2040f64..658e892fc 100644 --- a/grbl/print.h +++ b/grbl/print.h @@ -1,8 +1,9 @@ /* print.h - Functions for formatting output strings - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef print_h #define print_h diff --git a/grbl/probe.c b/grbl/probe.c index 133d73b3c..3bba4df05 100644 --- a/grbl/probe.c +++ b/grbl/probe.c @@ -1,6 +1,6 @@ /* probe.c - code pertaining to probing methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/probe.h b/grbl/probe.h index 1e8674da7..81bd48696 100644 --- a/grbl/probe.h +++ b/grbl/probe.h @@ -1,6 +1,6 @@ /* probe.h - code pertaining to probing methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/protocol.c b/grbl/protocol.c index e6abd4f61..2b81f001e 100644 --- a/grbl/protocol.c +++ b/grbl/protocol.c @@ -1,8 +1,9 @@ /* protocol.c - controls Grbl execution protocol and procedures - Part of Grbl v0.9 - - Copyright (c) 2012-2015 Sungeun K. Jeon + Part of Grbl + + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" @@ -198,6 +193,8 @@ void protocol_execute_realtime() report_alarm_message(ALARM_ABORT_CYCLE); } else if (rt_exec & EXEC_ALARM_PROBE_FAIL) { report_alarm_message(ALARM_PROBE_FAIL); + } else if (rt_exec & EXEC_ALARM_HOMING_FAIL) { + report_alarm_message(ALARM_HOMING_FAIL); } // Halt everything upon a critical event flag. Currently hard and soft limits flag this. if (rt_exec & EXEC_CRITICAL_EVENT) { diff --git a/grbl/protocol.h b/grbl/protocol.h index 6095bd729..3fc3780d6 100644 --- a/grbl/protocol.h +++ b/grbl/protocol.h @@ -1,8 +1,9 @@ /* protocol.h - controls Grbl execution protocol and procedures - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef protocol_h #define protocol_h diff --git a/grbl/report.c b/grbl/report.c index 6e86ca66e..1a84a0c92 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -1,6 +1,6 @@ /* report.c - reporting and messaging methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon @@ -98,6 +98,8 @@ void report_alarm_message(int8_t alarm_code) printPgmString(PSTR("Abort during cycle")); break; case ALARM_PROBE_FAIL: printPgmString(PSTR("Probe fail")); break; + case ALARM_HOMING_FAIL: + printPgmString(PSTR("Homing fail")); break; } printPgmString(PSTR("\r\n")); delay_ms(500); // Force delay to ensure message clears serial write buffer. diff --git a/grbl/report.h b/grbl/report.h index 60ab9601b..cfd0d8b2c 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -1,6 +1,6 @@ /* report.h - reporting and messaging methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon @@ -59,6 +59,7 @@ #define ALARM_SOFT_LIMIT_ERROR -2 #define ALARM_ABORT_CYCLE -3 #define ALARM_PROBE_FAIL -4 +#define ALARM_HOMING_FAIL -5 // Define Grbl feedback message codes. #define MESSAGE_CRITICAL_EVENT 1 diff --git a/grbl/serial.c b/grbl/serial.c index a327defc7..edfbecf7d 100644 --- a/grbl/serial.c +++ b/grbl/serial.c @@ -1,8 +1,9 @@ /* serial.c - Low level functions for sending and recieving bytes via the serial port - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/serial.h b/grbl/serial.h index 9c28afdfa..b48fd35e4 100644 --- a/grbl/serial.h +++ b/grbl/serial.h @@ -1,8 +1,9 @@ /* serial.c - Low level functions for sending and recieving bytes via the serial port - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef serial_h #define serial_h diff --git a/grbl/settings.c b/grbl/settings.c index cd1e63b90..956cb021e 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -1,8 +1,9 @@ /* settings.c - eeprom configuration handling - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/settings.h b/grbl/settings.h index 01acd691d..5090824f5 100644 --- a/grbl/settings.h +++ b/grbl/settings.h @@ -1,8 +1,9 @@ /* settings.h - eeprom configuration handling - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #ifndef settings_h #define settings_h diff --git a/grbl/spindle_control.c b/grbl/spindle_control.c index abad6c27d..f0724b4f1 100644 --- a/grbl/spindle_control.c +++ b/grbl/spindle_control.c @@ -1,8 +1,9 @@ /* spindle_control.c - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/spindle_control.h b/grbl/spindle_control.h index 0c728da71..1aec91ca4 100644 --- a/grbl/spindle_control.h +++ b/grbl/spindle_control.h @@ -1,8 +1,9 @@ /* spindle_control.h - spindle control methods - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -16,12 +17,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . -*/ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon */ #ifndef spindle_control_h diff --git a/grbl/stepper.c b/grbl/stepper.c index fafb10466..155b805c7 100644 --- a/grbl/stepper.c +++ b/grbl/stepper.c @@ -1,8 +1,9 @@ /* stepper.c - stepper motor driver: executes motion plans using stepper motors - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon -*/ #include "grbl.h" diff --git a/grbl/stepper.h b/grbl/stepper.h index fe4d853f4..074570461 100644 --- a/grbl/stepper.h +++ b/grbl/stepper.h @@ -1,8 +1,9 @@ /* stepper.h - stepper motor driver: executes motion plans of planner.c using the stepper motors - Part of Grbl v0.9 + Part of Grbl - Copyright (c) 2012-2015 Sungeun K. Jeon + Copyright (c) 2011-2015 Sungeun K. Jeon + Copyright (c) 2009-2011 Simen Svale Skogsrud Grbl is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,12 +18,6 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ -/* - This file is based on work from Grbl v0.8, distributed under the - terms of the MIT-license. See COPYING for more details. - Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011 Sungeun K. Jeon -*/ #ifndef stepper_h #define stepper_h diff --git a/grbl/system.c b/grbl/system.c index 7a0916247..2f3d1005c 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -1,6 +1,6 @@ /* system.c - Handles system level commands and real-time processes - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon diff --git a/grbl/system.h b/grbl/system.h index d6e190ed3..a74f02915 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -1,6 +1,6 @@ /* system.h - Header for system level commands and real-time processes - Part of Grbl v0.9 + Part of Grbl Copyright (c) 2014-2015 Sungeun K. Jeon @@ -45,6 +45,7 @@ #define EXEC_ALARM_SOFT_LIMIT bit(2) // bitmask 00000100 #define EXEC_ALARM_ABORT_CYCLE bit(3) // bitmask 00001000 #define EXEC_ALARM_PROBE_FAIL bit(4) // bitmask 00010000 +#define EXEC_ALARM_HOMING_FAIL bit(5) // bitmask 00100000 // Define system state bit map. The state variable primarily tracks the individual functions // of Grbl to manage each without overlapping. It is also used as a messaging flag for From d034dc21817059a0ec2e679207ebf532212932d9 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sun, 15 Feb 2015 19:23:16 -0700 Subject: [PATCH 33/74] Improved homing limit search handling. - Instead of a single overall max travel for a search distance for the homing limit switches. The homing cycle now applies the max travel of each axis to the search target. Generally makes more sense this way and saved more than a 100bytes of flash too. --- README.md | 4 ++-- grbl/grbl.h | 2 +- grbl/limits.c | 22 +++++++--------------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e03cc0f45..3e69e2341 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,11 @@ It accepts standards-compliant g-code and has been tested with the output of sev Grbl includes full acceleration management with look ahead. That means the controller will look up to 18 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering. -* [Licensing](https://github.com/grbl/grbl/wiki/Licensing): Grbl v0.9 is free software, released under the GPLv3 license. Obsolete versions of Grbl, v0.8 and prior, are released under the permissive MIT-license. This will ensure Grbl will always be an open-source project while making the code permissive for others. +* [Licensing](https://github.com/grbl/grbl/wiki/Licensing): Grbl is free software, released under the GPLv3 license. * For more information and help, check out our **[Wiki pages!](https://github.com/grbl/grbl/wiki)** If you find that the information is out-dated, please to help us keep it updated by editing it or notifying our community! Thanks! -* Lead Developer [_2011 - Current_]: Sonny Jeon, Ph.D. (USA) +* Lead Developer [_2011 - Current_]: Sungeun(Sonny) K. Jeon, Ph.D. (USA) aka @chamnit * Lead Developer [_2009 - 2011_]: Simen Svale Skogsrud (Norway). aka The Originator/Creator/Pioneer/Father of Grbl. diff --git a/grbl/grbl.h b/grbl/grbl.h index 42e2fcfb9..08e7dd7eb 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150210" +#define GRBL_VERSION_BUILD "20150215" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 57de228bd..6f00b0627 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -124,7 +124,7 @@ void limits_go_home(uint8_t cycle_mask) float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; - float max_travel = 0.0; + float max_travel; for (idx=0; idx settings.max_travel[idx]) { max_travel = settings.max_travel[idx]; } } - max_travel *= -HOMING_AXIS_SEARCH_SCALAR; // Ensure homing switches engaged by over-estimating max travel. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. plan_sync_position(); // Sync planner position to current machine position. @@ -156,15 +151,12 @@ void limits_go_home(uint8_t cycle_mask) // Set target location for active axes and setup computation for homing rate. if (bit_istrue(cycle_mask,bit(idx))) { n_active_axis++; - if (approach) { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] -= max_travel; } - else { target[idx] += max_travel; } - } else { - // Set target direction based on cycle mask - if (bit_istrue(settings.homing_dir_mask,bit(idx))) { target[idx] += max_travel; } - else { target[idx] -= max_travel; } - } + // Set target based on max_travel setting. Ensure homing switches engaged with search scalar. + // NOTE: settings.max_travel[] is stored as a negative value. + max_travel = (-HOMING_AXIS_SEARCH_SCALAR)*settings.max_travel[idx]; + if (bit_istrue(settings.homing_dir_mask,bit(idx))) { max_travel = -max_travel; } + if (!approach) { max_travel = -max_travel; } + target[idx] += max_travel; } // Apply axislock to the step port pins active in this cycle. From c7db1c4546665174adad0664b73d6792a2a6dfb1 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 23 Feb 2015 18:45:26 -0700 Subject: [PATCH 34/74] New configuration options. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New configuration option at compile-time: - Force alarm upon power-up or hard reset. When homing is enabled, this is already the default behavior. This simply forces this all of the time. - GUI reporting mode. Removes most human-readable strings that GUIs don’t need. This saves nearly 2KB in flash space that can be used for other features. - Hard limit force state check: In the hard limit pin change ISR, Grbl by default sets the hard limit alarm upon any pin change to guarantee the alarm is set. If this option is set, it’ll check the state within the ISR, but can’t guarantee the pin will be read correctly if the switch is bouncing. This option makes hard limit behavior a little less annoying if you have a good buffered switch circuit that removes bouncing and electronic noise. - Software debounce bug fix. It was reading the pin incorrectly for the setting. - Re-factored some of the ‘$’ settings code. --- grbl/config.h | 34 ++++++- grbl/grbl.h | 4 +- grbl/limits.c | 20 +++-- grbl/main.c | 5 ++ grbl/report.c | 239 +++++++++++++++++++++++++++++--------------------- grbl/system.c | 97 ++++++++++---------- 6 files changed, 240 insertions(+), 159 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index e51b27c6a..297742e9a 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -106,8 +106,8 @@ // this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell // which one is enabled. This option only effects homing, where if a limit is engaged, Grbl will // alarm out and force the user to manually disengage the limit switch. Otherwise, if you have one -// limit switch for each axis, don't enable this option. By keeping it disabled, you can homing while -// on the limit switch and not have to move the machine off of it. +// limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a +// homing cycle while on the limit switch and not have to move the machine off of it. // #define LIMITS_TWO_SWITCHES_ON_AXES // Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer @@ -161,9 +161,22 @@ // with little to no benefit during normal operation. // #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. +// When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM +// by default. This is to make it as simple as possible for new users to start using Grbl. When homing +// is enabled and a user has installed limit switches, Grbl will boot up in an ALARM state to indicate +// Grbl doesn't know its position and to force the user to home before proceeding. This option forces +// Grbl to always initialize into an ALARM state regardless of homing or not. This option is more for +// OEMs and LinuxCNC users that would like this power-cycle behavior. +// #define FORCE_INITIALIZATION_ALARM // Default disabled. Uncomment to enable. + // --------------------------------------------------------------------------------------- // ADVANCED CONFIGURATION OPTIONS: +// Enables minimal reporting feedback mode for GUIs, where human-readable strings are not as important. +// This saves nearly 2KB of flash space and may allow enough space to install other/future features. +// NOTE: This feature is new and experimental. Make sure the GUI you are using supports this mode. +#define REPORT_GUI_MODE // Default disabled. Uncomment to enable. + // The temporal resolution of the acceleration management subsystem. A higher number gives smoother // acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively // impact performance. The correct value for this parameter is machine dependent, so it's advised to @@ -180,8 +193,10 @@ // step smoothing. See stepper.c for more details on the AMASS system works. #define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. -// Sets the maximum step rate allowed to be written as a Grbl setting. This value is strictly limited -// by the CPU speed and will change if something other than an AVR running at 16MHz is used. +// Sets the maximum step rate allowed to be written as a Grbl setting. This option enables an error +// check in the settings module to prevent settings values that will exceed this limitation. The maximum +// step rate is strictly limited by the CPU speed and will change if something other than an AVR running +// at 16MHz is used. // NOTE: For now disabled, will enable if flash space permits. // #define MAX_STEP_RATE_HZ 30000 // Hz @@ -318,6 +333,17 @@ // work well and are cheap to find) and wire in a low-pass circuit into each limit pin. // #define ENABLE_SOFTWARE_DEBOUNCE // Default disabled. Uncomment to enable. +// Force Grbl to check the state of the hard limit switches when the processor detects a pin +// change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits +// alarm upon any pin change, since bouncing switches can cause a state check like this to +// misread the pin. When hard limits are triggers, this should be 100% reliable, which is the +// reason that this option is disabled by default. Only if your system/electronics can guarantee +// the pins don't bounce, we recommend enabling this option. If so, this will help prevent +// triggering a hard limit when the machine disengages from the switch. +// NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled. +// #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. + + // --------------------------------------------------------------------------------------- // TODO: Install compile-time option to send numeric status codes rather than strings. diff --git a/grbl/grbl.h b/grbl/grbl.h index 08e7dd7eb..ff9226989 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -22,8 +22,8 @@ #define grbl_h // Grbl versioning system -#define GRBL_VERSION "0.9h" -#define GRBL_VERSION_BUILD "20150215" +#define GRBL_VERSION "0.9i" +#define GRBL_VERSION_BUILD "20150223" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 6f00b0627..75b9f8233 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -79,8 +79,18 @@ void limits_disable() // limit setting if their limits are constantly triggering after a reset and move their axes. if (sys.state != STATE_ALARM) { if (!(sys.rt_exec_alarm)) { - mc_reset(); // Initiate system kill. - bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + #ifdef HARD_LIMIT_FORCE_STATE_CHECK + uint8_t bits = (LIMIT_PIN & LIMIT_MASK); + // Check limit pin state. + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; } + if (bits) { + mc_reset(); // Initiate system kill. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + } + #else + mc_reset(); // Initiate system kill. + bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + #endif } } } @@ -92,10 +102,10 @@ void limits_disable() WDTCSR &= ~(1< 30kHz")); break; + #ifdef REPORT_GUI_MODE + print_uint8_base10(status_code); + #else + switch(status_code) { + case STATUS_EXPECTED_COMMAND_LETTER: + printPgmString(PSTR("Expected command letter")); break; + case STATUS_BAD_NUMBER_FORMAT: + printPgmString(PSTR("Bad number format")); break; + case STATUS_INVALID_STATEMENT: + printPgmString(PSTR("Invalid statement")); break; + case STATUS_NEGATIVE_VALUE: + printPgmString(PSTR("Value < 0")); break; + case STATUS_SETTING_DISABLED: + printPgmString(PSTR("Setting disabled")); break; + case STATUS_SETTING_STEP_PULSE_MIN: + printPgmString(PSTR("Value < 3 usec")); break; + case STATUS_SETTING_READ_FAIL: + printPgmString(PSTR("EEPROM read fail. Using defaults")); break; + case STATUS_IDLE_ERROR: + printPgmString(PSTR("Not idle")); break; + case STATUS_ALARM_LOCK: + printPgmString(PSTR("Alarm lock")); break; + case STATUS_SOFT_LIMIT_ERROR: + printPgmString(PSTR("Homing not enabled")); break; + case STATUS_OVERFLOW: + printPgmString(PSTR("Line overflow")); break; + // case STATUS_MAX_STEP_RATE_EXCEEDED: + // printPgmString(PSTR("Step rate > 30kHz")); break; - // Common g-code parser errors. - case STATUS_GCODE_MODAL_GROUP_VIOLATION: - printPgmString(PSTR("Modal group violation")); break; - case STATUS_GCODE_UNSUPPORTED_COMMAND: - printPgmString(PSTR("Unsupported command")); break; - case STATUS_GCODE_UNDEFINED_FEED_RATE: - printPgmString(PSTR("Undefined feed rate")); break; - default: - // Remaining g-code parser errors with error codes - printPgmString(PSTR("Invalid gcode ID:")); - print_uint8_base10(status_code); // Print error code for user reference - } + // Common g-code parser errors. + case STATUS_GCODE_MODAL_GROUP_VIOLATION: + printPgmString(PSTR("Modal group violation")); break; + case STATUS_GCODE_UNSUPPORTED_COMMAND: + printPgmString(PSTR("Unsupported command")); break; + case STATUS_GCODE_UNDEFINED_FEED_RATE: + printPgmString(PSTR("Undefined feed rate")); break; + default: + // Remaining g-code parser errors with error codes + printPgmString(PSTR("Invalid gcode ID:")); + print_uint8_base10(status_code); // Print error code for user reference + } + #endif printPgmString(PSTR("\r\n")); } } @@ -89,18 +93,22 @@ void report_status_message(uint8_t status_code) void report_alarm_message(int8_t alarm_code) { printPgmString(PSTR("ALARM: ")); - switch (alarm_code) { - case ALARM_HARD_LIMIT_ERROR: - printPgmString(PSTR("Hard limit")); break; - case ALARM_SOFT_LIMIT_ERROR: - printPgmString(PSTR("Soft limit")); break; - case ALARM_ABORT_CYCLE: - printPgmString(PSTR("Abort during cycle")); break; - case ALARM_PROBE_FAIL: - printPgmString(PSTR("Probe fail")); break; - case ALARM_HOMING_FAIL: - printPgmString(PSTR("Homing fail")); break; - } + #ifdef REPORT_GUI_MODE + print_uint8_base10(alarm_code); + #else + switch (alarm_code) { + case ALARM_HARD_LIMIT_ERROR: + printPgmString(PSTR("Hard limit")); break; + case ALARM_SOFT_LIMIT_ERROR: + printPgmString(PSTR("Soft limit")); break; + case ALARM_ABORT_CYCLE: + printPgmString(PSTR("Abort during cycle")); break; + case ALARM_PROBE_FAIL: + printPgmString(PSTR("Probe fail")); break; + case ALARM_HOMING_FAIL: + printPgmString(PSTR("Homing fail")); break; + } + #endif printPgmString(PSTR("\r\n")); delay_ms(500); // Force delay to ensure message clears serial write buffer. } @@ -140,20 +148,22 @@ void report_init_message() // Grbl help message void report_grbl_help() { - printPgmString(PSTR("$$ (view Grbl settings)\r\n" - "$# (view # parameters)\r\n" - "$G (view parser state)\r\n" - "$I (view build info)\r\n" - "$N (view startup blocks)\r\n" - "$x=value (save Grbl setting)\r\n" - "$Nx=line (save startup block)\r\n" - "$C (check gcode mode)\r\n" - "$X (kill alarm lock)\r\n" - "$H (run homing cycle)\r\n" - "~ (cycle start)\r\n" - "! (feed hold)\r\n" - "? (current status)\r\n" - "ctrl-x (reset Grbl)\r\n")); + #ifndef REPORT_GUI_MODE + printPgmString(PSTR("$$ (view Grbl settings)\r\n" + "$# (view # parameters)\r\n" + "$G (view parser state)\r\n" + "$I (view build info)\r\n" + "$N (view startup blocks)\r\n" + "$x=value (save Grbl setting)\r\n" + "$Nx=line (save startup block)\r\n" + "$C (check gcode mode)\r\n" + "$X (kill alarm lock)\r\n" + "$H (run homing cycle)\r\n" + "~ (cycle start)\r\n" + "! (feed hold)\r\n" + "? (current status)\r\n" + "ctrl-x (reset Grbl)\r\n")); + #endif } @@ -161,31 +171,54 @@ void report_grbl_help() { // NOTE: The numbering scheme here must correlate to storing in settings.c void report_grbl_settings() { // Print Grbl settings. - printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); - printPgmString(PSTR(" (step pulse, usec)\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); - printPgmString(PSTR(" (step idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask); - printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); - printPgmString(PSTR(")\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); - printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask); - printPgmString(PSTR(")\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); - printPgmString(PSTR(" (step enable invert, bool)\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); - printPgmString(PSTR(" (limit pins invert, bool)\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); - printPgmString(PSTR(" (probe pin invert, bool)\r\n$10=")); print_uint8_base10(settings.status_report_mask); - printPgmString(PSTR(" (status report mask:")); print_uint8_base2(settings.status_report_mask); - printPgmString(PSTR(")\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); - printPgmString(PSTR(" (junction deviation, mm)\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); - printPgmString(PSTR(" (arc tolerance, mm)\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); - printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); - printPgmString(PSTR(" (soft limits, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); - printPgmString(PSTR(" (hard limits, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); - printPgmString(PSTR(" (homing cycle, bool)\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); - printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); - printPgmString(PSTR(")\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); - printPgmString(PSTR(" (homing feed, mm/min)\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); - printPgmString(PSTR(" (homing seek, mm/min)\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); - printPgmString(PSTR(" (homing debounce, msec)\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); - printPgmString(PSTR(" (homing pull-off, mm)\r\n")); - + #ifdef REPORT_GUI_MODE + printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); + printPgmString(PSTR("\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); + printPgmString(PSTR("\r\n$2=")); print_uint8_base10(settings.step_invert_mask); + printPgmString(PSTR("\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); + printPgmString(PSTR("\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + printPgmString(PSTR("\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + printPgmString(PSTR("\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + printPgmString(PSTR("\r\n$10=")); print_uint8_base10(settings.status_report_mask); + printPgmString(PSTR("\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); + printPgmString(PSTR("\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); + printPgmString(PSTR("\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR("\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + printPgmString(PSTR("\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + printPgmString(PSTR("\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + printPgmString(PSTR("\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); + printPgmString(PSTR("\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); + printPgmString(PSTR("\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); + printPgmString(PSTR("\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); + printPgmString(PSTR("\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); + printPgmString(PSTR("\r\n")); + #else + printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); + printPgmString(PSTR(" (step pulse, usec)\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); + printPgmString(PSTR(" (step idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask); + printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); + printPgmString(PSTR(")\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); + printPgmString(PSTR(" (dir port invert mask:")); print_uint8_base2(settings.dir_invert_mask); + printPgmString(PSTR(")\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + printPgmString(PSTR(" (step enable invert, bool)\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); + printPgmString(PSTR(" (limit pins invert, bool)\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); + printPgmString(PSTR(" (probe pin invert, bool)\r\n$10=")); print_uint8_base10(settings.status_report_mask); + printPgmString(PSTR(" (status report mask:")); print_uint8_base2(settings.status_report_mask); + printPgmString(PSTR(")\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); + printPgmString(PSTR(" (junction deviation, mm)\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); + printPgmString(PSTR(" (arc tolerance, mm)\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + printPgmString(PSTR(" (soft limits, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + printPgmString(PSTR(" (hard limits, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + printPgmString(PSTR(" (homing cycle, bool)\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); + printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); + printPgmString(PSTR(")\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); + printPgmString(PSTR(" (homing feed, mm/min)\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); + printPgmString(PSTR(" (homing seek, mm/min)\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); + printPgmString(PSTR(" (homing debounce, msec)\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); + printPgmString(PSTR(" (homing pull-off, mm)\r\n")); + #endif + // Print axis settings uint8_t idx, set_idx; uint8_t val = AXIS_SETTINGS_START_VAL; @@ -200,19 +233,23 @@ void report_grbl_settings() { case 2: printFloat_SettingValue(settings.acceleration[idx]/(60*60)); break; case 3: printFloat_SettingValue(-settings.max_travel[idx]); break; } - printPgmString(PSTR(" (")); - switch (idx) { - case X_AXIS: printPgmString(PSTR("x")); break; - case Y_AXIS: printPgmString(PSTR("y")); break; - case Z_AXIS: printPgmString(PSTR("z")); break; - } - switch (set_idx) { - case 0: printPgmString(PSTR(", step/mm")); break; - case 1: printPgmString(PSTR(" max rate, mm/min")); break; - case 2: printPgmString(PSTR(" accel, mm/sec^2")); break; - case 3: printPgmString(PSTR(" max travel, mm")); break; - } - printPgmString(PSTR(")\r\n")); + #ifdef REPORT_GUI_MODE + printPgmString(PSTR("\r\n")); + #else + printPgmString(PSTR(" (")); + switch (idx) { + case X_AXIS: printPgmString(PSTR("x")); break; + case Y_AXIS: printPgmString(PSTR("y")); break; + case Z_AXIS: printPgmString(PSTR("z")); break; + } + switch (set_idx) { + case 0: printPgmString(PSTR(", step/mm")); break; + case 1: printPgmString(PSTR(" max rate, mm/min")); break; + case 2: printPgmString(PSTR(" accel, mm/sec^2")); break; + case 3: printPgmString(PSTR(" max travel, mm")); break; + } + printPgmString(PSTR(")\r\n")); + #endif } val += AXIS_SETTINGS_INCREMENT; } diff --git a/grbl/system.c b/grbl/system.c index 2f3d1005c..a31c5fef4 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -109,54 +109,57 @@ uint8_t system_execute_line(char *line) float parameter, value; switch( line[char_counter] ) { case 0 : report_grbl_help(); break; - case '$' : // Prints Grbl settings - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. - else { report_grbl_settings(); } - break; - case 'G' : // Prints gcode parser state - // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - else { report_gcode_modes(); } - break; - case 'C' : // Set check g-code mode [IDLE/CHECK] - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - // Perform reset when toggling off. Check g-code mode should only work if Grbl - // is idle and ready, regardless of alarm locks. This is mainly to keep things - // simple and consistent. - if ( sys.state == STATE_CHECK_MODE ) { - mc_reset(); - report_feedback_message(MESSAGE_DISABLED); - } else { - if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. - sys.state = STATE_CHECK_MODE; - report_feedback_message(MESSAGE_ENABLED); + case '$': case 'G': case 'C': case 'X': + if ( line[(char_counter+1)] != 0 ) { return(STATUS_INVALID_STATEMENT); } + switch( line[char_counter] ) { + case '$' : // Prints Grbl settings + if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. + else { report_grbl_settings(); } + break; + case 'G' : // Prints gcode parser state + // TODO: Move this to realtime commands for GUIs to request this data during suspend-state. + report_gcode_modes(); + break; + case 'C' : // Set check g-code mode [IDLE/CHECK] + // Perform reset when toggling off. Check g-code mode should only work if Grbl + // is idle and ready, regardless of alarm locks. This is mainly to keep things + // simple and consistent. + if ( sys.state == STATE_CHECK_MODE ) { + mc_reset(); + report_feedback_message(MESSAGE_DISABLED); + } else { + if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. + sys.state = STATE_CHECK_MODE; + report_feedback_message(MESSAGE_ENABLED); + } + break; + case 'X' : // Disable alarm lock [ALARM] + if (sys.state == STATE_ALARM) { + report_feedback_message(MESSAGE_ALARM_UNLOCK); + sys.state = STATE_IDLE; + // Don't run startup script. Prevents stored moves in startup from causing accidents. + if (system_check_safety_door_ajar()) { // Check safety door switch before returning. + bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); + protocol_execute_realtime(); // Enter safety door mode. + } + } // Otherwise, no effect. + break; + // case 'J' : break; // Jogging methods + // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be + // susceptible to other realtime commands except for e-stop. The jogging function is intended to + // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped + // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would + // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the + // motion by repeatedly toggling to slow the motion to the desired location. Location data would + // need to be updated real-time and supplied to the user through status queries. + // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are + // handled by the planner. It would be possible for the jog subprogram to insert blocks into the + // block buffer without having the planner plan them. It would need to manage de/ac-celerations + // on its own carefully. This approach could be effective and possibly size/memory efficient. +// } +// break; } - break; - case 'X' : // Disable alarm lock [ALARM] - if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } - if (sys.state == STATE_ALARM) { - report_feedback_message(MESSAGE_ALARM_UNLOCK); - sys.state = STATE_IDLE; - // Don't run startup script. Prevents stored moves in startup from causing accidents. - if (system_check_safety_door_ajar()) { // Check safety door switch before returning. - bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR); - protocol_execute_realtime(); // Enter safety door mode. - } - } // Otherwise, no effect. - break; -// case 'J' : break; // Jogging methods - // TODO: Here jogging can be placed for execution as a seperate subprogram. It does not need to be - // susceptible to other realtime commands except for e-stop. The jogging function is intended to - // be a basic toggle on/off with controlled acceleration and deceleration to prevent skipped - // steps. The user would supply the desired feedrate, axis to move, and direction. Toggle on would - // start motion and toggle off would initiate a deceleration to stop. One could 'feather' the - // motion by repeatedly toggling to slow the motion to the desired location. Location data would - // need to be updated real-time and supplied to the user through status queries. - // More controlled exact motions can be taken care of by inputting G0 or G1 commands, which are - // handled by the planner. It would be possible for the jog subprogram to insert blocks into the - // block buffer without having the planner plan them. It would need to manage de/ac-celerations - // on its own carefully. This approach could be effective and possibly size/memory efficient. + break; default : // Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing) if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); } From d4ae8f94aff41a8b8a70e7bf0ee1387334fa354d Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 23 Feb 2015 18:50:32 -0700 Subject: [PATCH 35/74] Fixed config.h to Grbl release defaults. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - REPORT_GUI_MODE was accidentally enabled, when it shouldn’t have. --- grbl/config.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index 297742e9a..cde506529 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -174,8 +174,9 @@ // Enables minimal reporting feedback mode for GUIs, where human-readable strings are not as important. // This saves nearly 2KB of flash space and may allow enough space to install other/future features. +// GUIs will need to install a look-up table for the error-codes that Grbl sends back in their place. // NOTE: This feature is new and experimental. Make sure the GUI you are using supports this mode. -#define REPORT_GUI_MODE // Default disabled. Uncomment to enable. +// #define REPORT_GUI_MODE // Default disabled. Uncomment to enable. // The temporal resolution of the acceleration management subsystem. A higher number gives smoother // acceleration, particularly noticeable on machines that run at very high feedrates, but may negatively @@ -226,7 +227,7 @@ // enable pin will output 5V for maximum RPM with 256 intermediate levels and 0V when disabled. // NOTE: IMPORTANT for Arduino Unos! When enabled, the Z-limit pin D11 and spindle enable pin D12 switch! // The hardware PWM output on pin D11 is required for variable spindle output voltages. -#define VARIABLE_SPINDLE // Default disabled. Uncomment to enable. +#define VARIABLE_SPINDLE // Default enabled. Comment to disable. // Used by the variable spindle output only. These parameters set the maximum and minimum spindle speed // "S" g-code values to correspond to the maximum and minimum pin voltages. There are 256 discrete and From 85b0c7a8b48e68fe0c4a5e8b2d8cb24a0789a231 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 25 Feb 2015 08:29:56 -0700 Subject: [PATCH 36/74] G91.1 support. Fixed a config.h option. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - G91.1 support added. This g-code sets the arc IJK distance mode to incremental, which is the default already. This simply helps reduce parsing errors with certain CAM programs that output this command. - Max step rate checks weren’t being compiled in if the option was enabled. Fixed now. - Alarm codes were not displaying correctly when GUI reporting mode was enabled. Due to unsigned int problem. Changed codes to positive values since they aren’t shared with other codes. --- README.md | 1 + grbl/gcode.c | 13 ++++++++++--- grbl/gcode.h | 20 ++++++++++++-------- grbl/report.c | 9 +++++---- grbl/report.h | 14 +++++++------- grbl/settings.c | 8 ++++++-- 6 files changed, 41 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 3e69e2341..962d932c8 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ List of Supported G-Codes in Grbl v0.9 - Feed Rate Modes: G93, G94 - Unit Modes: G20, G21 - Distance Modes: G90, G91 + - Arc IJK Distance Modes: G91.1 - Plane Select Modes: G17, G18, G19 - Tool Length Offset Modes: G43.1, G49 - Cutter Compensation Modes: G40 diff --git a/grbl/gcode.c b/grbl/gcode.c index b915e486d..37f9ff91e 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -213,9 +213,16 @@ uint8_t gc_execute_line(char *line) } break; case 90: case 91: - word_bit = MODAL_GROUP_G3; - if (int_value == 90) { gc_block.modal.distance = DISTANCE_MODE_ABSOLUTE; } // G90 - else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91 + if (mantissa == 0) { + word_bit = MODAL_GROUP_G3; + if (int_value == 90) { gc_block.modal.distance = DISTANCE_MODE_ABSOLUTE; } // G90 + else { gc_block.modal.distance = DISTANCE_MODE_INCREMENTAL; } // G91 + } else { + word_bit = MODAL_GROUP_G4; + if (mantissa != 10) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G90.1 not supported] + mantissa = 0; // Set to zero to indicate valid non-integer G command. + // Otherwise, arc IJK incremental mode is default. G91.1 does nothing. + } break; case 93: case 94: word_bit = MODAL_GROUP_G5; diff --git a/grbl/gcode.h b/grbl/gcode.h index 0b478d073..46df351ff 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -33,15 +33,16 @@ #define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G80] Motion #define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection #define MODAL_GROUP_G3 3 // [G90,G91] Distance mode -#define MODAL_GROUP_G5 4 // [G93,G94] Feed rate mode -#define MODAL_GROUP_G6 5 // [G20,G21] Units -#define MODAL_GROUP_G7 6 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. -#define MODAL_GROUP_G8 7 // [G43,G43.1,G49] Tool length offset -#define MODAL_GROUP_G12 8 // [G54,G55,G56,G57,G58,G59] Coordinate system selection +#define MODAL_GROUP_G4 4 // [G90.1,G91.1] Arc IJK distance mode +#define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode +#define MODAL_GROUP_G6 6 // [G20,G21] Units +#define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. +#define MODAL_GROUP_G8 8 // [G43,G43.1,G49] Tool length offset +#define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection -#define MODAL_GROUP_M4 9 // [M0,M1,M2,M30] Stopping -#define MODAL_GROUP_M7 10 // [M3,M4,M5] Spindle turning -#define MODAL_GROUP_M8 11 // [M7,M8,M9] Coolant control +#define MODAL_GROUP_M4 10 // [M0,M1,M2,M30] Stopping +#define MODAL_GROUP_M7 11 // [M3,M4,M5] Spindle turning +#define MODAL_GROUP_M8 12 // [M7,M8,M9] Coolant control #define OTHER_INPUT_F 12 #define OTHER_INPUT_S 13 @@ -82,6 +83,9 @@ #define DISTANCE_MODE_ABSOLUTE 0 // G90 (Default: Must be zero) #define DISTANCE_MODE_INCREMENTAL 1 // G91 +// Modal Group G4: Arc IJK distance mode +#define DISTANCE_ARC_MODE_INCREMENTAL 0 // G91.1 (Default: Must be zero) + // Modal Group M4: Program flow #define PROGRAM_FLOW_RUNNING 0 // (Default: Must be zero) #define PROGRAM_FLOW_PAUSED 1 // M0, M1 diff --git a/grbl/report.c b/grbl/report.c index eae699553..9460f6ac2 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -68,10 +68,11 @@ void report_status_message(uint8_t status_code) case STATUS_SOFT_LIMIT_ERROR: printPgmString(PSTR("Homing not enabled")); break; case STATUS_OVERFLOW: - printPgmString(PSTR("Line overflow")); break; - // case STATUS_MAX_STEP_RATE_EXCEEDED: - // printPgmString(PSTR("Step rate > 30kHz")); break; - + printPgmString(PSTR("Line overflow")); break; + #ifdef MAX_STEP_RATE_HZ + case STATUS_MAX_STEP_RATE_EXCEEDED: + printPgmString(PSTR("Step rate > 30kHz")); break; + #endif // Common g-code parser errors. case STATUS_GCODE_MODAL_GROUP_VIOLATION: printPgmString(PSTR("Modal group violation")); break; diff --git a/grbl/report.h b/grbl/report.h index cfd0d8b2c..e21df424e 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -33,7 +33,7 @@ #define STATUS_ALARM_LOCK 9 #define STATUS_SOFT_LIMIT_ERROR 10 #define STATUS_OVERFLOW 11 -// #define STATUS_MAX_STEP_RATE_EXCEEDED 12 +#define STATUS_MAX_STEP_RATE_EXCEEDED 12 #define STATUS_GCODE_UNSUPPORTED_COMMAND 20 #define STATUS_GCODE_MODAL_GROUP_VIOLATION 21 @@ -54,12 +54,12 @@ #define STATUS_GCODE_UNUSED_WORDS 36 #define STATUS_GCODE_G43_DYNAMIC_AXIS_ERROR 37 -// Define Grbl alarm codes. Less than zero to distinguish alarm error from status error. -#define ALARM_HARD_LIMIT_ERROR -1 -#define ALARM_SOFT_LIMIT_ERROR -2 -#define ALARM_ABORT_CYCLE -3 -#define ALARM_PROBE_FAIL -4 -#define ALARM_HOMING_FAIL -5 +// Define Grbl alarm codes. +#define ALARM_HARD_LIMIT_ERROR 1 +#define ALARM_SOFT_LIMIT_ERROR 2 +#define ALARM_ABORT_CYCLE 3 +#define ALARM_PROBE_FAIL 4 +#define ALARM_HOMING_FAIL 5 // Define Grbl feedback message codes. #define MESSAGE_CRITICAL_EVENT 1 diff --git a/grbl/settings.c b/grbl/settings.c index 956cb021e..87535d566 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -189,11 +189,15 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { // Valid axis setting found. switch (set_idx) { case 0: - // if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #ifdef MAX_STEP_RATE_HZ + if (value*settings.max_rate[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif settings.steps_per_mm[parameter] = value; break; case 1: - // if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #ifdef MAX_STEP_RATE_HZ + if (value*settings.steps_per_mm[parameter] > (MAX_STEP_RATE_HZ*60.0)) { return(STATUS_MAX_STEP_RATE_EXCEEDED); } + #endif settings.max_rate[parameter] = value; break; case 2: settings.acceleration[parameter] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. From 76730176da0ddee2f31aea3e28e2df54342629c9 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 4 Mar 2015 06:50:26 -0700 Subject: [PATCH 37/74] Arduino IDE compatibility and minor homing fixes - Added an include in the right spot, if a user tries to compile and upload Grbl through the Arduino IDE with the old way. - Fixed a minor bug with homing max travel calculations. It was causing simultaneous axes homing to move slow than it did before. --- README.md | 2 +- grbl/config.h | 1 + grbl/grbl.h | 2 +- grbl/limits.c | 25 +++++++++++++++---------- grbl/protocol.c | 4 ++++ 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 962d932c8..afad1bbd2 100644 --- a/README.md +++ b/README.md @@ -82,5 +82,5 @@ List of Supported G-Codes in Grbl v0.9 ------------- Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you! -[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EBQWAWQAAT878) +[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW) diff --git a/grbl/config.h b/grbl/config.h index cde506529..2d6cb7ce2 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -27,6 +27,7 @@ #ifndef config_h #define config_h +#include "grbl.h" // For Arduino IDE compatibility. // Default settings. Used when resetting EEPROM. Change to desired name in defaults.h diff --git a/grbl/grbl.h b/grbl/grbl.h index ff9226989..2122a500a 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150223" +#define GRBL_VERSION_BUILD "20150302" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 75b9f8233..155aba523 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -134,7 +134,8 @@ void limits_go_home(uint8_t cycle_mask) float target[N_AXIS]; uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; - float max_travel; + + float max_travel = 0.0; for (idx=0; idx Date: Sat, 7 Mar 2015 13:32:59 -0700 Subject: [PATCH 38/74] Another homing cycle fix. - The homing cycle should be working again. Reverted it back to how it was about a month ago before I started to fiddle with it. Turns out that my past self knew what he was doing. --- grbl/grbl.h | 2 +- grbl/limits.c | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/grbl/grbl.h b/grbl/grbl.h index 2122a500a..1ff036ece 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150302" +#define GRBL_VERSION_BUILD "20150307" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 155aba523..83d93d9bb 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -163,15 +163,19 @@ void limits_go_home(uint8_t cycle_mask) // Initialize and declare variables needed for homing routine. uint8_t axislock = 0; uint8_t n_active_axis = 0; - system_convert_array_steps_to_mpos(target,sys.position); + system_convert_array_steps_to_mpos(target,sys.position); for (idx=0; idx Date: Sat, 14 Mar 2015 09:27:48 -0600 Subject: [PATCH 39/74] Cleaned-up limit pin reporting and comments. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Cleaned up the limit pin state reporting option to display only the state per axis, rather than the whole port. It’s organized by an XYZ order, 0(low)-1(high), and generally looks like `Lim:001`. - Separated the control pin state reporting from limit state reporting as a new compile option. This stayed the same in terms of showing the entire port in binary, since it’s not anticipated that this will be used much, if at all. - Updated some of the gcode source comments regarding supported g-codes. --- grbl/config.h | 17 ++++++++++++----- grbl/gcode.c | 6 +++--- grbl/gcode.h | 9 +++++---- grbl/grbl.h | 2 +- grbl/report.c | 11 +++++++++-- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index 2d6cb7ce2..6efb761ba 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -156,11 +156,18 @@ // NOTE: Will eventually be added to Grbl settings in v1.0. // #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. -// Enable input pin states feedback in status reports. The data is presented as a binary value with -// the bits in the appropriate input pin ports being 0(low) or 1(high). Useful for setting up a new -// CNC machine, but do not recommend keeping this option by default, as it will consume CPU resources -// with little to no benefit during normal operation. -// #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. +// Enable limit pin states feedback in status reports. The data is presented as 0 (low) or 1(high), +// where the order is XYZ. For example, if the Y- and Z-limit pins are active, Grbl will include the +// following string in the status report "Lim:011". This is generally useful for setting up a new +// CNC machine, but we do not recommend keeping this option enabled, as it will consume CPU resources +// with little to no benefit during normal operation and it may not be supported by most GUIs. +// #define REPORT_LIMIT_PIN_STATE // Default disabled. Uncomment to enable. + +// Enable control pin states feedback in status reports. The data is presented as simple binary of +// the control pin port (0 (low) or 1(high)), masked to show only the input pins. Non-control pins on the +// port will always show a 0 value. See cpu_map.h for the pin bitmap. As with the limit pin reporting, +// we do not recommend keeping this option enabled. Try to only use this for setting up a new CNC. +// #define REPORT_CONTROL_PIN_STATE // Default disabled. Uncomment to enable. // When Grbl powers-cycles or is hard reset with the Arduino reset button, Grbl boots up with no ALARM // by default. This is to make it as simple as possible for new users to start using Grbl. When homing diff --git a/grbl/gcode.c b/grbl/gcode.c index 37f9ff91e..3893c6179 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1056,9 +1056,9 @@ uint8_t gc_execute_line(char *line) group 1 = {G81 - G89} (Motion modes: Canned cycles) group 4 = {M1} (Optional stop, ignored) group 6 = {M6} (Tool change) - group 7 = {G40, G41, G42} cutter radius compensation - group 8 = {G43} tool length offset (But G43.1/G94 IS SUPPORTED) - group 8 = {*M7} enable mist coolant + group 7 = {G41, G42} cutter radius compensation (G40 is supported) + group 8 = {G43} tool length offset (G43.1/G49 are supported) + group 8 = {*M7} enable mist coolant (* Compile-option) group 9 = {M48, M49} enable/disable feed and speed override switches group 10 = {G98, G99} return mode canned cycles group 13 = {G61, G61.1, G64} path control mode diff --git a/grbl/gcode.h b/grbl/gcode.h index 46df351ff..53311163e 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -30,14 +30,14 @@ // and are similar/identical to other g-code interpreters by manufacturers (Haas,Fanuc,Mazak,etc). // NOTE: Modal group define values must be sequential and starting from zero. #define MODAL_GROUP_G0 0 // [G4,G10,G28,G28.1,G30,G30.1,G53,G92,G92.1] Non-modal -#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G80] Motion +#define MODAL_GROUP_G1 1 // [G0,G1,G2,G3,G38.2,G38.3,G38.4,G38.5,G80] Motion #define MODAL_GROUP_G2 2 // [G17,G18,G19] Plane selection #define MODAL_GROUP_G3 3 // [G90,G91] Distance mode -#define MODAL_GROUP_G4 4 // [G90.1,G91.1] Arc IJK distance mode +#define MODAL_GROUP_G4 4 // [G91.1] Arc IJK distance mode #define MODAL_GROUP_G5 5 // [G93,G94] Feed rate mode #define MODAL_GROUP_G6 6 // [G20,G21] Units #define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. -#define MODAL_GROUP_G8 8 // [G43,G43.1,G49] Tool length offset +#define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset #define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection #define MODAL_GROUP_M4 10 // [M0,M1,M2,M30] Stopping @@ -142,8 +142,9 @@ typedef struct { uint8_t feed_rate; // {G93,G94} uint8_t units; // {G20,G21} uint8_t distance; // {G90,G91} + // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only one supported. uint8_t plane_select; // {G17,G18,G19} - // uint8_t cutter_comp; // {G40} NOTE: Don't need to track since it's always disabled. + // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only one supported. uint8_t tool_length; // {G43.1,G49} uint8_t coord_select; // {G54,G55,G56,G57,G58,G59} uint8_t program_flow; // {M0,M1,M2,M30} diff --git a/grbl/grbl.h b/grbl/grbl.h index 1ff036ece..7b5bb1ba6 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150307" +#define GRBL_VERSION_BUILD "20150314" // Define standard libraries used by Grbl. #include diff --git a/grbl/report.c b/grbl/report.c index 9460f6ac2..e03bdde04 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -484,9 +484,16 @@ void report_realtime_status() printFloat_RateValue(st_get_realtime_rate()); #endif - #ifdef REPORT_INPUT_PIN_STATES + #ifdef REPORT_LIMIT_PIN_STATE printPgmString(PSTR(",Lim:")); - print_uint8_base2(LIMIT_PIN & LIMIT_MASK); + uint8_t idx; + for (idx=0; idx Date: Sun, 15 Mar 2015 21:57:21 -0600 Subject: [PATCH 40/74] Updated README. - Also altered the G38.X reporting to save some bytes. --- README.md | 63 ++++++++++++++++++++++++++++++--------------------- grbl/gcode.h | 2 +- grbl/grbl.h | 2 +- grbl/report.c | 7 +++--- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index afad1bbd2..de9dfdedf 100644 --- a/README.md +++ b/README.md @@ -22,13 +22,15 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) _(2014-09-05)_ -* [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) _(2014-09-05)_ - - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9g:** +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2014-03-15)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ + - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - - Settings WILL be overwritten. Please make sure you have a backup. Also, settings have been renumbered and some have changed how they work. See our [Configuring v0.9 Wiki page](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9) for details. + - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. _**Archives:**_ +* [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) +* [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) * [Grbl v0.8c Atmega328p 16mhz 9600baud](http://bit.ly/SSdCJE) * [Grbl v0.7d Atmega328p 16mhz 9600baud](http://bit.ly/ZhL15G) * [Grbl v0.6b Atmega328p 16mhz 9600baud](http://bit.ly/VD04A5) @@ -38,34 +40,43 @@ _**Archives:**_ *** -##Update Summary for v0.9 from v0.8 - - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600). And your settings will be over-written! Make sure to have a backup.** - - **_NEW_ Super Smooth Stepper Algorithm:** Complete overhaul of the handling of the stepper driver to simplify and reduce task time per ISR tick. Much smoother operation with the new Adaptive Multi-Axis Step Smoothing (AMASS) algorithm which does what its name implies (see stepper.c source for details). Users should immediately see significant improvements in how their machines move and overall performance! - - **Stability and Robustness Updates:** Grbl's overall stability has been focused on for this version. The planner and step-execution interface has been completely re-written for robustness and incorruptibility by the introduction of an intermediate step segment buffer that "checks-out" steps from the planner buffer in real-time. This means we can now fearlessly drive Grbl to it's highest limits. Combined with the new stepper algorithm and planner optimizations, this translated to **5x to 10x** overall performance increases in our testing! Also, stability and robustness tests have been reported to easily take 1.4 million (yes, **million**) line g-code programs like a champ! - - **(x4)+ Faster Planner:** Planning computations improved four-fold or more by optimizing end-to-end operations, which included streamlining the computations and introducing a planner pointer to locate un-improvable portions of the buffer and not waste cycles recomputing them. - - **Compile-able via Arduino IDE!:** Grbl's source code may be now download and altered, and then be compiled and flashed directly through the Arduino IDE, which should work on all platforms. See the Wiki for details on how to do it. - - **G-Code Parser Overhaul:** Completely re-written from the ground-up for 100%-compliance* to the g-code standard. (* Parts of the NIST standard are a bit out-dated and arbitrary, so we altered some minor things to make more sense. Differences are outlined in the source code.) We also took steps to allow us to break up the g-code parser into distinct separate tasks, which is key for some future development ideas and improvements. - - **Independent Acceleration and Velocity Settings:** Each axes may be defined with unique acceleration and velocity parameters and Grbl will automagically calculate the maximum acceleration and velocity through a path depending on the direction traveled. This is very useful for machines that have very different axes properties, like the ShapeOko's z-axis. - - **Soft Limits:** Checks if any motion command exceeds workspace limits before executing it, and alarms out, if detected. Another safety feature, but, unlike hard limits, position does not get lost, as it forces a feed hold before erroring out. NOTE: This still requires limit switches for homing so Grbl knows where the machine origin is, and the new max axis travel settings configured correctly for the machine. - - **Probing:** The G38.2 straight probe and G43.1/49 tool offset g-code commands are now supported. A simple probe switch must be connected to the Uno analog pin 5 (normally-open to ground). Grbl will report the probe position back to the user when the probing cycle detects a pin state change. - - **Tool Length Offsets:** Probing doesn't make sense without tool length offsets(TLO), so we added it! The G43.1 dynamic TLO (described by linuxcnc.org) and G49 TLO cancel commands are now supported. G43.1 dynamic TLO works like the normal G43 TLO(NOT SUPPORTED) but requires an additional axis word with the offset value attached. We did this so Grbl does not have to track and maintain a tool offset database in its memory. Perhaps in the future, we will support a tool database, but not for this version. - - **Improved Arc Performance:** The larger the arc radius, the faster Grbl will trace it! We are now defining arcs in terms of arc chordal tolerance, rather than a fixed segment length. This automatically scales the arc segment length such that maximum radial error of the segment from the true arc is never more than the chordal tolerance value of a super-accurate default of 0.002 mm. - - **CPU Pin Mapping:** In an effort for Grbl to be compatible with other AVR architectures, such as the 1280 or 2560, a new cpu_map.h pin configuration file has been created to allow Grbl to be compiled for them. This is currently user supported, so your mileage may vary. If you run across a bug, please let us know or better send us a fix! Thanks in advance! - - **New Grbl SIMULATOR! (by @jgeisler and @ashelly):** A completely independent wrapper of the Grbl main source code that may be compiled as an executable on a computer. No Arduino required. Simply simulates the responses of Grbl as if it was on an Arduino. May be used for many things: checking out how Grbl works, pre-process moves for GUI graphics, debugging of new features, etc. Much left to do, but potentially very powerful, as the dummy AVR variables can be written to output anything you need. - - **Configurable Real-time Status Reporting:** Users can now customize the type of real-time data Grbl reports back when they issue a '?' status report. This includes data such as: machine position, work position, planner buffer usage, serial RX buffer usage. - - **Updated Homing Routine:** Sets workspace volume in all negative space regardless of limit switch position. Common on pro CNCs. But, the behavior may be changed by a compile-time option though. Now tied directly into the main planner and stepper modules to reduce flash space and allow maximum speeds during seeking. +##Update Summary for v0.9i from v0.9h + - **IMPORTANT:** + - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle PWM!** + - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** + - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! + - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - - **Optional Limit Pin Sharing:** Limit switches can be combined to share the same pins to free up precious I/O pins for other purposes. When combined, users must adjust the homing cycle mask in config.h to not home the axes on a shared pin at the same time. Don't worry; hard limits and the homing cycle still work just like they did before. - - **Optional Variable Spindle Speed Output:** Available only as a compile-time option through the config.h file. Enables PWM output for 'S' g-code commands. Enabling this feature will swap the Z-limit D11 pin and spindle enable D12 pin to access the hardware PWM on pin D12. The Z-limit pin, now on D12, should work just as it did before. - - **Additional Compile-Time Feature Options:** Line number tracking, real-time feed rate reporting. - - **SLATED FOR v1.0 DEVELOPMENT** Jogging controls and feedrate/spindle/coolant overrides. (In v0.9, the framework for feedrate overrides are in-place, only the minor details to complete it have yet to be installed.) + - **Additional Compile-Time Feature Options:** Limit/control pin state reporting, force power-up alarm state, GUI reporting mode, and more. + +##Update Summary for v0.9h from v0.8 + - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600)** + - **Super Smooth Stepper Algorithm** + - **Stability and Robustness Updates** + - **(x4)+ Faster Planner** + - **Compile-able via Arduino IDE!** + - **G-Code Parser Overhaul** + - **Independent Acceleration and Velocity Settings** + - **Soft Limits** + - **Probing** + - **Dynamic Tool Length Offsets** + - **Improved Arc Performance** + - **CPU Pin Mapping** + - **New Grbl SIMULATOR! (by @jgeisler and @ashelly)** + - **Configurable Real-time Status Reporting** + - **Updated Homing Routine** + - **CoreXY Support** + - **Full Limit and Control Pin Configurability** + - **Optional Limit Pin Sharing** + - **Optional Variable Spindle Speed Output** + - **Additional Compile-Time Feature Options** - ``` -List of Supported G-Codes in Grbl v0.9 +List of Supported G-Codes in Grbl v0.9i Master: - Non-Modal Commands: G4, G10 L2, G10 L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 - - Motion Modes: G0, G1, G2, G3, G38.1, G80 + - Motion Modes: G0, G1, G2, G3, G38.1, G38.2, G38.3, G38.4, G80 - Feed Rate Modes: G93, G94 - Unit Modes: G20, G21 - Distance Modes: G90, G91 diff --git a/grbl/gcode.h b/grbl/gcode.h index 53311163e..10d4792a4 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -68,7 +68,7 @@ #define MOTION_MODE_LINEAR 1 // G1 #define MOTION_MODE_CW_ARC 2 // G2 #define MOTION_MODE_CCW_ARC 3 // G3 -#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 +#define MOTION_MODE_PROBE_TOWARD 4 // G38.2 NOTE: G38.2, G38.3, G38.4, G38.5 must be sequential. See report_gcode_modes(). #define MOTION_MODE_PROBE_TOWARD_NO_ERROR 5 // G38.3 #define MOTION_MODE_PROBE_AWAY 6 // G38.4 #define MOTION_MODE_PROBE_AWAY_NO_ERROR 7 // G38.5 diff --git a/grbl/grbl.h b/grbl/grbl.h index 7b5bb1ba6..17886bab6 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150314" +#define GRBL_VERSION_BUILD "20150315" // Define standard libraries used by Grbl. #include diff --git a/grbl/report.c b/grbl/report.c index e03bdde04..f57360267 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -324,11 +324,10 @@ void report_gcode_modes() case MOTION_MODE_LINEAR : printPgmString(PSTR("G1")); break; case MOTION_MODE_CW_ARC : printPgmString(PSTR("G2")); break; case MOTION_MODE_CCW_ARC : printPgmString(PSTR("G3")); break; - case MOTION_MODE_PROBE_TOWARD : printPgmString(PSTR("G38.2")); break; - case MOTION_MODE_PROBE_TOWARD_NO_ERROR : printPgmString(PSTR("G38.3")); break; - case MOTION_MODE_PROBE_AWAY : printPgmString(PSTR("G38.4")); break; - case MOTION_MODE_PROBE_AWAY_NO_ERROR : printPgmString(PSTR("G38.5")); break; case MOTION_MODE_NONE : printPgmString(PSTR("G80")); break; + default: + printPgmString(PSTR("G38.")); + print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD+2)); } printPgmString(PSTR(" G")); From b3140351c896f8b3eb70b40d495932ee1eebe46f Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sun, 15 Mar 2015 22:03:33 -0600 Subject: [PATCH 41/74] Create README.md --- README.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..d88ab074b --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +![GitHub Logo](/doc/logo/Grbl Logo 250px.png) + + +*** + +Grbl is a no-compromise, high performance, low cost alternative to parallel-port-based motion control for CNC milling. It will run on a vanilla Arduino (Duemillanove/Uno) as long as it sports an Atmega 328. + +The controller is written in highly optimized C utilizing every clever feature of the AVR-chips to achieve precise timing and asynchronous operation. It is able to maintain up to 30kHz of stable, jitter free control pulses. + +It accepts standards-compliant g-code and has been tested with the output of several CAM tools with no problems. Arcs, circles and helical motion are fully supported, as well as, all other primary g-code commands. Macro functions, variables, and most canned cycles are not supported, but we think GUIs can do a much better job at translating them into straight g-code anyhow. + +Grbl includes full acceleration management with look ahead. That means the controller will look up to 18 motions into the future and plan its velocities ahead to deliver smooth acceleration and jerk-free cornering. + +* [Licensing](https://github.com/grbl/grbl/wiki/Licensing): Grbl is free software, released under the GPLv3 license. + +* For more information and help, check out our **[Wiki pages!](https://github.com/grbl/grbl/wiki)** If you find that the information is out-dated, please to help us keep it updated by editing it or notifying our community! Thanks! + +* Lead Developer [_2011 - Current_]: Sungeun(Sonny) K. Jeon, Ph.D. (USA) aka @chamnit + +* Lead Developer [_2009 - 2011_]: Simen Svale Skogsrud (Norway). aka The Originator/Creator/Pioneer/Father of Grbl. + +*** + +_**Master Branch:**_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2014-03-15)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ + - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** + - Baudrate is now **115200** (Up from 9600). + - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. + +_**Archives:**_ +* [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) +* [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) +* [Grbl v0.8c Atmega328p 16mhz 9600baud](http://bit.ly/SSdCJE) +* [Grbl v0.7d Atmega328p 16mhz 9600baud](http://bit.ly/ZhL15G) +* [Grbl v0.6b Atmega328p 16mhz 9600baud](http://bit.ly/VD04A5) +* [Grbl v0.51 Atmega328p 16mhz 9600baud](http://bit.ly/W75BS1) +* [Grbl v0.6b Atmega168 16mhz 9600baud](http://bit.ly/SScWnE) +* [Grbl v0.51 Atmega168 16mhz 9600baud](http://bit.ly/VXyrYu) + +------------- + +_Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help keep this project sustainable and to fund supporting equipment. Thank you!_ + +| [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EBQWAWQAAT878) | [![Flattr Grbl](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=chamnit&url=github.com/grbl/grbl&title=Grbl&language=&tags=github&category=software) | [![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.1.3/dist/gratipay.png)](https://gratipay.com/chamnit/) | +|:--:|:--:|:--:| + + +*** + +##Update Summary for v0.9i from v0.9h + - **IMPORTANT:** + - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle PWM!** + - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** + - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. + - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! + - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. + - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. + - **Additional Compile-Time Feature Options:** Limit/control pin state reporting, force power-up alarm state, GUI reporting mode, and more. + +##Update Summary for v0.9h from v0.8 + - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600)** + - **Super Smooth Stepper Algorithm** + - **Stability and Robustness Updates** + - **(x4)+ Faster Planner** + - **Compile-able via Arduino IDE!** + - **G-Code Parser Overhaul** + - **Independent Acceleration and Velocity Settings** + - **Soft Limits** + - **Probing** + - **Dynamic Tool Length Offsets** + - **Improved Arc Performance** + - **CPU Pin Mapping** + - **New Grbl SIMULATOR! (by @jgeisler and @ashelly)** + - **Configurable Real-time Status Reporting** + - **Updated Homing Routine** + - **CoreXY Support** + - **Full Limit and Control Pin Configurability** + - **Optional Limit Pin Sharing** + - **Optional Variable Spindle Speed Output** + - **Additional Compile-Time Feature Options** + +- +``` +List of Supported G-Codes in Grbl v0.9i Master: + - Non-Modal Commands: G4, G10 L2, G10 L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 + - Motion Modes: G0, G1, G2, G3, G38.1, G38.2, G38.3, G38.4, G80 + - Feed Rate Modes: G93, G94 + - Unit Modes: G20, G21 + - Distance Modes: G90, G91 + - Arc IJK Distance Modes: G91.1 + - Plane Select Modes: G17, G18, G19 + - Tool Length Offset Modes: G43.1, G49 + - Cutter Compensation Modes: G40 + - Coordinate System Modes: G54, G55, G56, G57, G58, G59 + - Program Flow: M0, M1, M2, M30* + - Coolant Control: M7*, M8, M9 + - Spindle Control: M3, M4, M5 +``` + +------------- +Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help fund supporting hardware and testing equipment. Thank you! + +[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CUGXJHXA36BYW) From 87cf6c888b83c65db5d8b60ca91644837d624a8a Mon Sep 17 00:00:00 2001 From: Sungeun Jeon Date: Sun, 15 Mar 2015 22:04:27 -0600 Subject: [PATCH 42/74] Updated README --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index d88ab074b..9f2fcd20b 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,6 @@ _**Archives:**_ * [Grbl v0.6b Atmega168 16mhz 9600baud](http://bit.ly/SScWnE) * [Grbl v0.51 Atmega168 16mhz 9600baud](http://bit.ly/VXyrYu) -------------- - -_Grbl is an open-source project and fueled by the free-time of our intrepid administrators and altruistic users. If you'd like to donate, all proceeds will be used to help keep this project sustainable and to fund supporting equipment. Thank you!_ - -| [![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EBQWAWQAAT878) | [![Flattr Grbl](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=chamnit&url=github.com/grbl/grbl&title=Grbl&language=&tags=github&category=software) | [![Support via Gratipay](https://cdn.rawgit.com/gratipay/gratipay-badge/2.1.3/dist/gratipay.png)](https://gratipay.com/chamnit/) | -|:--:|:--:|:--:| - *** From b1afeb4547f9cd9ff47de5029f4902539de94111 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Mon, 16 Mar 2015 08:24:09 -0600 Subject: [PATCH 43/74] Update README.md --- README.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9f2fcd20b..c79a0fcfb 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2014-03-15)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-03-15)_ * [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). @@ -43,7 +43,7 @@ _**Archives:**_ ##Update Summary for v0.9i from v0.9h - **IMPORTANT:** - - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle PWM!** + - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!** - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! @@ -67,8 +67,6 @@ _**Archives:**_ - **New Grbl SIMULATOR! (by @jgeisler and @ashelly)** - **Configurable Real-time Status Reporting** - **Updated Homing Routine** - - **CoreXY Support** - - **Full Limit and Control Pin Configurability** - **Optional Limit Pin Sharing** - **Optional Variable Spindle Speed Output** - **Additional Compile-Time Feature Options** @@ -76,8 +74,8 @@ _**Archives:**_ - ``` List of Supported G-Codes in Grbl v0.9i Master: - - Non-Modal Commands: G4, G10 L2, G10 L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 - - Motion Modes: G0, G1, G2, G3, G38.1, G38.2, G38.3, G38.4, G80 + - Non-Modal Commands: G4, G10L2, G10L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 + - Motion Modes: G0, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80 - Feed Rate Modes: G93, G94 - Unit Modes: G20, G21 - Distance Modes: G90, G91 @@ -89,6 +87,7 @@ List of Supported G-Codes in Grbl v0.9i Master: - Program Flow: M0, M1, M2, M30* - Coolant Control: M7*, M8, M9 - Spindle Control: M3, M4, M5 + - Valid Non-Command Words: F, I, J, K, L, N, P, R, S, T, X, Y, Z ``` ------------- From 353df7b0a0f79dd5e71c791deeaab8b6309fce57 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 26 Mar 2015 20:47:24 -0600 Subject: [PATCH 44/74] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index c79a0fcfb..e4dadee6a 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,11 @@ Grbl includes full acceleration management with look ahead. That means the contr *** +### Official Supporters of the Grbl CNC Project +[![Carbide3D](https://dl.dropboxusercontent.com/u/2221997/logo_240px.png)](http://carbide3d.com) [![Inventables](https://dzevsq2emy08i.cloudfront.net/paperclip/press_image_uploads/62/low_res/inventables-logo.png)](http://inventables.com) + +*** + _**Master Branch:**_ * [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-03-15)_ * [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ From 4841dff712c16ccb6b3a3f68cfafb15c4fcc3a3c Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 27 Mar 2015 08:57:05 -0600 Subject: [PATCH 45/74] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e4dadee6a..c2f7e3119 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Grbl includes full acceleration management with look ahead. That means the contr *** ### Official Supporters of the Grbl CNC Project -[![Carbide3D](https://dl.dropboxusercontent.com/u/2221997/logo_240px.png)](http://carbide3d.com) [![Inventables](https://dzevsq2emy08i.cloudfront.net/paperclip/press_image_uploads/62/low_res/inventables-logo.png)](http://inventables.com) +[![Carbide3D](http://carbide3d.com/files/logo_240px.png)](http://carbide3d.com) [![Inventables](https://dzevsq2emy08i.cloudfront.net/paperclip/press_image_uploads/62/low_res/inventables-logo.png)](http://inventables.com) *** From ed29d8a1229afdaa53195805d73b8fb898793ff2 Mon Sep 17 00:00:00 2001 From: Sungeun Jeon Date: Fri, 27 Mar 2015 18:13:18 -0600 Subject: [PATCH 46/74] New compile options and inverse time bug fix. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Apparently inverse time motion were not working for quite some time. Goes to show how many people actually use it. The calculation was bad and is now fixed in this update. It should now work correctly. - `;` comment type is now supported. This is standard on LinuxCNC and common on 3d printers. It was previously not supported due to not existing in the NIST standard, which is out-dated. - New compile-option to ECHO the line received. This should help users experiencing very weird problems and help diagnose if there is something amiss in the communication to Grbl. - New compile-option to use the spindle direction pin D13 as a spindle enable pin with PWM spindle speed on D11. This feature has been requested often from the laser cutter community. Since spindle direction isn’t really of much use, it seemed like good good trade. Note that M4 spindle enable counter-clock-wise support is removed for obvious reasons, while M3 and M5 still work. --- grbl/config.h | 33 ++++++++++++++++++++++++++++----- grbl/cpu_map.h | 30 +++++++++++++++++++----------- grbl/gcode.c | 9 +++++++-- grbl/grbl.h | 2 +- grbl/planner.c | 2 +- grbl/protocol.c | 30 +++++++++++++++++++++--------- grbl/report.c | 9 +++++++++ grbl/report.h | 3 +++ grbl/spindle_control.c | 31 ++++++++++++++++++++----------- 9 files changed, 109 insertions(+), 40 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index 6efb761ba..f4306946a 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -251,6 +251,22 @@ // spindle RPM output lower than this value will be set to this value. // #define MINIMUM_SPINDLE_PWM 5 // Default disabled. Uncomment to enable. Integer (0-255) +// By default on a 328p(Uno), Grbl combines the variable spindle PWM and the enable into one pin to help +// preserve I/O pins. For certain setups, these may need to be separate pins. This configure option uses +// the spindle direction pin(D13) as a separate spindle enable pin along with spindle speed PWM on pin D11. +// NOTE: This configure option only works with VARIABLE_SPINDLE enabled and a 328p processor (Uno). +// NOTE: With no direction pin, the spindle clockwise M4 g-code command will be removed. M3 and M5 still work. +// #define USE_SPINDLE_DIR_AS_ENABLE_PIN // Default disabled. Uncomment to enable. + +// With this enabled, Grbl sends back an echo of the line it has received, which has been pre-parsed (spaces +// removed, capitalized letters, no comments) and is to be immediately executed by Grbl. Echoes will not be +// sent upon a line buffer overflow, but should for all normal lines sent to Grbl. For example, if a user +// sendss the line 'g1 x1.032 y2.45 (test comment)', Grbl will echo back in the form '[echo: G1X1.032Y2.45]'. +// NOTE: Only use this for debugging purposes!! When echoing, this takes up valuable resources and can effect +// performance. If absolutely needed for normal operation, the serial write buffer should be greatly increased +// to help minimize transmission waiting within the serial write protocol. +// #define REPORT_ECHO_LINE_RECEIVED // Default disabled. Uncomment to enable. + // Minimum planner junction speed. Sets the default minimum junction speed the planner plans to at // every buffer block junction, except for starting from rest and end of the buffer, which are always // zero. This value controls how fast the machine moves through junctions with no regard for acceleration @@ -261,7 +277,8 @@ // Sets the minimum feed rate the planner will allow. Any value below it will be set to this minimum // value. This also ensures that a planned motion always completes and accounts for any floating-point -// round-off errors. A lower value than 1.0 mm/min may work in some cases, but we don't recommend it. +// round-off errors. Although not recommended, a lower value than 1.0 mm/min will likely work in smaller +// machines, perhaps to 0.1mm/min, but your success may vary based on multiple factors. #define MINIMUM_FEED_RATE 1.0 // (mm/min) // Number of arc generation iterations by small angle approximation before exact arc trajectory @@ -353,14 +370,20 @@ // #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. -// --------------------------------------------------------------------------------------- - -// TODO: Install compile-time option to send numeric status codes rather than strings. - // --------------------------------------------------------------------------------------- // COMPILE-TIME ERROR CHECKING OF DEFINE VALUES: +#ifndef HOMING_CYCLE_0 + #error "Required HOMING_CYCLE_0 not defined." +#endif + +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(VARIABLE_SPINDLE) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with VARIABLE_SPINDLE enabled" +#endif +#if defined(USE_SPINDLE_DIR_AS_ENABLE_PIN) && !defined(CPU_MAP_ATMEGA328P) + #error "USE_SPINDLE_DIR_AS_ENABLE_PIN may only be used with a 328p processor" +#endif // --------------------------------------------------------------------------------------- diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 64696163b..872e0bfcd 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -79,15 +79,23 @@ // Define spindle enable and spindle direction output pins. #define SPINDLE_ENABLE_DDR DDRB #define SPINDLE_ENABLE_PORT PORTB - #ifdef VARIABLE_SPINDLE // Z Limit pin and spindle enabled swapped to access hardware PWM on Pin 11. - #define SPINDLE_ENABLE_BIT 3 // Uno Digital Pin 11 + // Z Limit pin and spindle PWM/enable pin swapped to access hardware PWM on Pin 11. + #ifdef VARIABLE_SPINDLE + #ifdef USE_SPINDLE_DIR_AS_ENABLE_PIN + // If enabled, spindle direction pin now used as spindle enable, while PWM remains on D11. + #define SPINDLE_ENABLE_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.) + #else + #define SPINDLE_ENABLE_BIT 3 // Uno Digital Pin 11 + #endif #else #define SPINDLE_ENABLE_BIT 4 // Uno Digital Pin 12 - #endif - #define SPINDLE_DIRECTION_DDR DDRB - #define SPINDLE_DIRECTION_PORT PORTB - #define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.) - + #endif + #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN + #define SPINDLE_DIRECTION_DDR DDRB + #define SPINDLE_DIRECTION_PORT PORTB + #define SPINDLE_DIRECTION_BIT 5 // Uno Digital Pin 13 (NOTE: D13 can't be pulled-high input due to LED.) + #endif + // Define flood and mist coolant enable output pins. // NOTE: Uno analog pins 4 and 5 are reserved for an i2c interface, and may be installed at // a later date if flash and memory space allows. @@ -134,11 +142,11 @@ #define WAVE1_REGISTER WGM21 #define WAVE2_REGISTER WGM22 #define WAVE3_REGISTER WGM23 - + // NOTE: On the 328p, these must be the same as the SPINDLE_ENABLE settings. - #define SPINDLE_PWM_DDR SPINDLE_ENABLE_DDR - #define SPINDLE_PWM_PORT SPINDLE_ENABLE_PORT - #define SPINDLE_PWM_BIT SPINDLE_ENABLE_BIT // Shared with SPINDLE_ENABLE. + #define SPINDLE_PWM_DDR DDRB + #define SPINDLE_PWM_PORT PORTB + #define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11 #endif // End of VARIABLE_SPINDLE #endif diff --git a/grbl/gcode.c b/grbl/gcode.c index 3893c6179..db72aa2be 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -281,11 +281,16 @@ uint8_t gc_execute_line(char *line) case 2: case 30: gc_block.modal.program_flow = PROGRAM_FLOW_COMPLETED; break; // Program end and reset } break; - case 3: case 4: case 5: + #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN + case 4: + #endif + case 3: case 5: word_bit = MODAL_GROUP_M7; switch(int_value) { case 3: gc_block.modal.spindle = SPINDLE_ENABLE_CW; break; - case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break; + #ifndef USE_SPINDLE_DIR_AS_ENABLE_PIN + case 4: gc_block.modal.spindle = SPINDLE_ENABLE_CCW; break; + #endif case 5: gc_block.modal.spindle = SPINDLE_DISABLE; break; } break; diff --git a/grbl/grbl.h b/grbl/grbl.h index 17886bab6..c12769e33 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150315" +#define GRBL_VERSION_BUILD "20150327" // Define standard libraries used by Grbl. #include diff --git a/grbl/planner.c b/grbl/planner.c index dcf50ece2..7989e004b 100644 --- a/grbl/planner.c +++ b/grbl/planner.c @@ -320,7 +320,7 @@ uint8_t plan_check_full_buffer() // Adjust feed_rate value to mm/min depending on type of rate input (normal, inverse time, or rapids) // TODO: Need to distinguish a rapids vs feed move for overrides. Some flag of some sort. if (feed_rate < 0) { feed_rate = SOME_LARGE_VALUE; } // Scaled down to absolute max/rapids rate later - else if (invert_feed_rate) { feed_rate = block->millimeters/feed_rate; } + else if (invert_feed_rate) { feed_rate *= block->millimeters; } if (feed_rate < MINIMUM_FEED_RATE) { feed_rate = MINIMUM_FEED_RATE; } // Prevents step generation round-off condition. // Calculate the unit vector of the line move and the block maximum feed rate and acceleration scaled diff --git a/grbl/protocol.c b/grbl/protocol.c index dc70f5043..858ffefd7 100644 --- a/grbl/protocol.c +++ b/grbl/protocol.c @@ -21,6 +21,11 @@ #include "grbl.h" +// Define different comment types for pre-parsing. +#define COMMENT_NONE 0 +#define COMMENT_TYPE_PARENTHESES 1 +#define COMMENT_TYPE_SEMICOLON 2 + static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. @@ -33,6 +38,10 @@ static void protocol_execute_line(char *line) protocol_execute_realtime(); // Runtime command check point. if (sys.abort) { return; } // Bail to calling function upon system abort + #ifdef REPORT_ECHO_LINE_RECEIVED + report_echo_line_received(line); + #endif + if (line[0] == 0) { // Empty or comment line. Send status message for syncing purposes. report_status_message(STATUS_OK); @@ -82,7 +91,7 @@ void protocol_main_loop() // Primary loop! Upon a system abort, this exits back to main() to reset the system. // --------------------------------------------------------------------------------- - uint8_t iscomment = false; + uint8_t comment = COMMENT_NONE; uint8_t char_counter = 0; uint8_t c; for (;;) { @@ -101,14 +110,14 @@ void protocol_main_loop() if ((c == '\n') || (c == '\r')) { // End of line reached line[char_counter] = 0; // Set string termination character. protocol_execute_line(line); // Line is complete. Execute it! - iscomment = false; + comment = COMMENT_NONE; char_counter = 0; } else { - if (iscomment) { + if (comment != COMMENT_NONE) { // Throw away all comment characters if (c == ')') { - // End of comment. Resume line. - iscomment = false; + // End of comment. Resume line. But, not if semicolon type comment. + if (comment == COMMENT_TYPE_PARENTHESES) { comment = COMMENT_NONE; } } } else { if (c <= ' ') { @@ -121,9 +130,10 @@ void protocol_main_loop() // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now. // In the future, we could simply remove the items within the comments, but retain the // comment control characters, so that the g-code parser can error-check it. - iscomment = true; - // } else if (c == ';') { - // Comment character to EOL NOT SUPPORTED. LinuxCNC definition. Not NIST. + comment = COMMENT_TYPE_PARENTHESES; + } else if (c == ';') { + // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST. + comment = COMMENT_TYPE_SEMICOLON; // TODO: Install '%' feature // } else if (c == '%') { @@ -136,7 +146,7 @@ void protocol_main_loop() } else if (char_counter >= (LINE_BUFFER_SIZE-1)) { // Detect line buffer overflow. Report error and reset line buffer. report_status_message(STATUS_OVERFLOW); - iscomment = false; + comment = COMMENT_NONE; char_counter = 0; } else if (c >= 'a' && c <= 'z') { // Upcase lowercase line[char_counter++] = c-'a'+'A'; @@ -206,6 +216,8 @@ void protocol_execute_realtime() // to do what is needed before resetting, like killing the incoming stream. The // same could be said about soft limits. While the position is not lost, the incoming // stream could be still engaged and cause a serious crash if it continues afterwards. + + // TODO: Allow status reports during a critical alarm. Still need to think about implications of this. // if (sys.rt_exec_state & EXEC_STATUS_REPORT) { // report_realtime_status(); // bit_false_atomic(sys.rt_exec_state,EXEC_STATUS_REPORT); diff --git a/grbl/report.c b/grbl/report.c index f57360267..001c02de3 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -400,6 +400,15 @@ void report_build_info(char *line) } +// Prints the character string line Grbl has received from the user, which has been pre-parsed, +// and has been sent into protocol_execute_line() routine to be executed by Grbl. +void report_echo_line_received(char *line) +{ + printPgmString(PSTR("[echo: ")); printString(line); + printPgmString(PSTR("]\r\n")); +} + + // Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram // and the actual location of the CNC machine. Users may change the following function to their // specific needs, but the desired real-time data report must be as short as possible. This is diff --git a/grbl/report.h b/grbl/report.h index e21df424e..82593cf0f 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -87,6 +87,9 @@ void report_grbl_help(); // Prints Grbl global settings void report_grbl_settings(); +// Prints an echo of the pre-parsed line received right before execution. +void report_echo_line_received(char *line); + // Prints realtime status report void report_realtime_status(); diff --git a/grbl/spindle_control.c b/grbl/spindle_control.c index f0724b4f1..18c92acd4 100644 --- a/grbl/spindle_control.c +++ b/grbl/spindle_control.c @@ -24,16 +24,21 @@ void spindle_init() { - // On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin. + // Configure variable spindle PWM and enable pin, if requried. On the Uno, PWM and enable are + // combined unless configured otherwise. #ifdef VARIABLE_SPINDLE SPINDLE_PWM_DDR |= (1< Date: Fri, 27 Mar 2015 19:59:34 -0600 Subject: [PATCH 47/74] Compile-option for inverting spindle enable. - Installed a compile-option for inverting the spindle enable pin for certain electronics boards users have reported needing this. --- grbl/config.h | 7 +++++++ grbl/spindle_control.c | 24 ++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index f4306946a..d45b2607e 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -156,6 +156,13 @@ // NOTE: Will eventually be added to Grbl settings in v1.0. // #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. +// Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful +// for some pre-built electronic boards. +// NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and +// spindle enable are combined to one pin. If you need both this option and spindle speed PWM, +// uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below. +// #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable. + // Enable limit pin states feedback in status reports. The data is presented as 0 (low) or 1(high), // where the order is XYZ. For example, if the Y- and Z-limit pins are active, Grbl will include the // following string in the status report "Lim:011". This is generally useful for setting up a new diff --git a/grbl/spindle_control.c b/grbl/spindle_control.c index 18c92acd4..d9c5c100f 100644 --- a/grbl/spindle_control.c +++ b/grbl/spindle_control.c @@ -49,10 +49,18 @@ void spindle_stop() #ifdef VARIABLE_SPINDLE TCCRA_REGISTER &= ~(1< Date: Sun, 29 Mar 2015 11:35:16 -0600 Subject: [PATCH 48/74] Commit history, logo license, full-arc fix. - Commit history added to repo, as an easier way for people to see view the changes over time. - Grbl logo copyright license added. All rights reserved with regards to the Grbl logo. - G2/3 full circles would sometime not execute. The problem was due to numerical round-off of a trig calculation. Added a machine epsilon define to help detect and correct for this problem. Tested and should not effect general operation of arcs. --- README.md | 6 +- doc/log/commit_log_v0.7.txt | 433 ++++ doc/log/commit_log_v0.8c.txt | 831 ++++++++ doc/log/commit_log_v0.9g.txt | 2409 +++++++++++++++++++++++ doc/log/commit_log_v0.9i.txt | 596 ++++++ doc/media/COPYING | 2 + doc/{logo => media}/Grbl Logo 150px.png | Bin doc/{logo => media}/Grbl Logo 250px.png | Bin doc/{logo => media}/Grbl Logo 320px.png | Bin doc/{logo => media}/Grbl Logo 640px.png | Bin doc/{logo => media}/Grbl Logo.pdf | Bin doc/{logo => media}/Grbl Logo.svg | 0 grbl/config.h | 14 +- grbl/grbl.h | 2 +- grbl/motion_control.c | 4 +- 15 files changed, 4289 insertions(+), 8 deletions(-) create mode 100644 doc/log/commit_log_v0.7.txt create mode 100644 doc/log/commit_log_v0.8c.txt create mode 100644 doc/log/commit_log_v0.9g.txt create mode 100644 doc/log/commit_log_v0.9i.txt create mode 100644 doc/media/COPYING rename doc/{logo => media}/Grbl Logo 150px.png (100%) rename doc/{logo => media}/Grbl Logo 250px.png (100%) rename doc/{logo => media}/Grbl Logo 320px.png (100%) rename doc/{logo => media}/Grbl Logo 640px.png (100%) rename doc/{logo => media}/Grbl Logo.pdf (100%) rename doc/{logo => media}/Grbl Logo.svg (100%) diff --git a/README.md b/README.md index c2f7e3119..aab14fdb4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![GitHub Logo](/doc/logo/Grbl Logo 250px.png) +![GitHub Logo](/doc/media/Grbl Logo 250px.png) *** @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-03-15)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-15)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-03-29)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-29)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. diff --git a/doc/log/commit_log_v0.7.txt b/doc/log/commit_log_v0.7.txt new file mode 100644 index 000000000..5d536a3c0 --- /dev/null +++ b/doc/log/commit_log_v0.7.txt @@ -0,0 +1,433 @@ +---------------- +Date: 2012-01-17 +Author: Sonny Jeon +Subject: Update readme.textile + +---------------- +Date: 2012-01-17 +Author: Sonny Jeon +Subject: Merge pull request #47 from chamnit/v0_7 + +Merging chamnit/v0_7 to grbl/master + +---------------- +Date: 2012-01-17 +Author: Sonny Jeon +Subject: Merge chamnit/v0_7 with grbl/master + + +---------------- +Date: 2012-01-17 +Author: Sonny Jeon +Subject: Update readme.textile + +---------------- +Date: 2012-01-17 +Author: Sonny Jeon +Subject: Merge pull request #39 from chamnit/edge + +Merging chamnit/grbl edge v0.8a to grbl/grbl edge + +---------------- +Date: 2012-01-15 +Author: Sonny Jeon +Subject: Propagated premature step end bug fix from the edge branch. Updated printFloat() function. + +- Will not be uploading a hex build of this, unless asked. + + +---------------- +Date: 2012-01-15 +Author: Sonny Jeon +Subject: Fix bug with premature step end. Refactored _delay_ms() and square() for better portability. + +- Fixed a premature step end bug dating back to Simen's 0.7b edge +version is fixed, from which this code is forked from. Caused by Timer2 +constantly overflowing calling the Step Reset Interrupt every 128usec. +Now Timer2 is always disabled after a step end and should free up some +cycles for the main program. Could be more than one way to fix this +problem. I'm open to suggestions. + +- _delay_ms() refactored to accept only constants to comply with +current compilers. square() removed since not available with some +compilers. + + +---------------- +Date: 2012-01-10 +Author: Sonny Jeon +Subject: Extended position reporting with both home and work coordinates. Home position now retained after reset. Other minor changes/fixes. + +- Grbl now tracks both home and work (G92) coordinate systems and does +live updates when G92 is called. +- Rudimentary home and work position status reporting. Works but still +under major construction. +- Updated the main streaming script. Has a disabled periodic timer for +querying status reports, disabled only because the Python timer doesn't +consistently restart after the script exits. Add here only for user +testing. +- Fixed a bug to prevent an endless serial_write loop during status +reports. +- Refactored the planner variables to make it more clear what they are +and make it easier for clear them. + + +---------------- +Date: 2012-01-09 +Author: Sonny Jeon +Subject: Corrected a minor streaming script character counting bug. + +---------------- +Date: 2012-01-09 +Author: Sonny Jeon +Subject: Updated line in streaming script. + +---------------- +Date: 2012-01-06 +Author: Sonny Jeon +Subject: Position reporting, refactored system variables, serial print fixes, updated streaming scripts. + +- Added machine position reporting to status queries. This will be +further developed with part positioning/offsets and maintaining +location upon reset. + +- System variables refactored into a global struct for better +readability. + +- Removed old obsolete Ruby streaming scripts. These were no longer +compatible. Updated Python streaming scripts. + +- Fixed printFloat() and other printing functions. + +- Decreased planner buffer back to 18 blocks and increased TX serial +buffer to 64 bytes. Need the memory space for future developments. + +- Begun adding run-time modes to grbl, where block delete toggle, mm/in +reporting modes, jog modes, etc can be set during runtime. Will be +fleshed out and placed into EEPROM when everything is added. + + +---------------- +Date: 2011-12-10 +Author: Sonny Jeon +Subject: Various minor updates and variable definition corrections. Removed deprecated acceleration manager. + +- Removed deprecated acceleration manager (non-functional since v0.7b) +- Updated variable types and function headers. - Updated stepper +interrupt to ISR() from SIGNAL()+sei(). - General code cleanup. + + +---------------- +Date: 2011-12-08 +Author: Sonny Jeon +Subject: Initial v0.8 ALPHA commit. Features multi-tasking run-time command execution (feed hold, cycle start, reset, status query). Extensive re-structuring of code for future features. + +- ALPHA status. - Multitasking ability with run-time command executions +for real-time control and feedback. - Decelerating feed hold and resume +during operation. - System abort/reset, which immediately kills all +movement and re-initializes grbl. - Re-structured grbl to easily allow +for new features: Status reporting, jogging, backlash compensation. (To +be completed in the following releases.) - Resized TX/RX serial buffers +(32/128 bytes) - Increased planner buffer size to 20 blocks. - Updated +documentation. + + +---------------- +Date: 2011-11-19 +Author: Sonny Jeon +Subject: Updated README and reordered branch versions. + + +---------------- +Date: 2011-11-19 +Author: Sonny Jeon +Subject: Re-ordered stepper idle function to first disable interrupt. + +---------------- +Date: 2011-11-11 +Author: Sonny Jeon +Subject: Corrected clearing of target and position variable for the go home routine. Thanks Jens! + +---------------- +Date: 2011-10-11 +Author: Sonny Jeon +Subject: Delete a new work file shouldn't have been synced. + + +---------------- +Date: 2011-10-11 +Author: Sonny Jeon +Subject: Third time's a charm! No more deceleration issues! Updated grbl version and settings. General cleanup. + +- Fleshed out the original idea to completely remove the long slope at +the end of deceleration issue. This third time should absolutely +eliminate it. +- Changed the acceleration setting to kept as mm/min^2 internally, +since this was creating unneccessary additional computation in the +planner. Human readable value kept at mm/sec^2. +- Updated grbl version 0.7d and settings version to 4. NOTE: Please +check settings after update. These may have changed, but shouldn't. +- Before updating the new features (pause, e-stop, federate override, +etc), the edge branch will soon be merged with the master, barring any +immediate issues that people may have, and the edge branch will be the +testing ground for the new grbl version 0.8. + + +---------------- +Date: 2011-10-07 +Author: Sonny Jeon +Subject: Forgot something! Comments on what the last change does. + + +---------------- +Date: 2011-10-06 +Author: Sonny Jeon +Subject: Minor update to further eliminate the ole long slope deceleration issue. New update note! + +- Added another way to further ensure the long slope deceleration issue +is eliminated. If the stepper rate change is too great near zero, the +stepper rate is adjusted at half increments to the end of travel, +creating a smooth transition. - If the new STEPPER_IDLE_LOCK_TIME is +set as zero, this delay is not compiled at compile-time. - NOTE: The +next update is likely going to be major, involving a full re-write of +the stepper.c program to integrate a simple way to apply pauses, +jogging, e-stop, and feedrate overrides. The interface should be +flexible enough to be easily modified for use with either hardware +switches or software commands. Coming soon. + + +---------------- +Date: 2011-09-29 +Author: Sonny Jeon +Subject: Added complete stop delay at the end of all motion. Moved grbl preprocessor script into a new repository. + +Added a very short (25 ms) user-definable delay before the steppers are +disabled at the motors are disabled and grbl goes idle. This ensures +any residual inertia at the end of the last motion does not cause the +axes to drift and grbl to lose its position when manually entering +g-code or when performing a tool change and starting the next +operation. + + +---------------- +Date: 2011-09-25 +Author: Sonny Jeon +Subject: Updated some comments and fixed a bug in the new stepper logic. + +- The stepper logic was not initiating the decelerations for certain +cases. Just re-arranged the logic to fix it. + + +---------------- +Date: 2011-09-24 +Author: Sonny Jeon +Subject: Fixed long slope at deceleration issue. Moved things into config.h. New MINIMUM_PLANNER_SPEED parameter. + +- The long standing issue of a long slope at deceleration is likely +fixed. The stepper program was not tracking and timing the end of +acceleration and start of deceleration exactly and now is fixed to +start and stop on time. Also, to ensure a better acceleration curve fit +used by the planner, the stepper program delays the start of the +accelerations by a half trapezoid tick to employ the midpoint rule. - +Settings version 3 migration (not fully tested, but should work) - +Added a MINIMUM_PLANNER_SPEED user-defined parameter to planner to let +a user change this if problems arise for some reason. - Moved all +user-definable #define parameters into config.h with clear comments on +what they do and recommendations of how to change them. - Minor +housekeeping. + + +---------------- +Date: 2011-09-18 +Author: Sonny J +Subject: Fixed minor bugs in planner. Increased max dwell time. Long slope bug stop-gap solution note. + +- Fixed the planner TODO regarding minimum nominal speeds. Re-arranged +calculations to be both more efficient and guaranteed to be greater +than zero. - Missed a parenthesis location on the rate_delta +calculation. Should fix a nearly in-perceptible issue with incorrect +acceleration ramping in diagonal directions. - Increased maximum dwell +time from 6.5sec to an 18hour max. A crazy amount more, but that's how +the math works out. - Converted the internal feedrate values to mm/min +only, as it was switching between mm/min to mm/sec and back to mm/min. +Also added a feedrate > 0 check in gcode.c. - Identified the long slope +at the end of rapid de/ac-celerations noted by stephanix. Problem with +the numerical integration truncation error between the exact solution +of estimate_acceleration_distance and how grbl actually performs the +acceleration ramps discretely. Increasing the +ACCELERATION_TICKS_PER_SECOND in config.h helps fix this problem. +Investigating further. + + +---------------- +Date: 2011-09-15 +Author: Sonny J +Subject: More '%' modulo opertor removals and some housecleaning. + +- Serial functions contained quite a few modulo operations that would +be executed with high frequency when streaming. AVR processors are very +slow when operating these. In one test on the Arduino forums, it showed +about a 15x slow down compared to a simple if-then statement. - +Clarified some variable names and types and comments. + + +---------------- +Date: 2011-09-13 +Author: Sonny J +Subject: Further planner improvements and misc minor bug fixes. Memory savings and increased buffer size. + +- Update grbl version and settings version to automatically reset +eeprom. FYI, this will reset your grbl settings. - Saved +3*BLOCK_BUFFER_SIZE doubles in static memory by removing obsolete +variables: speed_x, speed_y, and speed_z. - Increased buffer size +conservatively to 18 from 16. (Probably can do 20). - Removed expensive! +modulo operator from block indexing function. Reduces significant +computational overhead. - Re-organized some sqrt() calls to be more +efficient during time critical planning cases, rather than non-time +critical. - Minor bug fix in planner max junction velocity logic. - +Simplified arc logic and removed need to multiply for CW or CCW +direction. + + +---------------- +Date: 2011-09-06 +Author: Sonny J +Subject: Optimized planner re-write. Significantly faster. Full arc support enabled by rotation matrix approach. + +- Significant improvements in the planner. Removed or reordered +repetitive and expensive calculations by order of importance: +recalculating unchanged blocks, trig functions [sin(), cos(), tan()], +sqrt(), divides, and multiplications. Blocks long enough for nominal +speed to be guaranteed to be reached ignored by planner. Done by +introducing two uint8_t flags per block. Reduced computational overhead +by an order of magnitude. - Arc motion generation completely +re-written and optimized. Now runs with acceleration planner. Removed +all but one trig function (atan2) from initialization. Streamlined +computations. Segment target locations generated by vector +transformation and small angle approximation. Arc path correction +implemented for accumulated error of approximation and single precision +calculation of Arduino. Bug fix in message passing. + + +---------------- +Date: 2011-09-04 +Author: Sonny J +Subject: Minor update for memory savings in ring buffer and fleshed out commenting. + +No changes in functionality. Path vectors moved from ring buffer to +local planner static variables to save 3*(BUFFER_SIZE - 1) doubles in +memory. Detailed comments. Really need to stop micro-updating. Should be +the last until a planner optimization (ala Jens Geisler) has been +completed. + + +---------------- +Date: 2011-09-04 +Author: Sonny J +Subject: More minor bug fixes in planner. + +Reverse planner was over-writing the initial/buffer tail entry speed, +which reset the forward planner and caused it to lose track of its +speed. Should now accelerate into short linear segments much nicer now. + + +---------------- +Date: 2011-09-03 +Author: Sonny J +Subject: Minor bug fixes in planner. + + +---------------- +Date: 2011-09-03 +Author: Sonny J +Subject: Add G02/03 arc conversion/pre-processor script and example streaming script + +Beta pre-processor script used to clean and streamline g-code for +streaming and converts G02/03 arcs into linear segments. Allows for full +acceleration support if the pre-processed g-code is then streamed to +grill, sans G02/03 arcs. Added a simple example streaming script for +Python users. + + +---------------- +Date: 2011-09-03 +Author: Sonny J +Subject: Significantly improved junction control and fixed computation bugs in planner + +- Junction jerk now re-defined as junction_deviation. The distance from +the junction to the edge of a circle tangent to both previous and +current path lines. The circle radii is used to compute the maximum +junction velocity by centripetal acceleration. More robust and +simplified way to compute jerk. - Fixed bugs related to entry and exit +factors. They were computed based on the current nominal speeds but not +when computing exit factors for neighboring blocks. Removed factors and +replaced with entry speeds only. Factors now only computed for stepper +trapezoid rate conversions. - Misc: Added min(), next_block_index, +prev_block_index functions for clarity. + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Moved comment and block delete handling into protocol.c from gcode.c. Fixes bug when comment and block delete are not isolated. Blank lines ignored. + +Comments, block delete characters, and blank lines are no longer passed +to the gcode parser and should free up some memory by ignoring these +characters. Gcode parser now expects clean gcode only. There was a bug +if there were block deletes or comments not in the first character (i.e. +spindle on/off for proofing geode without turning it on, or a NXX +followed by a comment). This should fix it by bypassing the problem. +Left a commented line for easily turning on and off block deletes for a +later feature, if desired. + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Revert ea5b8942db2616e93fc0478922010c3bab7c0481^..HEAD + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Moved comment and block delete handling into protocol.c from gcode.c. Fixes bug when comment and block delete are not isolated. Blank lines ignored. + +Comments, block delete characters, and blank lines are no longer passed +to the gcode parser and should free up some memory by ignoring these +characters. Gcode parser now expects clean gcode only. There was a bug +if there were block deletes or comments not in the first character (i.e. +spindle on/off for proofing geode without turning it on, or a NXX +followed by a comment). This should fix it by bypassing the problem. +Left a commented line for easily turning on and off block deletes for a +later feature, if desired. + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Revert 517a0f659a06182c89cafe27ee371edccad777a4^..HEAD + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Revert "Moved comment and block delete handling to be done in protocol.c rather than gcode.c. Prevents these from being held in memory. Also, fixes bug when comments and block delete character are mixed with g-code." + +This reverts commit ea5b8942db2616e93fc0478922010c3bab7c0481. + + +---------------- +Date: 2011-08-15 +Author: Sonny J +Subject: Revert fdc90f1821f1f5edb7756fcddce75b4b4fbf6bbf^..HEAD + + +---------------- +Date: 2011-08-15 +Author: chamnit +Subject: Removed comment and block delete handling from gcode.c. Parser expects clean gcode. + +---------------- +Date: 2011-08-15 +Author: chamnit +Subject: Moved comment and block delete handling to be done in protocol.c rather than gcode.c. Prevents these from being held in memory. Also, fixes bug when comments and block delete character are mixed with g-code. diff --git a/doc/log/commit_log_v0.8c.txt b/doc/log/commit_log_v0.8c.txt new file mode 100644 index 000000000..f62cf89eb --- /dev/null +++ b/doc/log/commit_log_v0.8c.txt @@ -0,0 +1,831 @@ +---------------- +Date: 2012-11-25 +Author: Sonny Jeon +Subject: G28/G30 post move bug fix. Altered file permissions. + + +---------------- +Date: 2012-11-25 +Author: Sonny Jeon +Subject: G28/G30 post move bug fix. + +- Fixed a bug when after moving to a pre-defined position G28/G30, the +next move would go someplace unexpected. The g-code parser position +vector wasn't getting updated. + + +---------------- +Date: 2012-11-20 +Author: Sonny Jeon +Subject: Merge error fix. + + +---------------- +Date: 2012-11-20 +Author: Sonny Jeon +Subject: Merge v0.8 edge to master + + +---------------- +Date: 2012-11-19 +Author: Sonny Jeon +Subject: Updated interface protocol. Fixed M2 bug. + +- Updated interface protocol to play nicer with interface programs. All +Grbl responses beginning with '$' signifies a setting. Bracketed '[]' +responses are feedback messages containing either state, parameter, or +general messages. Chevron '<>' response are from the real-time status +messages, i.e. position. + +- M2 Program end command was causing a system alarm. Fixed. Thanks +@blinkenlight ! + + +---------------- +Date: 2012-11-18 +Author: Sonny Jeon +Subject: Updated readme + + +---------------- +Date: 2012-11-18 +Author: Sonny Jeon +Subject: Homing search sequence now compile-time option. New defaults.h file. Tidying up. + +- The homing sequence is now a compile-time option, where a user can +choose which axes(s) move in sequence during the search phase. Up to 3 +sequences. Works with the locating phase and the pull-off maneuver. + +- New defaults.h file to store user generated default settings for +different machines. Mainly to be used as a central repo, but each set +may be select to be compiled in as a config.h define. + + +---------------- +Date: 2012-11-15 +Author: Sonny Jeon +Subject: Added Grbl state in status report. Removed switch support. + +- Added Grbl state (Idle, Running, Queued, Hold, etc) to the real-time +status reporting feature as feedback to the user of what Grbl is doing. +Updated the help message to reflect this change. + +- Removed switches (dry run, block delete, single block mode). To keep +Grbl simple and not muddled up from things that can easily be taken +care of by an external interface, these were removed. + +- Check g-code mode was retained, but the command was moved to '$C' +from '$S0'. + + +---------------- +Date: 2012-11-14 +Author: Sonny Jeon +Subject: Re-factored system states and alarm management. Serial baud support greater than 57600. + +- Refactored system states to be more clear and concise. Alarm locks +processes when position is unknown to indicate to user something has +gone wrong. + +- Changed mc_alarm to mc_reset, which now manages the system reset +function. Centralizes it. + +- Renamed '$X' kill homing lock to kill alarm lock. + +- Created an alarm error reporting method to clear up what is an alarm: +message vs a status error: message. For GUIs mainly. Alarm codes are +negative. Status codes are positive. + +- Serial baud support upto 115200. Previous baudrate calc was unstable +for 57600 and above. + +- Alarm state locks out all g-code blocks, including startup scripts, +but allows user to access settings and internal commands. For example, +to disable hard limits, if they are problematic. + +- Hard limits do not respond in an alarm state. + +- Fixed a problem with the hard limit interrupt during the homing +cycle. The interrupt register is still active during the homing cycle +and still signal the interrupt to trigger when re-enabled. Instead, +just disabled the register. + +- Homing rate adjusted. All axes move at homing seek rate, regardless +of how many axes move at the same time. This is unlike how the stepper +module does it as a point to point rate. + +- New config.h settings to disable the homing rate adjustment and the +force homing upon powerup. + +- Reduced the number of startup lines back down to 2 from 3. This +discourages users from placing motion block in there, which can be very +dangerous. + +- Startup blocks now run only after an alarm-free reset or after a +homing cycle. Does not run when $X kill is called. For satefy reasons + + +---------------- +Date: 2012-11-10 +Author: Sonny Jeon +Subject: Tweaks. Seek rate updates when set. CCW arc full circle fix. + +- Fixed a minor issue where the seek rates would not immediately be +used and only would after a reset. Should update live now. + +- A full circle IJ offset CCW arc would not do anything. Fixed bug via +a simple if-then statement. + +- Radius mode tweaks to check for negative value in sqrt() rather than +isnan() it. Error report updated to indicate what actually happened. + + +---------------- +Date: 2012-11-09 +Author: Sonny Jeon +Subject: Added note that D13 can't be used as input, pulled-high. + + +---------------- +Date: 2012-11-09 +Author: Sonny Jeon +Subject: Fixed homing cycle hanging after locating switches. + + +---------------- +Date: 2012-11-08 +Author: Sonny Jeon +Subject: Housekeeping. + +- Added some more notes to config.h. + +- Added the ability to override some of the #defines around Grbl in +config.h, like planner buffer size, line buffer size, serial +send/receive buffers. Mainly to centralize the configurations to be +able to port to different microcontrollers later. + + +---------------- +Date: 2012-11-08 +Author: Sonny Jeon +Subject: Sanguino compile patch + +@daapp : Sanguino compile serial USART path. Thanks! + + +---------------- +Date: 2012-11-07 +Author: Sonny Jeon +Subject: More tweaks. Removed dry run. Trimmed all messages to save flash space. + +- Removed the dry run switch. It was getting overly complicated for +what it needed to do. In practice, single block mode and feed rate +overrides (coming in next release) does a much better job with dry runs +than 'dry run'. + +- Trimmed all of Grbl's messages from help, status, feedback to +settings. Saved 0.6KB+ of flash space that could be used for v0.9 +features. + +- Removed some settings inits when set. Will depend on user to power +cycle to get some of these to reload. + +- Fixed a bug with settings version not re-writing old settings, when +it should. Thanks Alden! + + +---------------- +Date: 2012-11-06 +Author: Sonny Jeon +Subject: Merge pull request #132 from hin/header_dependencies + +Header dependencies + +---------------- +Date: 2012-11-05 +Author: Sonny Jeon +Subject: Tweaks and bug fixes. Increase to 3 startup blocks. Remove purge/added unlock command + +- Increased the number of startup blocks to 3 for no good reason other +than it doesn't increase the flash size. + +- Removed the purge buffer command and replaced with an disable homing +lock command. + +- Homing now blocks all g-code commands (not system commands) until the +homing cycle has been performed or the disable homing lock is sent. +Homing is required upon startup or if Grbl loses it position. This is +for safety reasons. + +- Cleaned up some of the Grbl states and re-organized it to be little +more cohesive. + +- Cleaned up the feedback and status messages to not use so much flash +space, as it's a premium now. + + - Check g-code and dry run switches how are mutually exclusive and +can't be enabled when the other is. And automatically resets Grbl when +disabled. + +- Some bug fixes and other minor tweaks. + + +---------------- +Date: 2012-11-05 +Author: Hans Insulander +Subject: Ignore dependency files + + +---------------- +Date: 2012-11-05 +Author: Hans Insulander +Subject: Generate header dependencies and use them in Makefile + + +---------------- +Date: 2012-11-05 +Author: Sonny Jeon +Subject: Tweaked dry run and check g-code switches. Now resets when toggled off. + +- To make managing the code easier and to help ensure a user starts +with a fresh reset, the functionality of check g-code and dry run has +been changed to automatically perform a soft reset when toggled off. +Position will not be lost, unless there is a cycle active. Feed hold +before toggling off it needed. + +This is mainly a safety issue. If a user dry runs a program and kills +it mid-program, and then restarts it thinking to run it as normal, the +g-code modes that we're set may not be what they expect, and very bad +things can happen. + +- NOTE: Grbl is at 83.5% of flash capacity. Not a lot of room left, but +I think we can squeeze in some more! + + +---------------- +Date: 2012-11-04 +Author: Sonny Jeon +Subject: Runtime command pinned out! Re-organized coolant pins. + +- Pinned out cycle start(A2), feed hold(A1), and reset(A0) runtime +commands. These pins are held high with the internal pull-up resistor +enabled. All you have to do is connect a normally-open switch to the +pin and ground. That's it. + +- Moved the coolant control pins to A3 (and the optional mist control +to A4). + +- Moved all of the MASK defines into the config.h file to centralize +them. + + +---------------- +Date: 2012-11-04 +Author: Sonny Jeon +Subject: Tweaks and minor bug fixes. Added purge buffer command. + +- Added a purge buffer (and lock) command. This is an advanced option +to clear any queued blocks in the buffer in the event of system +position being lost or homed. These queued blocks will likely not move +correctly if not purged. In typical use, the purging command releases +the homing axes lock in case a user need to move the axes off their +hard limit switches, but position is not guaranteed. Homing is advised +immediately after. + +- Created a system-wide sync current position function. Cleans up some +of the repetitive tasks in various places in the code that do the same +thing. + +- Removed the clear all switches command '$S'. Not really needed and +helped clean up a sync call. + +- Other minor tweaks. Readme updated slightly.. + + +---------------- +Date: 2012-11-03 +Author: Sonny Jeon +Subject: New startup script setting. New dry run, check gcode switches. New system state variable. Lots of reorganizing. + +(All v0.8 features installed. Still likely buggy, but now thourough +testing will need to start to squash them all. As soon as we're done, +this will be pushed to master and v0.9 development will be started. +Please report ANY issues to us so we can get this rolled out ASAP.) + +- User startup script! A user can now save one (up to 5 as compile-time +option) block of g-code in EEPROM memory. This will be run everytime +Grbl resets. Mainly to be used as a way to set your preferences, like +G21, G54, etc. + +- New dry run and check g-code switches. Dry run moves ALL motions at +rapids rate ignoring spindle, coolant, and dwell commands. For rapid +physical proofing of your code. The check g-code switch ignores all +motion and provides the user a way to check if there are any errors in +their program that Grbl may not like. + +- Program restart! (sort of). Program restart is typically an advanced +feature that allows users to restart a program mid-stream. The check +g-code switch can perform this feature by enabling the switch at the +start of the program, and disabling it at the desired point with some +minimal changes. + +- New system state variable. This state variable tracks all of the +different state processes that Grbl performs, i.e. cycle start, feed +hold, homing, etc. This is mainly for making managing of these task +easier and more clear. + +- Position lost state variable. Only when homing is enabled, Grbl will +refuse to move until homing is completed and position is known. This is +mainly for safety. Otherwise, it will let users fend for themselves. + +- Moved the default settings defines into config.h. The plan is to +eventually create a set of config.h's for particular as-built machines +to help users from doing it themselves. + +- Moved around misc defines into .h files. And lots of other little +things. + + +---------------- +Date: 2012-11-01 +Author: Sonny Jeon +Subject: Added block delete, opt stop, single block mode. New parser state and parameter feedback. Overhauled '$' command. + +NOTE: Another incremental update. Likely buggy, still a ways to go +before everything is installed, such as startup blocks. + +- Changed the '$' command to print help. '$$' now prints Grbl settings. +The help now instructs the user of runtime commands, switch toggling, +homing, etc. Jogging will be added to these in v0.9. + +- Added switches: block delete, opt stop, and single block mode. + +- Now can print the g-code parser state and persistent parameters +(coord sys) to view what Grbl has internally. + +- Made the gc struct in the g-code parser global to be able to print +the states. Also moved coordinate system tracking from sys to gc struct. + +- Changed up the welcome flag and updated version to v0.8c. + +- Removed spindle speed from gcode parser. Not used. + + +---------------- +Date: 2012-11-01 +Author: Sonny Jeon +Subject: New report module. 6 persistent work coordinates. New G-codes and settings. README and minor bug updates + +(NOTE: This push is likely buggy so proceed with caution. Just +uploading to let people know where we're going.) + +- New report.c module. Moved all feedback functions into this module to +centralize these processes. Includes realtime status reports, status +messages, feedback messages. + +- Official support 6 work coordinate systems (G54-G59), which are +persistently held in EEPROM memory. + +- New g-code support: G28.1, G30.1 stores current machine position as a +home position into EEPROM. G10 L20 Px stores current machine position +into work coordinates without needing to explicitly send XYZ words. + +- Homing performed with '$H' command. G28/G30 no longer start the +homing cycle. This is how it's supposed to be. + +- New settings: Stepper enable invert and n_arc correction installed. + +- Updated and changed up some limits and homing functionality. Pull-off +travel will now move after the homing cycle regardless of hard limits +enabled. Fixed direction of pull-off travel (went wrong way). + +- Started on designing an internal Grbl command protocol based on the +'$' settings letter. Commands with non numeric characters after '$' +will perform switch commands, homing cycle, jogging, printing +paramters, etc. Much more to do here. + +- Updated README to reflect all of the new features. + + +---------------- +Date: 2012-10-21 +Author: Sonny Jeon +Subject: Added misc message to indicate how to exit ALARM mode. + + +---------------- +Date: 2012-10-21 +Author: Sonny Jeon +Subject: New alarm method. Re(re)organized status messages. + +- Installed a new 'alarm' method to centralize motion kills across +alarm or reset events. Right now, this is controlled by system abort +and hard limits. But, in the future, a g-code parser error may call +this too as a safety feature. + +- Re(re)organized status messages to just print all errors, regardless +from where it was called. This centralizes them into one place. + +- Misc messages method installed for any user feedback that is not a +confirmation or error. Mainly so that there is a place to perform +warnings and such. + +- New stuff installed and still made the flash size smaller by saving +flash space from clearing out repeated '\r\n' pgmstrings. + +- Fixed a bug where hard limits message would print everytime a system +abort was sent. + + +---------------- +Date: 2012-10-21 +Author: Sonny Jeon +Subject: Re-organized status messages to be more coherent and centralized. + +- Reorganized all of the status message feedback from both the g-code +parser and settings modules to be centralized into two message modules: +status feedback from executing a line and warnings for misc feedback. + +- Pulled out the printPgmString() messages in settings.c and placed it +into the new module. (settings_dump() not moved). + +- Some other minor edits. Renaming defines, comment updates, etc. + + +---------------- +Date: 2012-10-18 +Author: Sonny Jeon +Subject: Hard limits code minor updates. + +- Fixed a bug that would not disable the steppers if a user issues a +system abort during a homing cycle. + +- Updated the hard limit interrupt to be more correct and to issue a +shutdown for the right situations when the switch has been triggered. + +- Added a status message to indicate to the user what happened and what +to do upon a hard limit trigger. + + +---------------- +Date: 2012-10-16 +Author: Sonny Jeon +Subject: 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. + + +---------------- +Date: 2012-10-13 +Author: Sonny Jeon +Subject: Minor updates, improvements, and bug fixes. + +- Allowed status_message function to be called by others. This is to +centralize all feedback into protocol.c. + +- Fixed a bug where line number words 'N' were causing the parser to +error out. + +- Allowed homing routine feed rates to move slower than the +MINIMUM_STEP_RATE parameter in config.h. + +- Homing performs idle lock at the end of the routine. + +- Stepper idle lock time will now not disable the steppers when the +value is set at 255. This is accomodate users who prefer to keep their +axes enabled at all times. + +- Moved some defines around to where they need to be. + + +---------------- +Date: 2012-10-12 +Author: Sonny Jeon +Subject: Updated delay_us() function to accept long integers + + +---------------- +Date: 2012-10-11 +Author: Sonny Jeon +Subject: (2x) speed increase in printFloat() function. Decimal places setting added. + +- printFloat() function execution doubled in speed. This is a precursor +to status reporting, since GUIs may query real-time position rapidly. + +- Decimal places added to settings (for now). This may disappear in +future pushes, but here for testing purposes. + + +---------------- +Date: 2012-10-11 +Author: Sonny Jeon +Subject: Homing stepper enable bit fix. + + +---------------- +Date: 2012-10-10 +Author: Sonny Jeon +Subject: Homing direction pin bits fixed. Lite refactoring of settings. + + +---------------- +Date: 2012-10-09 +Author: Sonny Jeon +Subject: 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. + + +---------------- +Date: 2012-10-08 +Author: Sonny Jeon +Subject: Fixed an issue with leaving the limit switches during a homing cycle. + + +---------------- +Date: 2012-10-08 +Author: Sonny Jeon +Subject: Updated version number to v0.8b to reflect changes. + + +---------------- +Date: 2012-10-08 +Author: Sonny Jeon +Subject: Limit pin internal pull-resistors enabled. Re-wrote read_double() function. Correctly changed all 'double's to 'float's. + +- Limit pin internal pull-resistors now enabled. Normal high operation. +This will be the standard going forward. + +- Updated all of the 'double' variable types to 'float' to reflect what +happens when compiled for the Arduino. Also done for compatibility +reasons to @jgeisler0303 's Grbl simulator code. + +- G-code parser will now ignore 'E' exponent values, since they are +reserved g-code characters for some machines. Thanks @csdexter! + +- The read_double() function was re-written and optimized for use in +Grbl. The strtod() avr lib was removed. + + +---------------- +Date: 2012-09-30 +Author: Sonny Jeon +Subject: Updated limit/homing routine. Works, but needs more TLC. + +- Added acceleration to the homing routine. + +- Homing now accounts for different step rates when moving multiple +axes without exceeding acceleration limits. + +- Homing now updates all internal positioning variables to machine zero +after completion. + +- "Poor-man's" debounce delay added. + +- Updated the delay_us() function to perform faster and more accurate +microsecond delays. Previously, the single increments would add +noticeable time drift for larger delays. + +- Fix a bug in the stepper.c prescalar calculations that was changed in +the last commit. + +- Other minor fixes. + + +---------------- +Date: 2012-09-21 +Author: Sonny Jeon +Subject: Minor prescalar optimization. Changed up some defines. + + +---------------- +Date: 2012-09-21 +Author: Sonny Jeon +Subject: Added coolant control (M7*, M8, M9). Mist control can be enabled via config.h. + +- Added coolant control! Flood control (M8) functions on analog pin 0. +Mist control (M7) is compile-time optional and is on analog pin 1. (Use +only if you have multiple coolants on your system). Based on work by +@openpnp. + +- Fixed some variable assignments in spindle control. + + +---------------- +Date: 2012-09-21 +Author: Sonny Jeon +Subject: Merge pull request #120 from tmpvar/configurable-makefile + +Add support for overriding DEVICE and PROGRAMMER + +---------------- +Date: 2012-09-21 +Author: Elijah Insua +Subject: Add support for overriding DEVICE and PROGRAMMER + +By setting environment variables. + +example: PROGRAMMER=-c arduino -P /dev/tty.usbmodemfa131 make flash + + +---------------- +Date: 2012-09-19 +Author: Sonny Jeon +Subject: M30 minor bug fix. + +Order of operations was off. Now works as intended, + + +---------------- +Date: 2012-06-27 +Author: Sonny Jeon +Subject: No changes. Github commit bug. + + +---------------- +Date: 2012-06-26 +Author: Sonny Jeon +Subject: Added step pulse delay after direction set (Compile-time option only). Updated read me. + +Added a compile-time only experimental feature that creates a +user-specified time delay between a step pulse and a direction pin set +(in config.h). This is for users with hardware-specific issues +(opto-couplers) that need more than a few microseconds between events, +which can lead to slowly progressing step drift after many many +direction changes. We suggest to try the hack/fix posted in the Wiki +before using this, as this experimental feature may cause Grbl to take +a performance hit at high step rates and about complex curves. + + +---------------- +Date: 2012-03-10 +Author: Sonny Jeon +Subject: Minor fix related to spindle_stop() crashing abort in certain cases. + +- Updated spindle_stop() to fix abort bug and to be more in line with +v0.8. + + +---------------- +Date: 2012-03-05 +Author: Sonny Jeon +Subject: Minor updates. + +- Updated makefile to be more universally compatible by not requiring +grep or ruby. + +- Edited XON/XOFF flow control usage, noting that FTDI-based Arduinos +are known to work, but not Atmega8U2-based Arduino. Still officially +not supported, but added for advanced users. + +- Minor edits. + + +---------------- +Date: 2012-02-25 +Author: Sonny Jeon +Subject: Minor include related compile fix. Added experimental XON/XOFF flow control. Not officially supported! + +- A latency issue related to USB-to-serial converters on the Arduino +does not allow for XON/XOFF flow control to work correctly on standard +terminal programs. It seems that only specialized UI's or avoiding the +USB port all together solves this problem. However, XON/XOFF flow +control is added for advanced users only as a compile-time option. This +feature is officially *NOT* supported by grbl, but let us know of any +successes with it! + + +---------------- +Date: 2012-02-12 +Author: Sonny Jeon +Subject: Spindle DDR pins init minor fix. + + +---------------- +Date: 2012-02-11 +Author: Sonny Jeon +Subject: Fix to enable spindle DDR ports. + +---------------- +Date: 2012-02-11 +Author: Sonny Jeon +Subject: Minor compiler compatibility update for _delay_us(). + + +---------------- +Date: 2012-02-11 +Author: Sonny Jeon +Subject: G54 work coordinate support (w/ G10,G92.1). Re-factored g-code parser with error checking. Minor compiler compatibility changes. + +- G54 work coordinate system support. Up to 6 work coordinate systems +(G54-G59) available as a compile-time option. + +- G10 command added to set work coordinate offsets from machine +position. + +- G92/G92.1 position offsets and cancellation support. Properly follows +NIST standard rules with other systems. + +- G53 absolute override now works correctly with new coordinate systems. + +- Revamped g-code parser with robust error checking. Providing user +feedback with bad commands. Follows NIST standards. + +- Planner module slightly changed to only expected position movements +in terms of machine coordinates only. This was to simplify coordinate +system handling, which is done solely by the g-code parser. + +- Upon grbl system abort, machine position and work positions are +retained, while G92 offsets are reset per NIST standards. + +- Compiler compatibility update for _delay_us(). + +- Updated README. + + +---------------- +Date: 2012-01-31 +Author: Sonny Jeon +Subject: printFloat rounding fix. Affected settings. Recommend using new build. + +printFloat was printing incorrectly and adding a value of 5 to every +float instead of 0.0005 when rounding to 3 decimal places. The printed +settings values do not accurately portray the actual stored value. +Recommend using newly posted build. + + +---------------- +Date: 2012-01-28 +Author: Sonny Jeon +Subject: Program stop support (M0,M1*,M2,M30*), proper position retainment upon reset, misc minor updates. + +- Program stop support (M0,M1*,M2,M30*). *Optional stop to be done. +*Pallet shuttle not supported. + +- Work position is set equal to machine position upon reset, as +according to NIST RS274-NGC guidelines. G92 is disabled. + +- Renamed mc_set_current_position() to mc_set_coordinate_offset(). + +- Fixed bug in plan_synchronize(). Would exit right before last step is +finished and caused issues with program stops. Now fixed. + +- Spindle now stops upon a run-time abort command. + +- Updated readme and misc upkeeping. + + +---------------- +Date: 2012-01-27 +Author: Sonny Jeon +Subject: Streaming script argparse bugfix. + + +---------------- +Date: 2012-01-27 +Author: Sonny Jeon +Subject: Updated streaming scripts. Compiler compatibility for _delay_ms(). + +- Moved obsolete streaming scripts to folder for reference. + +- Added a more complex Python streaming script which uses the serial +buffer as an additional streaming buffer. + +- Removed all references to a _delay_ms(variable) to allow for better +porting across different compilers. + diff --git a/doc/log/commit_log_v0.9g.txt b/doc/log/commit_log_v0.9g.txt new file mode 100644 index 000000000..bb9f107de --- /dev/null +++ b/doc/log/commit_log_v0.9g.txt @@ -0,0 +1,2409 @@ +---------------- +Date: 2014-09-05 +Author: Sonny Jeon +Subject: Minor bug fix and CPU pin map update. + +- Sometime I HATE github. This push is just here to be able to describe +the last two pushes today that had a merging conflict and lost all of +the commit comments before. + +- Setting $10 would cause $11 to be the same value. Missed a break +statement in the switch-case. Oops! Now fixed. + +- CPU pin map for the future versions of Grbl introduced, but not yet +finalized. Still working on it and it’s subject to change. + +- Added a new high-speed machining test g-code routine written by Todd +Fleming. Mills a pocket at 15,000mm/min. Do not use when connected to +your machine! You’ve been warned! + + +---------------- +Date: 2014-09-05 +Author: Sonny Jeon +Subject: Updated README.md + + +---------------- +Date: 2014-09-05 +Author: Sonny Jeon +Subject: Merge branch 'master' of https://github.com/grbl/grbl + +Conflicts: + README.md + + +---------------- +Date: 2014-08-24 +Author: Sonny Jeon +Subject: Merge pull request #472 from BinaryConstruct/edge + +Add defaults for OX CNC + +---------------- +Date: 2014-08-24 +Author: BinaryConstruct +Subject: Add defaults for OX CNC + + +---------------- +Date: 2014-08-22 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-22 +Author: Sonny Jeon +Subject: Updated build date. + + +---------------- +Date: 2014-08-22 +Author: Sonny Jeon +Subject: WPos report bug fix when MPos disabled. + + +---------------- +Date: 2014-08-18 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-17 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-17 +Author: Sonny Jeon +Subject: Updated bitly link to master firmware + + +---------------- +Date: 2014-08-17 +Author: Sonny Jeon +Subject: Merge branch 'master' into edge + + +---------------- +Date: 2014-08-17 +Author: Sonny Jeon +Subject: Final minor updates for master release. + +- Updated ShapeOko2 defaults based on machine testing of the basic +model provided by Inventables. (or close to it.) Should be pretty +conservative but much faster than before. For example, X and Y axes are +set at (10x) faster at 5000mm/min. It can run much faster than this, +but this seems like a safe speed for everyone. + +- Updated README for master release. + +- Added some new settings methods for clearing the EEPROM when changing +versions. Needs some more work, but it should ok for master release. +Should work on it more for the next version. + + +---------------- +Date: 2014-08-13 +Author: Sonny Jeon +Subject: Added EEPROM force clear. + +- When updating from v0.8, the settings will wipe the startup lines and +build info locations so that it won’t use whatever is already there in +the EEPROM. Parameters (coord offsets) are retained. They should be ok +during an upgrade. + + +---------------- +Date: 2014-08-13 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-13 +Author: Sonny Jeon +Subject: G28/30 bug fix. Block '$$' during cycle. SO2 defaults. + +- A G28/30 bug would cause it to move to machine coordinate [0,0,0] if +no axis words were sent. It was a typo in the new g-code parser. Fixed +and slightly re-written to be more consistent with the program flow. + +- Updated the ShapeOko2 defaults based on testing on the real machine. +A little conservative, but it might change again after some more +testing. + +- Now blocks ‘$$’ command during a motion, because the printout takes +too long and can starve the segment buffer. + + +---------------- +Date: 2014-08-08 +Author: Sonny Jeon +Subject: XON/XOFF flow control variable typo. + + +---------------- +Date: 2014-08-07 +Author: Sonny Jeon +Subject: Moved Grbl Sim to its own repo. + + +---------------- +Date: 2014-08-07 +Author: Sonny Jeon +Subject: Updated licensing + + +---------------- +Date: 2014-08-05 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-05 +Author: Sonny Jeon +Subject: Fixed bug related to very very low feed rates. + +- A very very low feed rate command like `G1 X100 F0.01` would cause +some floating-point round-off error and freeze Grbl into an infinite +loop. To fix it, introduced a MINIMUM_FEED_RATE parameter in config.h +to ensure motions always complete. + +- MINIMUM_FEED_RATE is set at 1.0 mm/min by default. It’s recommended +that no rates are below this value, but 0.1mm/min may be ok in some +situations. + + +---------------- +Date: 2014-08-04 +Author: Sonny Jeon +Subject: Allow '$$' in check mode. + +- Now allows the ‘$$’ view Grbl settings while in check mode + +- Updated the version build date + + +---------------- +Date: 2014-08-04 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-04 +Author: Sonny Jeon +Subject: Fixed probe position sync error. + +- Restored probe position syncing. Had removed a pull-off motion after +a probe cycle completes, but ended up de-synchronizing the g-code +parser and probing cycle positions. Putting the pull-off motion back +fixed the problem. + + +---------------- +Date: 2014-08-03 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-03 +Author: Sonny Jeon +Subject: Probing cycle and view build info bug fixes. + +- Probing cycle would drop into a QUEUED state, if multiple G38.2 are +sent. It would not honor the auto cycle start flags. To fix, the auto +cycle start state is saved at the beginning of the probing cycle and +restored at the end, since the feed hold it uses to stop a triggered +probe will disable the auto start flag. For now it’s a patch, rather +than a permanent fix. + +- protocol_buffer_synchronize() also has a failure case. Auto cycle +start does not get executed when the system is waiting in here, so if +it’s in a QUEUED state already, it won’t resume. Patched here, but not +fully resolved. + +- Fixed a problem with the “view build info” command. The EEPROM write +would do weird things and corrupt the EEPROM. Not sure exactly what +caused it, but it’s likely a compiler problem with an improperly +defined EEPROM address. It didn’t have enough room to store a full +string. To fix, the build info EEPROM range was increased and the max +number of STARTUP_BLOCKS was reduced to 2 from 3. + +- Lastly, when a $I view build info is used for the first time, it +would normally show an EEPROM read error, since it wasn’t cleared or +wasn’t therein the first place. It will now not show that error. A +patch rather than a permanent fix again. + + +---------------- +Date: 2014-08-01 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-08-01 +Author: Sonny Jeon +Subject: Minor bug fixes. + +- Bug fix for step and direction invert masks not immediately being in +effect. Now regenerates the masks when a user changes this setting. + +- Bug fix for probing cycle. G-code standard mandates that there is an +error if the probe is already triggered when the cycle is commanded. +However, Grbl may have motions to pull off a previous probing cycle in +queue and can falsely lead to errors. To fix this, the triggered check +is performed within the probing cycle itself, right after the planner +buffer is synced. If there is an error, it will now alarm out as a +probe fail. + + +---------------- +Date: 2014-07-28 +Author: Sonny Jeon +Subject: Compile in Atmel Studio fix. + + +---------------- +Date: 2014-07-28 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-27 +Author: Sonny Jeon +Subject: Added build info feedback in help + +- `$I` prints the Grbl build info and version number. NOTE: `$I=xxx` +stores an additional 30 character string into EEPROM, which will be +printed with the build info the next time it’s run. This is for +identification purposes for users that have more than one system using +Grbl. + + +---------------- +Date: 2014-07-26 +Author: Sonny Jeon +Subject: Updates to allow Arduino IDE direct compiling. + +- Only minor changes were required to make the Arduino IDE compile all +of the Grbl’s source code (correctly using the C-compiler). Tested in +Windows and Mac and with the normal USB upload and with a programmer. + + +---------------- +Date: 2014-07-26 +Author: Sonny Jeon +Subject: Settings refactoring. Bug fixes. Misc new features. + +This is likely the last major change to the v0.9 code base before push +to master. Only two minor things remain on the agenda (CoreXY support, +force clear EEPROM, and an extremely low federate bug). + +- NEW! Grbl is now compile-able and may be flashed directly through the +Arduino IDE. Only minor changes were required for this compatibility. +See the Wiki to learn how to do it. + +- New status reporting mask to turn on and off what Grbl sends back. +This includes machine coordinates, work coordinates, serial RX buffer +usage, and planner buffer usage. Expandable to more information on user +request, but that’s it for now. + +- Settings have been completely renumbered to allow for future new +settings to be installed without having to constantly reshuffle and +renumber all of the settings every time. + +- All settings masks have been standardized to mean bit 0 = X, bit 1 = +Y, and bit 2 = Z, to reduce confusion on how they work. The invert +masks used by the internal Grbl system were updated to accommodate this +change as well. + +- New invert probe pin setting, which does what it sounds like. + +- Fixed a probing cycle bug, where it would freeze intermittently, and +removed some redundant code. + +- Homing may now be set to the origin wherever the limit switches are. +Traditionally machine coordinates should always be in negative space, +but when limit switches on are on the opposite side, the machine +coordinate would be set to -max_travel for the axis. Now you can always +make it [0,0,0] via a compile-time option in config.h. (Soft limits +routine was updated to account for this as well.) + + - Probe coordinate message immediately after a probing cycle may now +be turned off via a compile-time option in config.h. By default the +probing location is always reported. + +- Reduced the N_ARC_CORRECTION default value to reflect the changes in +how circles are generated by an arc tolerance, rather than a fixed arc +segment setting. + +- Increased the incoming line buffer limit from 70 to 80 characters. +Had some extra memory space to invest into this. + +- Fixed a bug where tool number T was not being tracked and reported +correctly. + +- Added a print free memory function for debugging purposes. Not used +otherwise. + +- Realtime rate report should now work during feed holds, but it hasn’t +been tested yet. + +- Updated the streaming scripts with MIT-license and added the simple +streaming to the main stream.py script to allow for settings to be sent. + +- Some minor code refactoring to improve flash efficiency. Reduced the +flash by several hundred KB, which was re-invested in some of these new +features. + + +---------------- +Date: 2014-07-17 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-12 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-12 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-12 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-12 +Author: Sonny Jeon +Subject: Updated README + + +---------------- +Date: 2014-07-11 +Author: Sonny Jeon +Subject: Updated README + + +---------------- +Date: 2014-07-11 +Author: Sonny Jeon +Subject: Merge pull request #441 from ashelly/edge-simfix + +Fixes for simulator in alternate configurations. + +---------------- +Date: 2014-07-10 +Author: ashelly +Subject: Restore changes made only for testing. + + +---------------- +Date: 2014-07-10 +Author: ashelly +Subject: Bug fixes for timers, added some wdt support for limit debounce. + +- Typo in timer def, +- Handle 8 bit timers correctly, +- Don't skip TOP count in CTC mode +- added SREG for atomic bit operations + + +---------------- +Date: 2014-07-09 +Author: Sonny Jeon +Subject: Merge branch 'dev' into edge + +Conflicts: + sim/simulator.c + sim/simulator.h + + +---------------- +Date: 2014-07-09 +Author: Sonny Jeon +Subject: Added test g-code programs. + + +---------------- +Date: 2014-07-06 +Author: Sonny Jeon +Subject: Version and build update. + +- Incremented from v0.9e to v0.9f due to the new g-codes, velocity +reporting option, decimal printing refactoring, grbl-sim updates, and +G0/G1 bug fix. + +- Settings version was also incremented since settings.decimal_places +is now gone. + + +---------------- +Date: 2014-07-06 +Author: Sonny Jeon +Subject: Isolate atomic bit flag for execution. + +- Denoted bit_true_atomic only for sys.execute bit settings. All other +bit_true type calls are for local variables only and don’t need atomic +access. Still looking into other ways of setting these flags without +requiring atomic access, but this is a patch for now. + + +---------------- +Date: 2014-07-06 +Author: Sonny Jeon +Subject: Merge pull request #436 from kfoltman/dev + +Fixed atomic access to flags in sys.execute. + +---------------- +Date: 2014-07-06 +Author: Sonny Jeon +Subject: Syntax fix for gcode.c + +- Whoops! Missed a bracket and it wasn’t compiling. Now fixed. + +- Updated the unsupported gcodes listed at the end of the gcode.c file. + + +---------------- +Date: 2014-07-06 +Author: Sonny Jeon +Subject: G43.1/G49 tool length offset installed. Minor bug fix. + +- Minor bug fix that caused G92.1 not to work. The mantissa of G92.1 +was not computed correctly due to floating point round-off errors and +the use of trunc(). Fixed it by changing the computation with round(). + +- Installed tool length offsets with G43.1 and G49! True tool length +offsets via G43 are not supported, because these require us to store +tool data that we don’t have space for. But we’ve come up with a good +solution for users that need this. Instead we are strictly using the +dynamic version G43.1 via linuxcnc.org. Visit their website for more +details on the command. + +- G43.1 operates by requiring an axis word and value to offset the +configured tool length axis, which can be configured for any axis +(default Z-axis) in config.h. For example, ```G43.1 Z0.5``` will offset +the work coordinates from Z0.0 to Z-0.5. + +- G49 will cancel the last tool length offset value and reset it to +zero. + +- Tweaked the ‘$#’ parameters report. `Probe` is now `PRB` and a new +value `TLO` states the tool length offset value. + + +---------------- +Date: 2014-07-05 +Author: Sonny Jeon +Subject: Merge branch 'ashelly-sim-update' into dev + + +---------------- +Date: 2014-07-05 +Author: Sonny Jeon +Subject: Merge grbl-sim updates for v0.9. + +- Removed some conflicting code in the main Grbl firmware source. + +- Temporary patch for coolant and spindle control with streaming +applied. + + +---------------- +Date: 2014-07-05 +Author: Sonny Jeon +Subject: New G43.1/G49 gcodes. Not working yet!! + +- Pushed this uncompleted code to merge a conflicting pull request. + +- New G43.1 and G49 g-codes to be installed. The beginnings of it are +in place. These g-codes are intended to be used in conjunction with +probing and allow GUIs to set tool length offsets without Grbl needing +to store a tool table. + +- G43.1 is defined as a dynamic tool length offset that is not stored +in memory. Rather, when commanded, these are applied to the work +coordinates until a reset or disabled by G49. This works much like G92. + + +---------------- +Date: 2014-07-05 +Author: ashelly +Subject: formatting + +---------------- +Date: 2014-07-05 +Author: ashelly +Subject: Update readme.md + +---------------- +Date: 2014-07-04 +Author: ashelly +Subject: Don't need kbhit.h + +---------------- +Date: 2014-07-04 +Author: Adam Shelly +Subject: minor tweaks for mingw. + + +---------------- +Date: 2014-07-04 +Author: Sonny Jeon +Subject: Realtime rate reporting. Updated decimal places. + +- Added a new optional compile-time feature for ‘realtime’ (within +50ms) feed rate reporting. When querying for a status report, a new +data value will state the current operating rate. It’s only beta at the +moment and has some kinks to work out. + +- Updated the code for printing floating point values to N decimal +places. Generalized the main floating point print code to accept a new +decimal places value and created a set of handler functions to print +certain floating point value types used in Grbl, like position, rates, +coordinate offsets, etc. All of these have different decimal +requirements and change when printed in mm or inches mode. + +- Number of decimal places for the different value types can be +re-defined in config.h, but there shouldn’t be a need for this, as +these are physically limited. + +- Removed the decimal places settings, as this was now obsoleted by the +new decimal places code. + +- The new decimal places code also saves almost 300kB in flash space, +as it’s more efficient. + + +---------------- +Date: 2014-07-04 +Author: ashelly +Subject: reduce diffs with dev branch + + +---------------- +Date: 2014-07-04 +Author: ashelly +Subject: Total rework of simulator for dev branch. Create separate thread for interrupt processes. Tick-accurate simulation of timers. Non-blocking character input for running in realtime mode. Decouple hardware sim from grbl code as much as possible. Expanded command line options. Provisions for cross-platform solution. + + +---------------- +Date: 2014-07-03 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-07-03 +Author: Sonny Jeon +Subject: G18 reporting bug fix. + +- G18 wasn’t getting reported back to the user correctly, even though +it has been set internally. Fixed the reporting code to reflect this +accurately. + + +---------------- +Date: 2014-07-03 +Author: Sonny Jeon +Subject: G-code parser G0/G1 bug fix. + +- Although stated as invalid in the NIST g-code standard, most g-code +parsers, including linuxcnc, allow G0 and G1 to be commanded without +axis words present. For example, something like ‘G1 F100.0’ to preset +the motion mode and feed rate without a motion commanded. Older CNC +controllers actually required this for feed rate settings. This update +should now allow this type of behavior. + + +---------------- +Date: 2014-07-02 +Author: Sonny Jeon +Subject: Minor bug fixes and updates. Line number tracking. + +- Line number tracking was getting truncated at 255, since it was using +wrong variable type. Fixed it with a trunc(). + +- Increased the max number line allowed by Grbl to 9999999 from the +g-code standard 99999. The latter seems to be an arbitrary number, so +we are allowing larger ones for at least one known use case scenario. + +- Created a new test directory to contain some testing g-code to proof +the firmware. Only got started with one test case so far. More will be +inserted as needed. + +- Some other commenting updates to clarify certain aspects of the code. + + +---------------- +Date: 2014-06-26 +Author: Krzysztof Foltman +Subject: Fixed atomic access to flags in sys.execute. + +This seems to fix the bug that caused Grbl to hang during some operations, +especially jogging. + + +---------------- +Date: 2014-05-31 +Author: Sonny Jeon +Subject: Arc error-checking update. + +- Updated offset-mode arc error-checking to EMC2’s version: The old +NIST definition required the radii to the current location and target +location to differ no more than 0.002mm. This proved to be problematic +and probably why LinuxCNC(EMC2) updated it to be 0.005mm AND 0.1% +radius OR 0.5mm. + + +---------------- +Date: 2014-05-31 +Author: Sonny Jeon +Subject: Various minor g-code parser fixes. + +- Updated the mantissa calculation that checks for non-integer values +and GXX.X commands that aren’t supported. There was a potential uint8 +overflow issue. + +- Fixed g-code parser bug related to not using the correct modal +struct. G10 P0 not selecting the current coordinate system when a +G55-59 is issued in the same line. + +- Fixed g-code parser bug related to not using the correct modal +struct. Target position locations were not computed correctly when +G90/91 distance modes were changed in the same line. It was using the +previous state, rather than the current block. + + +---------------- +Date: 2014-05-29 +Author: Sonny Jeon +Subject: Fixed spindle/coolant/dwell state check. + + +---------------- +Date: 2014-05-25 +Author: Sonny Jeon +Subject: Major g-code parser overhaul. 100%* compliant. Other related updates. + +- Completely overhauled the g-code parser. It’s now 100%* compliant. (* +may have some bugs). Being compliant, here are some of the major +differences. + +- SMALLER and JUST AS FAST! A number of optimizations were found that +sped things up and allowed for the more thorough error-checking to be +installed without a speed hit. Trimmed a lot of ‘fat’ in the parser and +still was able to make it significantly smaller than it was. + +- No default feed rate setting! Removed completely! This doesn’t exist +in the g-code standard. So, it now errors out whenever it’s undefined +for motions that require it (G1/2/3/38.2). + +- Any g-code parser error expunges the ENTIRE block. This means all +information is lost and not passed on to the running state. Before some +of the states would remain, which could have led to some problems. + +- If the g-code block passes all of the error-checks, the g-code state +is updated and all motions are executed according to the order of +execution. + +- Changes in spindle speed, when already running, will update the +output pin accordingly. This fixes a bug, where it wouldn’t update the +speed. + +- Update g-code parser error reporting. Errors now return detailed +information of what exact went wrong. The most common errors return a +short text description. For less common errors, the parser reports +‘Invalid gcode ID:20’, where 20 is a error ID. A list of error code IDs +and their descriptions will be documented for user reference elsewhere +to save flash space. + +- Other notable changes: + +- Added a print integer routine for uint8 variables. This saved +significant flash space by switching from a heavier universal print +integer routine. + +- Saved some flash space with our own short hypotenuse calculation + +- Some arc computation flash and memory optimizations. + + +---------------- +Date: 2014-05-18 +Author: Jens Geisler +Subject: Merge pull request #408 from chamnit/master + +MIT-Licensing change. + +---------------- +Date: 2014-05-18 +Author: Sonny Jeon +Subject: MIT-licensing change. + + +---------------- +Date: 2014-05-18 +Author: Sonny Jeon +Subject: MIT-licensing change + + +---------------- +Date: 2014-04-28 +Author: Sonny Jeon +Subject: Merge pull request #391 from paulkaplan/master + +Update Shapeoko 2 defaults + +---------------- +Date: 2014-04-14 +Author: Paul Kaplan +Subject: updated shapeoko2 defaults + + +---------------- +Date: 2014-03-14 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-03-13 +Author: Sonny Jeon +Subject: Comment corrections and function call update. + + +---------------- +Date: 2014-03-13 +Author: Sonny Jeon +Subject: Merge pull request #373 from EliteEng/dev + +Added Probing to Mega2560 and fixed Shapeoko2 compile error + +---------------- +Date: 2014-03-11 +Author: Rob Brown +Subject: Added Probing to Mega2560 and fixed Shapeoko2 compile error + + +---------------- +Date: 2014-03-07 +Author: henols +Subject: Probing command gets stuck in hold if several g38.2 are submitted +Ex. +G0 X0 Y0 Z0 +G38.2 Z-10 F100 +G10 L20 P0 Z0 +G0 Z2 +G38.2 Z-1 F50 +G10 L20 P0 Z0 +G0 Z2 +G0 X0 Y0 +G38.2 Z-1 F100 +G0 Z2 + + +---------------- +Date: 2014-03-10 +Author: Sonny Jeon +Subject: Merge pull request #372 from martinstingl/master + +Corrected units of default acceleration values + +---------------- +Date: 2014-03-10 +Author: Martin Stingl +Subject: Corrected units of default acceleration values + + +---------------- +Date: 2014-03-07 +Author: Sonny Jeon +Subject: Merge pull request #368 from henols/dev + +Probing command gets stuck in hold if several g38.2 are submitted + +---------------- +Date: 2014-03-07 +Author: henols +Subject: Probing command gets stuck in hold if several g38.2 are submitted +Ex. +G0 X0 Y0 Z0 +G38.2 Z-10 F100 +G10 L20 P0 Z0 +G0 Z2 +G38.2 Z-1 F50 +G10 L20 P0 Z0 +G0 Z2 +G0 X0 Y0 +G38.2 Z-1 F100 +G0 Z2 + + +---------------- +Date: 2014-02-28 +Author: Sonny Jeon +Subject: G38.2 probe feature rough draft installed. Working but needs testing. + +- G38.2 straight probe now supported. Rough draft. May be tweaked more +as testing ramps up. + +- G38.2 requires at least one axis word. Multiple axis words work too. +When commanded, the probe cycle will move at the last ‘F’ feed rate +specified in a straight line. + +- During a probe cycle: If the probe pin goes low (normal high), Grbl +will record that immediate position and engage a feed hold. Meaning +that the CNC machine will move a little past the probe switch point, so +keep federates low to stop sooner. Once stopped, Grbl will issue a move +to go back to the recorded probe trigger point. + +- During a probe cycle: If the probe switch does not engage by the time +the machine has traveled to its target coordinates, Grbl will issue an +ALARM and the user will be forced to reset Grbl. (Currently G38.3 probe +without error isn’t supported, but would be easy to implement later.) + +- After a successful probe, Grbl will send a feedback message +containing the recorded probe coordinates in the machine coordinate +system. This is as the g-code standard on probe parameters specifies. + +- The recorded probe parameters are retained in Grbl memory and can be +viewed with the ‘$#’ print parameters command. Upon a power-cycle, not +a soft-reset, Grbl will re-zero these values. + +- Moved ‘$#’ command to require IDLE or ALARM mode, because it accesses +EEPROM to fetch the coordinate system offsets. + +- Updated the Grbl version to v0.9d. + +- The probe cycle is subject to change upon testing or user-feedback. + + +---------------- +Date: 2014-02-27 +Author: Sonny Jeon +Subject: Probe cycle line numbers ifdef fixes to get it to compile. + +- Updated some of the ifdefs when disabling line numbers feature. +Getting messy with this compile-time option. This will likely get +cleaned up later. + +- This is just a push to get the new probing code to compile. Testing +and optimization of the code will soon follow and be pushed next. + + +---------------- +Date: 2014-02-27 +Author: Sonny Jeon +Subject: Merge pull request #362 from robgrz/dev + +Minimal probing cycle working. Supports both G38.2 for error and G38.3 ... + +---------------- +Date: 2014-02-26 +Author: Sonny Jeon +Subject: Added grbl planner Matlab simulator for test reference. Updated line number compile-time option. + +- Added a grbl planner simulation tool that was written in Matlab and +Python. It was used to visualize the inner workings of the planner as a +program is streamed to it. The simulation assumes that the planner +buffer is empty, then filled, and kept filled. This is mainly for users +to see how the planner works. + +- Updated some of the compile-time ifdefs when enabling line numbers. +The leaving the un-used line numbers in the function calls eats a +non-neglible amount of flash memory. So the new if-defs remove them. + + +---------------- +Date: 2014-02-25 +Author: Robert Grzesek +Subject: Minimal probing cycle working. Supports both G38.2 for error and G38.3 when no errors are desired. + + +---------------- +Date: 2014-02-19 +Author: Sonny Jeon +Subject: Minor updates to line number feature. + +- Changed line number integer types from unsigned to signed int32. +G-code mandates values cannot exceed 99999. Negative values can be used +to indicate certain modes. + +- Homing cycle line number changed to -1, as an indicator. + +- Fixed a reporting define for the spindle states that was broken by +the last merge. + + +---------------- +Date: 2014-02-19 +Author: Sonny Jeon +Subject: Merge pull request #356 from robgrz/dev + +Line number reporting as compile-time option. + +---------------- +Date: 2014-02-19 +Author: Sonny Jeon +Subject: Commenting updates. Minor bug fix with exit of soft limit event. + + +---------------- +Date: 2014-02-18 +Author: Robert Grzesek +Subject: Merge commit 'cd71a90ce8a770e0030ed6c9bac805b89724e275' into dev + +Conflicts: + limits.c + motion_control.c + report.c + + +---------------- +Date: 2014-02-15 +Author: Sonny Jeon +Subject: Homing and feed hold bug fixes. + +WARNING: Bugs may still exist. This branch is a work in progress and +will be pushed to the edge branch when at beta stability. Use at your +own risk. + +- Homing freezing issue fixed. Had to do with the cycle stop flag being +set incorrectly after the homing cycles and before the pull-off +maneuver. Now resets the stepper motors before this can happen. + +- Fixed an issue with a rare feed hold failure. Had to do with feed +hold ending exactly at the end of a block. The runtime protocol now +sets the QUEUED and IDLE states appropriately when this occurs. Still +need to clean this code up however, as it’s patched rather than written +well. + +- Updated version build via $I command. + +- Forgot to comment on a new feature for the last commit. Since steps +are integers and millimeters traveled are floats, the old step segment +generator ignored the step fraction differences in generating the +segment velocities. Didn’t see like it would be much of a big deal, but +there were instances that this would be a problem, especially for very +slow feed rates. The stepper algorithm now micro-adjusts the segment +velocities based on the step fractions not executed from the previous +segment. This ensures that Grbl generates the velocity profiles EXACTLY +and noticeably improves overall acceleration performance. + + +---------------- +Date: 2014-02-09 +Author: Sonny Jeon +Subject: Refactoring and lots of bug fixes. Updated homing cycle. + +WARNING: There are still some bugs to be worked out. Please use caution +if you test this firmware. + +- Feed holds work much better, but there are still some failure +conditions that need to be worked out. This is the being worked on +currently and a fix is planned to be pushed next. + +- Homing cycle refactoring: Slight adjustment of the homing cycle to +allow for limit pins to be shared by different axes, as long as the +shared limit pins are not homed on the same cycle. Also, removed the +LOCATE_CYCLE portion of the homing cycle configuration. It was +redundant. + +- Limit pin sharing: (See above). To clear up one or two limit pins for +other IO, limit pins can now be shared. For example, the Z-limit can be +shared with either X or Y limit pins, because it’s on a separate homing +cycle. Hard limit will still work exactly as before. + +- Spindle pin output fixed. The pins weren’t getting initialized +correctly. + +- Fixed a cycle issue where streaming was working almost like a single +block mode. This was caused by a problem with the spindle_run() and +coolant_run() commands and issuing an unintended planner buffer sync. + +- Refactored the cycle_start, feed_hold, and other runtime routines +into the runtime command module, where they should be handled here +only. These were redundant. + +- Moved some function calls around into more appropriate source code +modules. + +- Fixed the reporting of spindle state. + + +---------------- +Date: 2014-02-06 +Author: Robert Grzesek +Subject: Made line number reporting optional via config.h + + +---------------- +Date: 2014-02-06 +Author: Robert Grzesek +Subject: Initial line number reporting + + +---------------- +Date: 2014-02-02 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-01-28 +Author: Jens Geisler +Subject: Merge pull request #337 from michmerr/edge + +Make sure that cycle_start state is set before simulating steps. + +---------------- +Date: 2014-01-28 +Author: michmerr +Subject: Simplify setting of STATE_CYCLE and ISR interval. + +Set sys.state to STATE_CYCLE directly instead of calling back to +st_wakeup(). + +Convert get_step_time() to a constant and rename it to ISR_INTERVAL. + + +---------------- +Date: 2014-01-22 +Author: michmerr +Subject: Make sure that cycle_start state is set before simulating steps. + + +---------------- +Date: 2014-01-15 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-01-14 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-01-10 +Author: Sonny Jeon +Subject: Lots of re-organization and cleaning-up. Some bug fixes. + +- Added a new source and header file called system. These files contain +the system commands and variables, as well as all of the system headers +and standard libraries Grbl uses. Centralizing some of the code. + +- Re-organized the include headers throughout the source code. + +- ENABLE_M7 define was missing from config.h. Now there. + +- SPINDLE_MAX_RPM and SPINDLE_MIN_RPM now defined in config.h. No +uncommenting to prevent user issues. Minimum spindle RPM now provides +the lower, near 0V, scale adjustment, i.e. some spindles can go really +slow so why use up our 256 voltage bins for them? + +- Remove some persistent variables from coolant and spindle control. +They were redundant. + +- Removed a VARIABLE_SPINDLE define in cpu_map.h that shouldn’t have +been there. + +- Changed the DEFAULT_ARC_TOLERANCE to 0.002mm to improve arc tracing. +Before we had issues with performance, no longer. + +- Fixed a bug with the hard limits and the software debounce feature +enabled. The invert limit pin setting wasn’t honored. + +- Fixed a bug with the homing direction mask. Now is like it used to +be. At least for now. + +- Re-organized main.c to serve as only as the reset/initialization +routine. Makes things a little bit clearer in terms of execution +procedures. + +- Re-organized protocol.c as the overall master control unit for +execution procedures. Not quite there yet, but starting to make a +little more sense in how things are run. + +- Removed updating of old settings records. So many new settings have +been added that it’s not worth adding the code to migrate old user +settings. + +- Tweaked spindle_control.c a bit and made it more clear and consistent +with other parts of Grbl. + +- Tweaked the stepper disable bit code in stepper.c. Requires less +flash memory. + + +---------------- +Date: 2014-01-05 +Author: Sonny Jeon +Subject: Updates to some stepper algorithm commenting + + +---------------- +Date: 2014-01-05 +Author: Sonny Jeon +Subject: New build info feature. (per @Analogreality request) + +- New build info feature. Hidden command ‘$I’ will print the build info +for your Grbl firmware. Users may also write an identifying message +within it via ‘$I=‘ with up to 32 characters. (no more, or else it will +break). + +- Adjusted the max number of startup lines to 3. Majority of people +will only need one. + +- Fixed a compile error with spindle_control.c. A rogue #endif was +causing problems. + + +---------------- +Date: 2014-01-04 +Author: Sonny Jeon +Subject: Variable spindle output. Resolved conflicts in last push. + +Resolve conflicts. + + +---------------- +Date: 2014-01-04 +Author: Sonny Jeon +Subject: Cleaned up variable spindle output (PWM). Code and config comments. + +- Variable spindle speed output as a configuration option. Thanks +@EliteEng! When enabled, the Z-limit (D11) and spindle enable(D12) pins +switch to allow access to the hardware PWM output on pin D11. +Otherwise, everything should work as it does. + +- Removed option for inverting the spindle and coolant enable pins. +This is a safety hazard, especially for the spindle. When Grbl +initializes, all pins are momentarily low until it finishes booting. If +an invert is enabled, this means the spindles can be energized briefly +during this time. If users need signal inversion, it’s recommended to +just wire in an inversion circuit instead. + +- Cleared out references to spindle variable output in terms of step +signal. This isn’t complete and requires more deliberation before +installing. + +- Cleared up and cleaned up some code and config comments. + + +---------------- +Date: 2014-01-03 +Author: Sonny Jeon +Subject: Merge pull request #322 from EliteEng/dev + +Update to fix compile error + +---------------- +Date: 2014-01-03 +Author: Rob Brown +Subject: Update to fix compile error + +Update to fix compile error + + +---------------- +Date: 2014-01-02 +Author: Sonny Jeon +Subject: Merge pull request #318 from EliteEng/dev + +PWM Spindle Control and Invert Spindle & Coolant Pins + +---------------- +Date: 2014-01-03 +Author: Rob Brown +Subject: Update spindle_control.c + +Updated spindle_control.c due to compile error. + +---------------- +Date: 2014-01-02 +Author: Sonny Jeon +Subject: Fix for M7/8/9 modal group checks. Updated AMASS frequency cutoffs and code cleaned. + +- Updated Grbl version to 0.9c and build number. + +- G-code parser was missing modal group violation checks for M7/8/9 +commands. Added them. + +- Updated the Adaptive Multi-Axis Step Smoothing (AMASS) cutoff +frequencies so that the trade between the 16-bit Timer1 accuracy and +the level step smoothing are somewhat better balanced. (Smoothing isn’t +free, but a higher accuracy timer would provide high cutoff +frequencies.) + + +---------------- +Date: 2014-01-02 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-01-02 +Author: Rob Brown +Subject: PWM Spindle Control and Invert Spindle & Coolant Pins + +PWM Spindle Control and Invert Spindle & Coolant Pins + + +---------------- +Date: 2013-12-30 +Author: Sonny Jeon +Subject: Minor bug fixes: Homing travel calculations. Cycle resuming after spindle and dwell commands. + +- Homing travel calculations fixed. It was computing the min travel +rather than max. + +- Auto-start disable and pausing after spindle or dwell commands. +Related to plan_synchronize() function call. Now fixed, but still need +to work on the system state. + +- Pushed a fix to make this branch more Arduino IDE compatible. Removed +extern call in nuts_bolts.c + +- Updated the stepper configuration option of enabling or disabling the +new Adaptive Multi-Axis Step Smoothing Algorithm. Now works either way. + +- Updated some copyright info. + + +---------------- +Date: 2013-12-30 +Author: Sonny Jeon +Subject: Merge pull request #201 from Protoneer/master + +Made a few changes to make the code compatible with the Arduino IDE. Sorry about the tardiness! + +---------------- +Date: 2013-12-30 +Author: Sonny Jeon +Subject: Incomplete push but working. Lots more stuff. More to come. + +- NEW! An active multi-axis step smoothing algorithm that automatically +adjusts dependent on step frequency. This solves the long standing +issue to aliasing when moving with multiple axes. Similar in scheme to +Smoothieware, but more advanced in ensuring a more consistent CPU +overhead throughout all frequencies while maintaining step exactness. + +- Switched from Timer2 to Timer0 for the Step Port Reset Interrupt. +Mainly to free up hardware PWM pins. + +- Seperated the direction and step pin assignments, so we can now move +them to seperate ports. This means that we can more easily support 4+ +axes in the future. + +- Added a setting for inverting the limit pins, as so many users have +request. Better late than never. + +- Bug fix related to EEPROM calls when in cycle. The EEPROM would kill +the stepper motion. Now protocol mandates that the system be either in +IDLE or ALARM to access or change any settings. + +- Bug fix related to resuming the cycle after a spindle or dwell +command if auto start has been disabled. This fix is somewhat temporary +or more of a patch. Doesn’t work with a straight call-response +streaming protocol, but works fine with serial buffer pre-filling +streaming that most clients use. + +- Renamed the pin_map.h to cpu_map.h to more accurately describe what +the file is. + +- Pushed an auto start bug fix upon re-initialization. + +- Much more polishing to do! + + +---------------- +Date: 2013-12-29 +Author: Sonny Jeon +Subject: Incomplete dev code push, but working. Lots of updates/fixes/improvements. Much still to polish. + +- Ugh. Github just erased my list of improvements and changes due to a +conflict and forcing me to resolve it. Hope this goes through. + +- Major stepper algorithm change. Trashed the old v0.9 edge +branch-style stepper algorithm. It’s fine, but it was susceptible to +aliasing noise when moving very slow or very fast. It also had a bit of +CPU overhead. It was written to solve a standing issue with v0.8 +master, where it couldn’t generate a smooth acceleration abocve +10-15kHz. But, with new step segment buffer in v0.9c, it inadvertently +fixed the acceleration problem with v0.8 stepper algorithm. So, what +does it mean for you? Smoother stepper pulses and likely higher step +frequencies. + +- Stepper algorithm now uses Timer1 and Timer2, instead of Timer0 and +Timer2. Timers 0 and 2 can be swapped if there is an issue. + +- With the old v0.8 stepper algorithm, the STEP_DELAY_PULSE +configuration option is also back. + +- NEW! Hard limit software debouncing. Grbl now employs the AVR’s +watchdog timer as a way to monitor the hard limit pins and checking +their states after a delay. This is a simple software debouncing +technique and may help alleviate some of the false trigger some users +have been complaining about. BUT, this won’t fix electric noise issues! + +- Fixed an issue with the new homing cycle routine where it wasn’t +honoring the acceleration and axis speed limits depending on the homing +cycle mask. Now does. Also, updated the homing direction mask code to +be a little cleaner. + +- Moved the main part of the homing cycle control and execution to +motion_control.c, where it fits better. + +- Removed the STATE_INIT system state as it was redundant. Made the +system states into bitflags so multiple system states can be checked +via one if statement. + +- Reorganized the power-up routine to work with the new system states. + + +---------------- +Date: 2013-12-29 +Author: Sonny Jeon +Subject: Merge branch 'dev' of https://github.com/grbl/grbl into dev + +Conflicts: + limits.c + + +---------------- +Date: 2013-12-29 +Author: Sonny Jeon +Subject: Merge branch 'dev' of https://github.com/grbl/grbl into dev + +Conflicts: + limits.c + + +---------------- +Date: 2013-12-27 +Author: Sonny Jeon +Subject: Merge pull request #312 from scottrcarlson/dev + +Fixed homing_dir_mask functionality in the re-written homing_cycle. + +---------------- +Date: 2013-12-27 +Author: Scott R Carlson +Subject: Hard Limits configured for active high. + +Added the use of homing_dir_mask to homing_cycle + + +---------------- +Date: 2013-12-10 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2013-12-10 +Author: Sonny Jeon +Subject: Revamped homing cycle. Axis limits and max travel bug fixes. Build info. Refactored config.h. + +- Revamped and improved homing cycle. Now tied directly into the main +planner and stepper code, which enables much faster homing seek rates. +Also dropped the compiled flash size by almost 1KB, meaning 1KB more +for other features. + +- Refactored config.h. Removed obsolete defines and configuration +options. Moved lots of “advanced” options into the advanced area of the +file. + +- Updated defaults.h with the new homing cycle. Also updated the +Sherline 5400 defaults and added the ShapeOko2 defaults per user +submissions. + +- Fixed a bug where the individual axes limits on velocity and +acceleration were not working correctly. Caused by abs() returning a +int, rather than a float. Corrected with fabs(). Duh. + +- Added build version/date to the Grbl welcome message to help indicate +which version a user is operating on. + +- Max travel settings were not being defaulted into the settings EEPROM +correctly. Fixed. + +- To stop a single axis during a multi-axes homing move, the stepper +algorithm now has a simple axis lock mask which inhibits the desired +axes from moving. Meaning, if one of the limit switches engages before +the other, we stop that one axes and keep moving the other. + + +---------------- +Date: 2013-12-10 +Author: Sonny Jeon +Subject: Merge pull request #301 from shapeoko/master + +added shapeoko2 profile + +---------------- +Date: 2013-12-10 +Author: Edward +Subject: added shapeoko2 profile + +shapeoko 2 uses 2mm GT2 belting and 20tooth pulleys + + +---------------- +Date: 2013-12-07 +Author: Sonny Jeon +Subject: Deceleration to zero speed improvements. Update defaults. + +- A minor issue with deceleration ramps when close to zero velocity. +Should be virtually unnoticeable for most CNC systems, but fixed in +this push and accurate to physics. + +- Updated some of the junction deviation defaults. Because the new +stepper algorithm can easily maximize a CNC machine’s capabilities or +simply go much faster, this means the speed in which it enters +junctions has to be a little more constrained. Meaning that, we have to +slow a little bit down more so that we don’t exceed the acceleration +limits of the stepper motors. + + +---------------- +Date: 2013-12-07 +Author: Sonny Jeon +Subject: Pushed bug fixes. Updated readme. + +- G18 plane select fix from XZ-plane to ZX-plane per right hand rule. + +- Added volatile declaration for rx_buffer_tail in serial.c. No real +effect to operation as avr-gcc adds this upon compilation. Helps with +porting issues when using a different compiler. + + +---------------- +Date: 2013-12-07 +Author: Sonny Jeon +Subject: Pushed limits active high option. Updated defaults.h. Misc bug fixes. Cleaned up codebase. + +- Pushed limit switch active high option (i.e. NC switches). + +- Updated defaults.h to be in-line with the new settings. + +- Refactored feed hold handling and step segment buffer to be more +generalized in effort to make adding feedrate overrides easier in the +future. Also made it a little more clean. + +- Fixed G18 plane select issue. Now ZX-plane, rather than XZ-plane, per +right hand rule. + +- Cleaned some of the system settings by more accurately renaming some +of the variables and removing old obsolete ones. + +- Declared serial.c rx_buffer_tail to be volatile. No effect, since +avr-gcc automatically does this during compilation. Helps with porting +when using other compilers. + +- Updated version number to v0.9b. + +- Updates to README.md + + +---------------- +Date: 2013-12-04 +Author: Sonny Jeon +Subject: Reinstated feed holds into new stepper algorithm and planner. Rough draft, but working. + +- Reinstated the feed hold feature with the new stepper algorithm and +new optimized planner. It works, but will be re-factored a bit soon to +clean up the code. + +- At this point, feedrate overrides may need to be installed in the +v1.0 version of grbl, while this version will likely be pushed to the +edge branch soon and pushed to master after the bugs have been squashed. + +- Measured the overall performance of the new planner and stepper +algorithm on an oscilloscope. The new planner is about 4x faster than +before, where it is completing a plan in around 1ms. The stepper +algorithm itself is minutely faster, as it is a little lighter. The +trade-off in the increased planner performance comes from the new step +segment buffer. However, even in the worse case scenario, the step +segment buffer generates a new segment with a typical 0.2 ms, and the +worse case is 1ms upon a new block or replanning the active block. +Added altogether, it’s argubly still twice as efficient as the old one. + + +---------------- +Date: 2013-11-23 +Author: Sonny Jeon +Subject: Merge pull request #289 from Travis-Snoozy/master + +Add support for active-high limit switches + +---------------- +Date: 2013-11-22 +Author: Travis Snoozy +Subject: Add support for active-high limit switches + + +---------------- +Date: 2013-11-22 +Author: Sonny Jeon +Subject: Yet another major stepper algorithm and planner overhaul. + +- Overhauled the stepper algorithm and planner again. This time +concentrating on the decoupling of the stepper ISR completely. It is +now dumb, relying on the segment generator to provide the number of +steps to execute and how fast it needs to go. This freed up lots of +memory as well because it made a lot tracked variables obsolete. + +- The segment generator now computes the velocity profile of the +executing planner block on the fly in floating point math, instead of +allowing the stepper algorithm to govern accelerations in the previous +code. What this accomplishes is the ability and framework to (somewhat) +easily install a different physics model for generating a velocity +profile, i.e. s-curves. + +- Made some more planner enhancements and increased efficiency a bit. + +- The changes also did not increase the compiled size of Grbl, but +decreased it slightly as well. + +- Cleaned up a lot of the commenting. + +- Still much to do, but this push works and still is missing feedholds +(coming next.) + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Another merge fix. + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Merge fixes. + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Merge branch 'dev_2' into dev + +Conflicts: + README.md + gcode.c + motion_control.c + planner.c + planner.h + protocol.c + report.c + settings.c + settings.h + stepper.c + stepper.h + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Merge branch 'dev_2' into dev + +Conflicts: +README.md +gcode.c +motion_control.c +planner.c +planner.h +protocol.c +report.c +settings.c +settings.h +stepper.c +stepper.h + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Planner function call fix. More clean up. + + +---------------- +Date: 2013-10-29 +Author: Sonny Jeon +Subject: Updated comments. Changed stepper variable names to be more understandable. Added step locking note. + +- Updated config comments and stepper code comments for the new changes. + +- Changed stepper algorithm variable names to be more understandable in +what they actually do. + +- Added a stepper lock note in default.h per user request. + +- Started some code layout in handling feed holds and refactoring the +homing routine to use the main stepper algorithm instead of a seperate +version. + + +---------------- +Date: 2013-10-24 +Author: Sonny Jeon +Subject: Cleaned up stepper and planner code. + +- Added some compile-time error checking. Will add more in future +pushes to ensure settings are correct and within parameters that won't +break anything. + +- Pushed some master branch changes with MEGA pin settings. + +- Cleaned up planner code and comments to clarify some of the new +changes. Still much to do here. + +- Cleaned up the new stepper code. May need to abstract some of the +segment buffer more to fix the feed holds (and integrate homing into +the main stepper routine). With what's planned, this should make the +stepper algorithm easier to attach other types of processes to it, +where it is now tightly integrated with the planner buffer and nothing +else. + + +---------------- +Date: 2013-10-21 +Author: Sonny Jeon +Subject: Merge pull request #279 from EliteEng/master + +Changed Stepper Pins + +---------------- +Date: 2013-10-18 +Author: Rob Brown +Subject: Changed Stepper Pins + +Changed Stepper Pins so the Step Port Invert Mask matches the UNO + + +---------------- +Date: 2013-10-17 +Author: Sonny Jeon +Subject: Merge pull request #278 from EliteEng/master + +Update Pin Change Interrupts on Mega 2560 + +---------------- +Date: 2013-10-17 +Author: Rob Brown +Subject: Update Pin Change Interrupts so it works + +PCIE1 - Interrupt 8 on the Mega is attached to USART0 RX so when any +serial communication was transmitted it was triggering the Reset +Interrupt + + +---------------- +Date: 2013-10-14 +Author: Sonny Jeon +Subject: Fine tuning of new stepper algorithm with protected planner. Adaptive step prediction for segment buffer. + +- Cleaned up the new stepper algorithm code with more commenting and +better logic flow. + +- The new segment buffer now predicts the number of steps each segment +should have to execute over about 8 milliseconds each (based on the +ACCELERATION_TICKS_PER_SECOND setting). So, for when the whole segment +buffer is full, the stepper algorithm has roughly 40 milliseconds of +steps queued before it needs to refilled by the main program. + +- Readjusted the max supported step rate back to 30kHz from the lower +development 20kHz. Everything still works amazing great and the test +CNC machine still runs twice as fast with the new stepper algorithm and +planner. + +- Upped the standard serial baudrate to 115200 baud, as it is clear +that the bottleneck is the serial interface. Will now support this, as +well as the old 9600 baud, in new firmware builds. + + +---------------- +Date: 2013-10-12 +Author: Sonny Jeon +Subject: New stepper subsystem bug fixes. + +- New stepper algorithm with the new optimized planner seems to be +working nearly twice as fast as the previous algorithm. + +- For one, the planner computation overhead is probably a fraction of +what it used to be with the worst case being about half still. + +- Secondly, anytime the planner plans back to the first executing +block, it no longer overwrites the block conditions and allows it to +complete without lost steps. So no matter if the streams slows, the +protected planner should keep the steppers moving without risk of lost +steps (although this still needs to be tested thoroughly and may +audibly sound weird when this happens.) + +- It now seems that the bottleneck is the serial baudrate (which is +good!) + + +---------------- +Date: 2013-10-09 +Author: Sonny Jeon +Subject: Protected buffer works! Vast improvements to planner efficiency. Many things still broken with overhaul. + +Development push. Lots still broken. + +- Protected planner concept works! This is a critical precursor to +enabling feedrate overrides in allowing the planner buffer and the +stepper execution operate atomically. This is done through a +intermediary segment buffer. + +- Still lots of work to be done, as this was a complete overhaul of the +planner and stepper subsystems. The code can be cleaned up quite a bit, +re-enabling some of the broken features like feed holds, and finishing +up some of the concepts + +- Pushed some of the fixes from the master and edge branch to here, as +this will likely replace the edge branch when done. + + +---------------- +Date: 2013-08-25 +Author: Sonny Jeon +Subject: Merge pull request #263 from 0xPIT/master + +remove mcu argument for avr-size in makefile as it is not present in GNU... + +---------------- +Date: 2013-08-25 +Author: 0xPIT +Subject: remove mcu argument for avr-size in makefile as it is not present in GNU Binutils 2.22 + + +---------------- +Date: 2013-08-20 +Author: Sonny Jeon +Subject: Pin map definition cleanup. + + +---------------- +Date: 2013-08-19 +Author: Sonny Jeon +Subject: Processor-independent pin mapping feature. + +- Cleaned up and organized pin mapping concept by @elmom. + +- pin_map.h allows for user-supplied pin mapping and port vector +definitions in a centralized file. With more processor types, more +definitions could be added. + + +---------------- +Date: 2013-08-19 +Author: Sonny Jeon +Subject: Merge pull request #260 from elmom/master + +Thanks for the contribution! Looks good. Will update some of the semantics shortly, but the idea is solid. + +---------------- +Date: 2013-08-19 +Author: Sonny Jeon +Subject: Push old dev_2 draft to work on other things. + +- **NON-FUNCTIONAL** +- Contains an old draft of separating the stepper driver direct access +to the planner buffer. This is designed to keep the stepper and planner +modules independent and prevent overwriting or other complications. In +this way, feedrate override should be able to be installed as well. +- A number of planner optimizations are installed too. +- Not sure where the bugs are. Either in the new planner optimizations, +new stepper module updates, or in both. Or it just could be that the +Arduino AVR is choking with the new things it has to do. + + +---------------- +Date: 2013-08-19 +Author: Sonny Jeon +Subject: Merge pull request #229 from 0xPIT/patch-1 + +fix command line parameter for avr-size + +---------------- +Date: 2013-07-21 +Author: Elmo Mäntynen +Subject: Refactor config.h to allow defaults for chips/boards with different pin mappings + + +---------------- +Date: 2013-07-21 +Author: Elmo Mäntynen +Subject: Added pin mapping list to docs, useful for porting + + +---------------- +Date: 2013-07-21 +Author: Elmo Mäntynen +Subject: Make serial work with most chips by default + + +---------------- +Date: 2013-05-16 +Author: 0xPIT +Subject: fix command line parameter for avr-size + +---------------- +Date: 2013-04-05 +Author: Sonny Jeon +Subject: Updated readme + + +---------------- +Date: 2013-04-05 +Author: Sonny Jeon +Subject: Increased g-code parser line buffer. Added line overflow feedback. + +- Increased g-code parser line buffer from 50 to 70 characters. Should +fix most all issues with long arc statements, provided that they are 8 +digits(float) long only. + +- Added a line buffer overflow feedback error to let the user know when +it encounters this problem. Resets the line whenever this occurs. +(Thanks @BHSPitMonkey!) + + +---------------- +Date: 2013-04-05 +Author: Sonny Jeon +Subject: Updates to edge/dev. Line buffer increased/planner buffer decreased. Line overflow feedback. + +- Increased g-code parser line buffer to 70 characters (from 50) to +prevent some long arc commands from getting truncated. + +- Decreased planner buffer from 18 to 17 blocks to free up memory for +line buffer. + +- Added a line buffer overflow feedback error (Thanks @BHSPitMonkey!) + + +---------------- +Date: 2013-03-28 +Author: Sonny Jeon +Subject: Minor updates to code and commenting. + + +---------------- +Date: 2013-03-22 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2013-03-21 +Author: Sonny Jeon +Subject: Untested! Soft limits, max travel, homing changes, new settings. + +- WARNING: Completely untested. Will later when there is time. Settings +WILL be overwritten, as there are new settings. + +- Soft limits installed. Homing must be enabled for soft limits to work +correctly. Errors out much like a hard limit, locking out everything +and bringing up the alarm mode. Only difference is it forces a feed +hold before doing so. Position is not lost. + +- IMPORTANT: Homing had to be updated so that soft limits work better +with less CPU overhead. When homing completes, all axes are assumed to +exist in negative space. If your limit switch is other side, the homing +cycle with set this axis location to the max travel value, rather than +zero. + +- Update mc_line() to accept an array, rather than individual variables. + +- Added an mc_auto_cycle_start() function handle this feature. +Organization only. + +- + + +---------------- +Date: 2013-03-19 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2013-03-19 +Author: Sonny Jeon +Subject: G-code updates for G10 L2 and L20 + +- Updated g-codes G10 L2 and G10 L20 to the new descriptions on +linuxcnc.org + + +---------------- +Date: 2013-03-19 +Author: Sonny Jeon +Subject: G-code updates for G10 L2 and L20. + +- LinuxCNC's g-code definitions changed for G10. Updated to their +descriptions. + + +---------------- +Date: 2013-03-13 +Author: Bertus Kruger +Subject: Update planner.c + +Removed inline from all functions. + +If this is really needed is there another way that we can get +around using it? (The Arduino IDE does not recognize it)  + +---------------- +Date: 2013-03-13 +Author: Bertus Kruger +Subject: Update nuts_bolts.c + +Removed __floatunsisf and used normal casting on line 81. +This makes it compatible with the Arduino IDE. + +---------------- +Date: 2013-03-12 +Author: Sonny Jeon +Subject: Pushed minor changes. Thanks @Protoneer! + + +---------------- +Date: 2013-03-12 +Author: Sonny Jeon +Subject: Merge pull request #200 from Protoneer/master + +Fixed small bug. + +---------------- +Date: 2013-03-13 +Author: Bertus Kruger +Subject: Update gcode.c + +Removed the home_select variable. + +---------------- +Date: 2013-03-13 +Author: Bertus Kruger +Subject: Update eeprom.h + +Fixed the function signature. + +---------------- +Date: 2013-03-13 +Author: Bertus Kruger +Subject: Update eeprom.c + +Changed back + +---------------- +Date: 2013-03-12 +Author: Bertus Kruger +Subject: Update gcode.c + +home_select defined out of scope. Moved it outside the switch +so the rest of the switch can see it properly.  + +---------------- +Date: 2013-03-12 +Author: Bertus Kruger +Subject: Update eeprom.c + +Function eeprom_put_char's parameters did not align with the .h file. + +---------------- +Date: 2013-03-01 +Author: Sonny Jeon +Subject: Bug fix to-do note on soft limit checks. Not yet completed. + + +---------------- +Date: 2013-03-01 +Author: Sonny Jeon +Subject: Minor changes and added notes to soft limits routines. + +- Changed up mc_line to accept an array rather than individual x,y,z +coordinates. Makes some of the position data handling more effective, +especially for a 4th-axis later on. + +- Changed up some soft limits variable names. + + +---------------- +Date: 2013-02-26 +Author: Sonny Jeon +Subject: Merge pull request #193 from bungao/soft_limts + +integrating soft limits + +---------------- +Date: 2013-02-26 +Author: Jens Geisler +Subject: bugfix: uninitiallized curr_block->new_entry_speed_sqr lead to step loss +in some cases + +---------------- +Date: 2013-02-26 +Author: bungao +Subject: integrating soft limits + + +---------------- +Date: 2013-02-22 +Author: Sonny Jeon +Subject: Added some prelimary notes to new changes. + + +---------------- +Date: 2013-02-22 +Author: Sonny Jeon +Subject: Push additional updates from @jgeisler0303 + + +---------------- +Date: 2013-02-22 +Author: Jens Geisler +Subject: changed atomic access for updating the acceleration profile +the stepper interrupt is only halted when necessary and for the shortest +time possible (8% cycle time) + +---------------- +Date: 2013-02-20 +Author: Sonny Jeon +Subject: Merge pull request #188 from jgeisler0303/new_planner + +New planner commits merge into dev branch. + +---------------- +Date: 2013-02-20 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2013-02-20 +Author: Jens Geisler +Subject: added counter for planner steps + +---------------- +Date: 2013-02-20 +Author: Jens Geisler +Subject: implemented a mixture of Sonny's MATLAB and my previous grbl planner +ontop of the edge planner +examples run byte for byte identical old and new version + +---------------- +Date: 2013-01-18 +Author: Sonny Jeon +Subject: Merge pull request #169 from silasb/fix-execute-bit-on-files + +Removing executable bit on the files + +---------------- +Date: 2013-01-18 +Author: Sonny Jeon +Subject: Merge bug fixes from recent v0.8c push. Added readme for Grbl Sim. + + +---------------- +Date: 2013-01-18 +Author: Sonny Jeon +Subject: Merge pull request #167 from tmpvar/simulator-mac + +Fix sim makefile so it works on mac + +---------------- +Date: 2013-01-18 +Author: Elijah Insua +Subject: Fix sim makefile so it works on mac + +These changes include a path separator fix and the removal of --gc-sections which causes ld failures, and is not needed on a pc. + +This patch also changes how a compiler is selected. The makefile will now select the system compiler , which should work fine +under mingw and linux. + + +---------------- +Date: 2013-01-17 +Author: Silas Baronda +Subject: Removing executable bit on the files + + +---------------- +Date: 2013-01-17 +Author: Sonny Jeon +Subject: Merge pull request #112 from jgeisler0303/simulator + +Grbl Simulator. Oh yeah. + +---------------- +Date: 2013-01-17 +Author: Jens Geisler +Subject: relaunch ontop of latest grbl edge +code very messy but tested + +---------------- +Date: 2013-01-09 +Author: Sonny Jeon +Subject: Merge pull request #160 from daapp/edge + +Replace some constants with N_AXIS. + +---------------- +Date: 2013-01-10 +Author: Alexander Danilov +Subject: Replace some constants with N_AXIS. + + +---------------- +Date: 2013-01-06 +Author: Sonny Jeon +Subject: Fixed bug with homing and polling at the same time. Updated readme. + + +---------------- +Date: 2013-01-06 +Author: Sonny Jeon +Subject: Minor changes. + +- Changed some names up and removed a plan_reset() function that is +never used. + + +---------------- +Date: 2012-12-21 +Author: Sonny Jeon +Subject: Readme link to edge build 2012-12-21 + + +---------------- +Date: 2012-12-21 +Author: Sonny Jeon +Subject: Updated README. Max step rate back at 30kHz. Acceleration minor bug fix. + +- Returned the max step rate to 30kHz. The new arc algorithm works uses +so much less CPU overhead, because the segments are longer, that the +planner has no problem computing through them. + +- Fixed an issue with the acceleration independence scaling. Should now +work with accelerations above 400mm/sec^2 or so. + +- Updated README + + +---------------- +Date: 2012-12-19 +Author: Sonny Jeon +Subject: Arc mm_per_segment removed, now in terms of tolerance. Stepper ramp counter variable type corrected. + +- Arc mm_per_segment parameter was removed and replaced with an +arc_tolerance parameter, which scales all arc segments automatically to +radius, such that the line segment error doesn't exceed the tolerance. +Significantly improves arc performance through larger radius arc, +because the segments are much longer and the planner buffer has more to +work with. + +- Moved n_arc correction from the settings to config.h. Mathematically +this doesn't need to be a setting anymore, as the default config value +will work for all known CNC applications. The error does not accumulate +as much anymore, since the small angle approximation used by the arc +generation has been updated to a third-order approximation and how the +line segment length scale with radius and tolerance now. Left in +config.h for extraneous circumstances. + +- Corrected the st.ramp_count variable (acceleration tick counter) to a +8-bit vs. 32-bit variable. Should make the stepper algorithm just a +touch faster overall. + + +---------------- +Date: 2012-12-16 +Author: Sonny Jeon +Subject: Slow trailing steps fix. Added more defaults. + +- Fixed an issue (hopefully) with slow trailing steps after a +triangular velocity profile move. Sets the trapezoid tick cycle counter +to the correct value for an accurate reproduction of the deceleration +curve. Keeps it from arriving too early to the target position, which +causes the slow trailing steps. + +- Added Zen Toolworks 7x7 to default settings. + +- Updated readme with new edge build. + + +---------------- +Date: 2012-12-16 +Author: Sonny Jeon +Subject: Max velocity axes independence installed. Fixed intermittent slow trailing steps. Timer0 disable fix. + +- Maximum velocity for each axis is now configurable in settings. All +rapids/seek move at these maximums. All feed rates(including rapids) +may be limited and scaled down so that no axis does not exceed their +limits. + +- Moved around auto-cycle start. May change later, but mainly to ensure +the planner buffer is completely full before cycle starting a streaming +program. Otherwise it should auto-start when there is a break in the +serial stream. + +- Reverted old block->max_entry_speed_sqr calculations. Feedrate +overrides not close to ready at all. + +- Fixed intermittent slow trailing steps for some triangle velocity +profile moves. The acceleration tick counter updating was corrected to +be exact for that particular transition. Should be ok for normal +trapezoidal profiles. + +- Fixed the Timer0 disable after a step pulse falling edge. Thanks +@blinkenlight! + + +---------------- +Date: 2012-12-14 +Author: Sonny Jeon +Subject: Acceleration independence installed. Initial re-work of planner for feedrate overrides. + +NOTE: This push is a work-in-progress and there are known bugs that +need to be fixed, like homing acceleration being incompatible. Released +for testing. Settings will definitely be overwritten, as new settings +were needed. + +- Acceleration independence installed in planner. Each axis can now +have different accelerations and Grbl will maximize the accelerations +depending on the direction its moving. Very useful for users like on +the ShapeOko with vastly different Z-axis properties. + +- More planner optimizations and re-factoring. Slightly improved some +of the older calculations, but new acceleration calculations offset +these improvements. Overall no change in processing speed. + +- Removed planner nominal length checks. It was arguable whether or not +this improved planner efficiency, especially in the worst case scenario +of arcs. + +- Updated readme and changed to markdown format. + + +---------------- +Date: 2012-12-12 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2012-12-12 +Author: Sonny Jeon +Subject: Changed README to markdown + + +---------------- +Date: 2012-12-12 +Author: Sonny Jeon +Subject: Added download links to README. + + +---------------- +Date: 2012-12-12 +Author: Sonny Jeon +Subject: Moved compiled builds to different repo. + + +---------------- +Date: 2012-12-11 +Author: Sonny Jeon +Subject: Added builds folder. + +Because the Downloads section has been removed, added a builds folder +for users to download pre-compiled firmware without needing to compile +it themselves. + + +---------------- +Date: 2012-12-11 +Author: Sonny Jeon +Subject: Added builds folder. + +In light of the downloads section in Github being removed, added a +builds folder for all of the .hex files. Hopefully these won't be +removed either. + + +---------------- +Date: 2012-12-11 +Author: Sonny Jeon +Subject: Planner optimizations. + +- Improved planner execution speed by 5% or more. Re-factored most of +the calculations in terms of the square of velocity. This removed a lot +of sqrt() calculations for every planner_recalculate. + + +---------------- +Date: 2012-12-10 +Author: Sonny Jeon +Subject: (Another) Planner bug fix. + +- Oops again. Thought the new planner changes made things much better, +but there was a bug. Improvements we on the order of 20% execution time +reduction, rather than half. The increase to 30kHz Ranade timer +frequency also increased the overall overhead, so the total planner +change? Zero. But, it's still better. + + +---------------- +Date: 2012-12-10 +Author: Sonny Jeon +Subject: Planner bug fix. + +- Oops! Misplace an if-then statement. Should work as advertised now. +(Hopefully) + + +---------------- +Date: 2012-12-10 +Author: Sonny Jeon +Subject: Planner execution time halved and bug fixes. Increased step rate limit to 30kHz. + +- Planner execute speed has been more than halved from 4ms to 1.9ms +when computing a plan for a single line segment during arc generation. +This means that Grbl can now run through an arc (or complex curve) +twice as fast as before without starving the buffer. For 0.1mm arc +segments, this means about the theoretical feed rate limit is about +3000mm/min for arcs now. + +- Increased the Ranade timer frequency to 30kHz, as there doesn't seem +to be any problems with increasing the frequency. This means that the +maximum step frequency is now back at 30kHz. + +- Added Zen Toolworks 7x7 defaults. + + +---------------- +Date: 2012-12-08 +Author: Sonny Jeon +Subject: New stepper algorithm. Optimized planner. + +- Brand-new stepper algorithm. Based on the Pramod Ranade inverse time +algorithm, but modified to ensure step events are exact. Currently +limited to about 15kHz step rates, much more to be done to enable 30kHz +again. + +- Removed Timer1. Stepper algorithm now uses Timer0 and Timer2. + +- Much improved step generation during accelerations. Smoother. Allows +much higher accelerations (and speeds) than before on the same machine. + +- Cleaner algorithm that is more easily portable to other CPU types. + +- Streamlined planner calculations. Removed accelerate_until and +final_rate variables from block buffer since the new stepper algorithm +is that much more accurate. + +- Improved planner efficiency by about 15-20% during worst case +scenarios (arcs). + +- New config.h options to tune new stepper algorithm. + diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt new file mode 100644 index 000000000..49aba2cf4 --- /dev/null +++ b/doc/log/commit_log_v0.9i.txt @@ -0,0 +1,596 @@ +---------------- +Date: 2015-03-27 +Author: Sungeun Jeon +Subject: Compile-option for inverting spindle enable. + +- Installed a compile-option for inverting the spindle enable pin for +certain electronics boards users have reported needing this. + + +---------------- +Date: 2015-03-27 +Author: Sungeun Jeon +Subject: New compile options and inverse time bug fix. + +- Apparently inverse time motion were not working for quite some time. +Goes to show how many people actually use it. The calculation was bad +and is now fixed in this update. It should now work correctly. + +- `;` comment type is now supported. This is standard on LinuxCNC and +common on 3d printers. It was previously not supported due to not +existing in the NIST standard, which is out-dated. + +- New compile-option to ECHO the line received. This should help users +experiencing very weird problems and help diagnose if there is +something amiss in the communication to Grbl. + +- New compile-option to use the spindle direction pin D13 as a spindle +enable pin with PWM spindle speed on D11. This feature has been +requested often from the laser cutter community. Since spindle +direction isn’t really of much use, it seemed like good good trade. +Note that M4 spindle enable counter-clock-wise support is removed for +obvious reasons, while M3 and M5 still work. + + +---------------- +Date: 2015-03-27 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2015-03-26 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2015-03-16 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2015-03-15 +Author: Sungeun Jeon +Subject: Updated README + + +---------------- +Date: 2015-03-15 +Author: Sonny Jeon +Subject: Create README.md + +---------------- +Date: 2015-03-15 +Author: Sungeun Jeon +Subject: Merge branch 'edge' + + +---------------- +Date: 2015-03-15 +Author: Sungeun Jeon +Subject: Updated README. + +- Also altered the G38.X reporting to save some bytes. + + +---------------- +Date: 2015-03-14 +Author: Sungeun Jeon +Subject: Cleaned-up limit pin reporting and comments. + +- Cleaned up the limit pin state reporting option to display only the +state per axis, rather than the whole port. It’s organized by an XYZ +order, 0(low)-1(high), and generally looks like `Lim:001`. + +- Separated the control pin state reporting from limit state reporting +as a new compile option. This stayed the same in terms of showing the +entire port in binary, since it’s not anticipated that this will be +used much, if at all. + +- Updated some of the gcode source comments regarding supported g-codes. + + +---------------- +Date: 2015-03-07 +Author: Sonny Jeon +Subject: Another homing cycle fix. + +- The homing cycle should be working again. Reverted it back to how it +was about a month ago before I started to fiddle with it. Turns out +that my past self knew what he was doing. + + +---------------- +Date: 2015-03-04 +Author: Sonny Jeon +Subject: Arduino IDE compatibility and minor homing fixes + +- Added an include in the right spot, if a user tries to compile and +upload Grbl through the Arduino IDE with the old way. + +- Fixed a minor bug with homing max travel calculations. It was causing +simultaneous axes homing to move slow than it did before. + + +---------------- +Date: 2015-02-25 +Author: Sonny Jeon +Subject: G91.1 support. Fixed a config.h option. + +- G91.1 support added. This g-code sets the arc IJK distance mode to +incremental, which is the default already. This simply helps reduce +parsing errors with certain CAM programs that output this command. + +- Max step rate checks weren’t being compiled in if the option was +enabled. Fixed now. + +- Alarm codes were not displaying correctly when GUI reporting mode was +enabled. Due to unsigned int problem. Changed codes to positive values +since they aren’t shared with other codes. + + +---------------- +Date: 2015-02-23 +Author: Sonny Jeon +Subject: Fixed config.h to Grbl release defaults. + +- REPORT_GUI_MODE was accidentally enabled, when it shouldn’t have. + + +---------------- +Date: 2015-02-23 +Author: Sonny Jeon +Subject: New configuration options. + +- New configuration option at compile-time: + - Force alarm upon power-up or hard reset. When homing is enabled, +this is already the default behavior. This simply forces this all of +the time. + - GUI reporting mode. Removes most human-readable strings that GUIs +don’t need. This saves nearly 2KB in flash space that can be used for +other features. + - Hard limit force state check: In the hard limit pin change ISR, Grbl +by default sets the hard limit alarm upon any pin change to guarantee +the alarm is set. If this option is set, it’ll check the state within +the ISR, but can’t guarantee the pin will be read correctly if the +switch is bouncing. This option makes hard limit behavior a little less +annoying if you have a good buffered switch circuit that removes +bouncing and electronic noise. + +- Software debounce bug fix. It was reading the pin incorrectly for the +setting. + +- Re-factored some of the ‘$’ settings code. + + +---------------- +Date: 2015-02-15 +Author: Sonny Jeon +Subject: Improved homing limit search handling. + +- Instead of a single overall max travel for a search distance for the +homing limit switches. The homing cycle now applies the max travel of +each axis to the search target. Generally makes more sense this way and +saved more than a 100bytes of flash too. + + +---------------- +Date: 2015-02-15 +Author: Sonny Jeon +Subject: Homing alarm upon no switch. Licensing update. + +- Homing cycle failure reports alarm feedback when the homing cycle is +exited via a reset, interrupted by a safety door switch, or does not +find the limit switch. + +- Homing cycle bug fix when not finding the limit switch. It would just +idle before, but now will exit with an alarm. + +- Licensing update. Corrected licensing according to lawyer +recommendations. Removed references to other Grbl versions. + + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Merge pull request #593 from poelstra/fix_makefile_deps + +Fix generating header dependencies, merge with 'normal' compile, force r... + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Updated README with new logo sized for github. + + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Doc re-org. New Grbl Logos! + + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Merge pull request #591 from EliteEng/edge + +Safety Door Update for Mega2560 + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Merge pull request #592 from poelstra/fix_softlimit + +Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error. + +---------------- +Date: 2015-02-13 +Author: Sonny Jeon +Subject: Merge pull request #594 from poelstra/fix_sim_build + +Fix function signature of print_uint32_base10(), necessary for compiling simulator. + +---------------- +Date: 2015-02-13 +Author: Martin Poelstra +Subject: Fix function signature of print_uint32_base10(), necessary for compiling simulator. + + +---------------- +Date: 2015-02-13 +Author: Martin Poelstra +Subject: Fix generating header dependencies, merge with 'normal' compile, force recompile when files are removed. + + +---------------- +Date: 2015-02-13 +Author: Martin Poelstra +Subject: Fix EXEC_ALARM_* flags: soft limit would lead to hard limit error. + + +---------------- +Date: 2015-02-13 +Author: Rob Brown +Subject: Safety Door Update for Mega2560 + + +---------------- +Date: 2015-02-11 +Author: Sonny Jeon +Subject: Overhauled state machine. New safety door feature. + +- Overhauled the state machine and cleaned up its overall operation. +This involved creating a new ‘suspend’ state for what all external +commands, except real-time commands, are ignored. All hold type states +enter this suspend state. + +- Removed ‘auto cycle start’ setting from Grbl. This was not used by +users in its intended way and is somewhat redundant, as GUI manage the +cycle start by streaming. It also muddled up how Grbl should interpret +how and when to execute a g-code block. Removing it made everything +much much simpler. + +- Fixed a program pause bug when used with other buffer_sync commands. + +- New safety door feature for OEMs. Immediately forces a feed hold and +then de-energizes the machine. Resuming is blocked until the door is +closed. When it is, it re-energizes the system and then resumes on the +normal toolpath. + +- Safety door input pin is optional and uses the feed hold pin on A1. +Enabled by config.h define. + +- Spindle and coolant re-energizing upon a safety door resume has a +programmable delay time to allow for complete spin up to rpm and +turning on the coolant before resuming motion. + +- Safety door-style feed holds can be used instead of regular feed hold +(doesn’t de-energize the machine) with a ‘@‘ character. If the safety +door input pin is not enabled, the system can be resumed at any time. + + +---------------- +Date: 2015-02-10 +Author: Sonny Jeon +Subject: Git fix for empty directory. Makefile updated. + +- ‘build’ directory was not being synced by git because it was empty. +Added a .gitignore file in the ‘build’ directory to force git to sync +it but keep it empty. + +- Updated the Makefile to not erase the .gitignore. + + +---------------- +Date: 2015-02-10 +Author: Sonny Jeon +Subject: File re-organization. New Makefile. + +- Re-organized source code files into a ‘grbl’ directory to lessen one +step in compiling Grbl through the Arduino IDE. + +- Added an ‘examples’ directory with an upload .INO sketch to further +simplify compiling and uploading Grbl via the Arduino IDE. + +- Updated the Makefile with regard to the source code no longer being +in the root directory. All files generated by compiling is placed in a +separate ‘build’ directory to keep things tidy. The makefile should +operate in the same way as it did before. + + +---------------- +Date: 2015-02-10 +Author: Sonny Jeon +Subject: Bug fix for certain motions. Re-org of includes. + +- Critical bug fix for diagonal motions that continue on the same +direction or return in the exact opposite direction. This issue could +cause Grbl to crash intermittently due to a numerical round-off error. +Grbl versions prior to v0.9g shouldn’t have this issue. + +- Reorganized all of the includes used by Grbl. Centralized it into a +single “grbl.h” include. This will help simplify the compiling and +uploading process through the Arduino IDE. + +- Added an example .INO file for users to simply open and run when +compiling and uploading through the IDE. More to come later. + + +---------------- +Date: 2015-02-06 +Author: Sonny Jeon +Subject: Limit/control pin state reporting option + +- As a setup feature, users can compile-in input pin status reporting. +Doesn’t do anything special, just prints the binary for the port. 0’s +and 1’s indicate low and high signals on the pins. It’s a bit cryptic +right now, but it’s just a start. + +- Added a max step rate check when writing step/mm and max rate +settings. Should help avoid people misdiagnosing problems associated +with going over the 30kHz step rate limit. Right now not enabled. Takes +up over 100k of flash. Need that room for other things right now. + + +---------------- +Date: 2015-02-04 +Author: Sonny Jeon +Subject: Rare planner bug fix and added simulator defaults. + +- Planner bug when moving along a diagonal back and forth on the same +path. Rare for the fact that most CAM programs don’t program this type +of motion, neither does jogging. Fixed in this update. + +- Added grbl_sim defaults for testing purposes. + + +---------------- +Date: 2015-01-17 +Author: Sonny Jeon +Subject: Fully configurable pins for NO or NC switches. + +- All pins, which include limits, control command, and probe pins, can +now all be configured to trigger as active-low or active-high and +whether the pin has its internal pull-up resistor enabled. This should +allow for just about all types of NO and NC switch configurations. + +- The probe pin invert setting hasn’t been added to the Grbl settings, +like the others, and will have to wait until v1.0. But for now, it’s +available as a compile-time option in config.h. + +- Fixed a variable spindle bug. + + +---------------- +Date: 2015-01-14 +Author: Sonny Jeon +Subject: Lot of refactoring for the future. CoreXY support. + +- Rudimentary CoreXY kinematics support. Didn’t test, but homing and +feed holds should work. See config.h. Please report successes and +issues as we find bugs. + +- G40 (disable cutter comp) is now “supported”. Meaning that Grbl will +no longer issue an error when typically sent in g-code program header. + +- Refactored coolant and spindle state setting into separate functions +for future features. + +- Configuration option for fixing homing behavior when there are two +limit switches on the same axis sharing an input pin. + +- Created a new “grbl.h” that will eventually be used as the main +include file for Grbl. Also will help simply uploading through the +Arduino IDE + +- Separated out the alarms execution flags from the realtime (used be +called runtime) execution flag variable. Now reports exactly what +caused the alarm. Expandable for new alarms later on. + +- Refactored the homing cycle to support CoreXY. + +- Applied @EliteEng updates to Mega2560 support. Some pins were +reconfigured. + +- Created a central step to position and vice versa function. Needed +for non-traditional cartesian machines. Should make it easier later. + +- Removed the new CPU map for the Uno. No longer going to used. There +will be only one configuration to keep things uniform. + + +---------------- +Date: 2014-11-05 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-10-29 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-10-28 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-10-28 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2014-10-01 +Author: Sonny Jeon +Subject: Updated variable spindle and new probing. Minor bug fixes. + +- Minor bug fix for variable spindle PWM output. Values smaller than +the minimum RPM for the spindle would overflow the PWM value. Thanks +Rob! + +- Created an optional minimum spindle PWM low-mark value as a +compile-time option. This is for special circumstances when the PWM has +to be at a certain level to be read by the spindle controller. + +- Refactored the new probing commands (G38.3, G38.4, G38.5) code to +work better with the rest of Grbl’s systems. + +- Refactored mc_probe() and mc_arc() to accept the mode of the command, +i.e. clockwise vs counter, toward vs away, etc. This is to make these +functions independent of gcode state variables. + +- Removed the pull off motion in the probing cycle. This is not an +official operation and was added for user simplicity, but wrongly did +so. So bye bye. + +- Created a configure probe invert mask function to handle the +different probe pin setting and probing cycle modes with a single mask. + + - Minor bug fix with reporting motion modes via $G. G38.2 wasn’t +showing up. It now does, along with the other new probing commands. + +- Refactored some of the new pin configurations for the future of Grbl. + +- + + +---------------- +Date: 2014-09-25 +Author: Sonny Jeon +Subject: Merge pull request #491 from tmpvar/G38.2+ + +G38.2+ + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: report probe_succeeded with probe status + + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: add probe_finalize to keep things DRY + +this allows the PRB report to be valid when in "no errors" mode and the probe fails + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: hop over probe pull-off sequence after probe miss + +and while "no errors" is enabled (G38.3, G38.5) + + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: add/install probe_errors_enabled in mc_probe_cycle + + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: bump mantissa to uint16_t to enable G38.5 + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: test only for & PROBE_ACTIVE + + +---------------- +Date: 2014-09-22 +Author: Elijah Insua +Subject: cleanup global var and push probe mode into probe_get_state + + +---------------- +Date: 2014-09-20 +Author: Sonny Jeon +Subject: Edit hard limit check at start of homing cycle + + +---------------- +Date: 2014-09-20 +Author: Sonny Jeon +Subject: Merge pull request #494 from ashelly/homing-alarm + +Alarm if limits engaged on homing start. + +---------------- +Date: 2014-09-20 +Author: Sonny Jeon +Subject: Merge pull request #493 from alpharesearch/edge + +If variable spindle is defined print S value via $G command. + +---------------- +Date: 2014-09-20 +Author: Sonny Jeon +Subject: Minor settings number overflow bug fix. + +- The `x` in `$x=val` would overflow when a value larger than 255 was +entered and passed to Grbl. This resulted with unintended parameters +being set by the overflow value. To fix, simply check for values larger +than 255 and error out. + + +---------------- +Date: 2014-09-17 +Author: ashelly +Subject: No false alarm if other bits in port are set. + +---------------- +Date: 2014-09-17 +Author: Markus Schulz +Subject: If variable spindle is defined print S value via $G command. + + +---------------- +Date: 2014-09-14 +Author: Elijah Insua +Subject: utilize MOTION_MODE_PROBE_NO_ERROR + + +---------------- +Date: 2014-09-14 +Author: Elijah Insua +Subject: install G38.{3,4,5} + + +---------------- +Date: 2014-09-14 +Author: Elijah Insua +Subject: add MOTION_MODE_PROBE_NO_ERROR + + +---------------- +Date: 2014-09-08 +Author: ashelly +Subject: Alarm if limits engaged on homing + diff --git a/doc/media/COPYING b/doc/media/COPYING new file mode 100644 index 000000000..ee26e1938 --- /dev/null +++ b/doc/media/COPYING @@ -0,0 +1,2 @@ + +Copyright (c) 2015 Gnea Research LLC. All Rights Reserved. diff --git a/doc/logo/Grbl Logo 150px.png b/doc/media/Grbl Logo 150px.png similarity index 100% rename from doc/logo/Grbl Logo 150px.png rename to doc/media/Grbl Logo 150px.png diff --git a/doc/logo/Grbl Logo 250px.png b/doc/media/Grbl Logo 250px.png similarity index 100% rename from doc/logo/Grbl Logo 250px.png rename to doc/media/Grbl Logo 250px.png diff --git a/doc/logo/Grbl Logo 320px.png b/doc/media/Grbl Logo 320px.png similarity index 100% rename from doc/logo/Grbl Logo 320px.png rename to doc/media/Grbl Logo 320px.png diff --git a/doc/logo/Grbl Logo 640px.png b/doc/media/Grbl Logo 640px.png similarity index 100% rename from doc/logo/Grbl Logo 640px.png rename to doc/media/Grbl Logo 640px.png diff --git a/doc/logo/Grbl Logo.pdf b/doc/media/Grbl Logo.pdf similarity index 100% rename from doc/logo/Grbl Logo.pdf rename to doc/media/Grbl Logo.pdf diff --git a/doc/logo/Grbl Logo.svg b/doc/media/Grbl Logo.svg similarity index 100% rename from doc/logo/Grbl Logo.svg rename to doc/media/Grbl Logo.svg diff --git a/grbl/config.h b/grbl/config.h index d45b2607e..878b34127 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -294,6 +294,16 @@ // bogged down by too many trig calculations. #define N_ARC_CORRECTION 12 // Integer (1-255) +// The arc G2/3 g-code standard is problematic by definition. Radius-based arcs have horrible numerical +// errors when arc at semi-circles(pi) or full-circles(2*pi). Offset-based arcs are much more accurate +// but still have a problem when arcs are full-circles (2*pi). This define accounts for the floating +// point issues when offset-based arcs are commanded as full circles, but get interpreted as extremely +// small arcs with around machine epsilon (1.2e-7rad) due to numerical round-off and precision issues. +// This define value sets the machine epsilon cutoff to determine if the arc is a full-circle or not. +// NOTE: Be very careful when adjusting this value. It should always be greater than 1.2e-7 but not too +// much greater than this. The default setting should capture most, if not all, full arc error situations. +#define ARC_ANGULAR_TRAVEL_EPSILON 5E-7 // Float (radians) + // Time delay increments performed during a dwell. The default value is set at 50ms, which provides // a maximum time delay of roughly 55 minutes, more than enough for most any application. Increasing // this delay will increase the maximum dwell time linearly, but also reduces the responsiveness of @@ -369,9 +379,9 @@ // Force Grbl to check the state of the hard limit switches when the processor detects a pin // change inside the hard limit ISR routine. By default, Grbl will trigger the hard limits // alarm upon any pin change, since bouncing switches can cause a state check like this to -// misread the pin. When hard limits are triggers, this should be 100% reliable, which is the +// misread the pin. When hard limits are triggered, they should be 100% reliable, which is the // reason that this option is disabled by default. Only if your system/electronics can guarantee -// the pins don't bounce, we recommend enabling this option. If so, this will help prevent +// that the switches don't bounce, we recommend enabling this option. This will help prevent // triggering a hard limit when the machine disengages from the switch. // NOTE: This option has no effect if SOFTWARE_DEBOUNCE is enabled. // #define HARD_LIMIT_FORCE_STATE_CHECK // Default disabled. Uncomment to enable. diff --git a/grbl/grbl.h b/grbl/grbl.h index c12769e33..cc7765d6f 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150327" +#define GRBL_VERSION_BUILD "20150329" // Define standard libraries used by Grbl. #include diff --git a/grbl/motion_control.c b/grbl/motion_control.c index bfd42d7b0..ad10a742e 100644 --- a/grbl/motion_control.c +++ b/grbl/motion_control.c @@ -100,9 +100,9 @@ // CCW angle between position and target from circle center. Only one atan2() trig computation required. float angular_travel = atan2(r_axis0*rt_axis1-r_axis1*rt_axis0, r_axis0*rt_axis0+r_axis1*rt_axis1); if (is_clockwise_arc) { // Correct atan2 output per direction - if (angular_travel >= 0) { angular_travel -= 2*M_PI; } + if (angular_travel >= -ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel -= 2*M_PI; } } else { - if (angular_travel <= 0) { angular_travel += 2*M_PI; } + if (angular_travel <= ARC_ANGULAR_TRAVEL_EPSILON) { angular_travel += 2*M_PI; } } // NOTE: Segment end points are on the arc, which can lead to the arc diameter being smaller by up to From f5e7436a0284047dcf372ecd5ee963780874d0da Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sun, 29 Mar 2015 20:33:51 -0600 Subject: [PATCH 49/74] Fix for limit pin reporting compile-option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The limit pin reporting wasn’t working correctly due to calling the wrong similarly-named function. Verified to be working now. --- grbl/report.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grbl/report.c b/grbl/report.c index 001c02de3..ed27e51b3 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -496,8 +496,8 @@ void report_realtime_status() printPgmString(PSTR(",Lim:")); uint8_t idx; for (idx=0; idx Date: Sun, 17 May 2015 13:25:36 -0600 Subject: [PATCH 50/74] Critical M0/2/30 fix. Homing updates. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Critical fix for M0 program pause. Due to its recent change, it would cause Grbl to suspend but wouldn’t notify the user of why Grbl was not doing anything. The state would show IDLE and a cycle start would resume it. Grbl now enters a HOLD state to better indicate the state change. - Critical fix for M2 and M30 program end. As with M0, the state previously would show IDLE while suspended. Grbl now does not suspend upon program end and leaves job control to the GUI. Grbl simply reports a `[Pgm End]` as a feedback message and resets certain g-code modes. - M2/30 g-code reseting fix. Previously Grbl would soft-reset after an M2/30, but this was not complaint to the (linuxcnc) g-code standard. It simply resets [G1,G17,G90,G94,G40,G54,M5,M9,M48] and keeps all other modes the same. - M0/M2/M30 check-mode fix. It now does not suspend the machine during check-mode. - Minor bug fix related to commands similar to G90.1, but not G90.1, not reporting an unsupported command. - Homing cycle refactoring. To help reduce the chance of users misunderstanding their limit switch wiring, Grbl only moves a short distance for the locate cycles only. In addition, the homing cycle pulls-off the limit switch by the pull-off distance to re-engage and locate home. This should improve its accuracy. - HOMING_FORCE_ORIGIN now sets the origin to the pull-off location, rather than where the limit switch was triggered. - Updated default junction deviation to 0.01mm. Recent tests showed that this improves Grbl’s cornering behavior a bit. - Added the ShapeOko3 defaults. - Added new feedback message `[Pgm End]` for M2/30 notification. - Limit pin reporting is now a $10 status report option. Requested by OEMs to help simplify support troubleshooting. --- doc/log/commit_log_v0.9i.txt | 26 ++++++ grbl/config.h | 2 +- grbl/defaults.h | 53 ++++++++--- grbl/gcode.c | 45 +++++++--- grbl/grbl.h | 2 +- grbl/limits.c | 168 ++++++++++++++++------------------- grbl/report.c | 29 +++--- grbl/report.h | 1 + grbl/settings.h | 1 + grbl/stepper.c | 5 +- grbl/system.h | 2 +- 11 files changed, 202 insertions(+), 132 deletions(-) diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 49aba2cf4..db7df6216 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,29 @@ +---------------- +Date: 2015-03-29 +Author: Sonny Jeon +Subject: Fix for limit pin reporting compile-option + +- The limit pin reporting wasn’t working correctly due to calling the +wrong similarly-named function. Verified to be working now. + + +---------------- +Date: 2015-03-29 +Author: Sonny Jeon +Subject: Commit history, logo license, full-arc fix. + +- Commit history added to repo, as an easier way for people to see view +the changes over time. + +- Grbl logo copyright license added. All rights reserved with regards +to the Grbl logo. + +- G2/3 full circles would sometime not execute. The problem was due to +numerical round-off of a trig calculation. Added a machine epsilon +define to help detect and correct for this problem. Tested and should +not effect general operation of arcs. + + ---------------- Date: 2015-03-27 Author: Sungeun Jeon diff --git a/grbl/config.h b/grbl/config.h index 878b34127..3375e5caa 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -79,7 +79,7 @@ // 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_LOCATE_CYCLE 2 // Integer (1-128) +#define N_HOMING_LOCATE_CYCLE 1 // Integer (1-128) // After homing, Grbl will set by default the entire machine space into negative space, as is typical // for professional CNC machines, regardless of where the limit switches are located. Uncomment this diff --git a/grbl/defaults.h b/grbl/defaults.h index f21b31e24..41bcf0ff5 100644 --- a/grbl/defaults.h +++ b/grbl/defaults.h @@ -49,7 +49,6 @@ #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm #define DEFAULT_ARC_TOLERANCE 0.002 // mm #define DEFAULT_REPORT_INCHES 0 // false - #define DEFAULT_AUTO_START 1 // true #define DEFAULT_INVERT_ST_ENABLE 0 // false #define DEFAULT_INVERT_LIMIT_PINS 0 // false #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false @@ -87,10 +86,9 @@ #define DEFAULT_DIRECTION_INVERT_MASK ((1< diff --git a/grbl/limits.c b/grbl/limits.c index 83d93d9bb..4df6f1e2d 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -22,9 +22,13 @@ #include "grbl.h" -// Homing axis search distance multiplier. Computed by this value times the axis max travel. -#define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. - +// Homing axis search distance multiplier. Computed by this value times the cycle travel. +#ifndef HOMING_AXIS_SEARCH_SCALAR + #define HOMING_AXIS_SEARCH_SCALAR 1.5 // Must be > 1 to ensure limit switch will be engaged. +#endif +#ifndef HOMING_AXIS_LOCATE_SCALAR + #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. +#endif void limits_init() { @@ -126,16 +130,12 @@ void limits_go_home(uint8_t cycle_mask) { if (sys.abort) { return; } // Block if system reset has been issued. - // Initialize homing in search mode to quickly engage the specified cycle_mask limit switches. - bool approach = true; - float homing_rate = settings.homing_seek_rate; - uint8_t invert_pin, idx; + // Initialize uint8_t n_cycle = (2*N_HOMING_LOCATE_CYCLE+1); - float target[N_AXIS]; - uint8_t limit_pin[N_AXIS], step_pin[N_AXIS]; - + float target[N_AXIS]; float max_travel = 0.0; + uint8_t idx; for (idx=0; idx 0); @@ -242,13 +260,16 @@ void limits_go_home(uint8_t cycle_mask) for (idx=0; idx 0.0) { - for (idx=0; idxstep_event_count >> 1); - st.counter_y = st.counter_x; - st.counter_z = st.counter_x; + st.counter_x = st.counter_y = st.counter_z = (st.exec_block->step_event_count >> 1); } - st.dir_outbits = st.exec_block->direction_bits ^ dir_port_invert_mask; #ifdef ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING diff --git a/grbl/system.h b/grbl/system.h index a74f02915..94f2143e5 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -71,7 +71,7 @@ typedef struct { uint8_t abort; // System abort flag. Forces exit back to main loop for reset. uint8_t state; // Tracks the current state of Grbl. - uint8_t suspend; // System suspend flag. Allows only realtime commands. Used primarily for holds. + uint8_t suspend; // System suspend bitflag variable that manages holds, cancels, and safety door. volatile uint8_t rt_exec_state; // Global realtime executor bitflag variable for state management. See EXEC bitmasks. volatile uint8_t rt_exec_alarm; // Global realtime executor bitflag variable for setting various alarms. From 25cdeb830b5e52d90ae9e34aa4696be58338c193 Mon Sep 17 00:00:00 2001 From: ashelly Date: Fri, 22 May 2015 10:24:48 -0400 Subject: [PATCH 51/74] Splitting Cpu map into separate files. Makes comparison, addition of new ones easier --- grbl/cpu_map.h | 228 +------------------------------------- grbl/cpu_map_atmega2560.h | 114 +++++++++++++++++++ grbl/cpu_map_atmega328p.h | 122 ++++++++++++++++++++ 3 files changed, 241 insertions(+), 223 deletions(-) create mode 100644 grbl/cpu_map_atmega2560.h create mode 100644 grbl/cpu_map_atmega328p.h diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 872e0bfcd..8623fdc36 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -33,121 +33,7 @@ #ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. - // Define serial port pins and interrupt vectors. - #define SERIAL_RX USART_RX_vect - #define SERIAL_UDRE USART_UDRE_vect - - // Define step pulse output pins. NOTE: All step bit pins must be on the same port. - #define STEP_DDR DDRD - #define STEP_PORT PORTD - #define X_STEP_BIT 2 // Uno Digital Pin 2 - #define Y_STEP_BIT 3 // Uno Digital Pin 3 - #define Z_STEP_BIT 4 // Uno Digital Pin 4 - #define STEP_MASK ((1< Date: Fri, 22 May 2015 10:48:25 -0400 Subject: [PATCH 52/74] Fixing up comment blocks in headers --- grbl/cpu_map.h | 5 +++-- grbl/cpu_map_atmega2560.h | 22 ++++++++++++++++++++++ grbl/cpu_map_atmega328p.h | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 8623fdc36..1781795d6 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -18,8 +18,9 @@ along with Grbl. If not, see . */ -/* The cpu_map.h file serves as a central pin mapping settings file for different processor - types, i.e. AVR 328p or AVR Mega 2560. Grbl officially supports the Arduino Uno, but the +/* The cpu_map.h file serves as a central pin mapping selection file for different processor + types, i.e. AVR 328p or AVR Mega 2560. Each processor has its own pin mapping file. + (i.e. cpu_map_atmega328p.h) Grbl officially supports the Arduino Uno, but the other supplied pin mappings are supplied by users, so your results may vary. */ // NOTE: This is still a work in progress. We are still centralizing the configurations to diff --git a/grbl/cpu_map_atmega2560.h b/grbl/cpu_map_atmega2560.h index 1c1ef399a..b8a0aa2ae 100644 --- a/grbl/cpu_map_atmega2560.h +++ b/grbl/cpu_map_atmega2560.h @@ -1,3 +1,25 @@ +/* + cpu_map_atmega2560.h - CPU and pin mapping configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* This cpu_map file serves as a central pin mapping settings file for AVR Mega 2560 */ + #ifdef GRBL_PLATFORM #error "cpu_map already defined: GRBL_PLATFORM=" GRBL_PLATFORM #endif diff --git a/grbl/cpu_map_atmega328p.h b/grbl/cpu_map_atmega328p.h index 5d38011c0..8bb071dd4 100644 --- a/grbl/cpu_map_atmega328p.h +++ b/grbl/cpu_map_atmega328p.h @@ -1,3 +1,27 @@ +/* + cpu_map_atmega328p.h - CPU and pin mapping configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* This cpu_map file serves as a central pin mapping settings file for AVR 328p + used on the Arduino Uno */ + + #ifdef GRBL_PLATFORM #error "cpu_map already defined: GRBL_PLATFORM=" GRBL_PLATFORM #endif From b58e8455c94649ccc58f35093f167b9324a2d238 Mon Sep 17 00:00:00 2001 From: ashelly Date: Fri, 22 May 2015 10:26:46 -0400 Subject: [PATCH 53/74] Moving defaults to individual files in subdirectory --- grbl/defaults.h | 288 ++------------------- grbl/defaults/defaults_generic.h | 63 +++++ grbl/defaults/defaults_oxcnc.h | 64 +++++ grbl/defaults/defaults_shapeoko.h | 71 +++++ grbl/defaults/defaults_shapeoko2.h | 70 +++++ grbl/defaults/defaults_shapeoko3.h | 68 +++++ grbl/defaults/defaults_sherline.h | 67 +++++ grbl/defaults/defaults_simulator.h | 64 +++++ grbl/defaults/defaults_zen_toolworks_7x7.h | 69 +++++ 9 files changed, 551 insertions(+), 273 deletions(-) create mode 100644 grbl/defaults/defaults_generic.h create mode 100644 grbl/defaults/defaults_oxcnc.h create mode 100644 grbl/defaults/defaults_shapeoko.h create mode 100644 grbl/defaults/defaults_shapeoko2.h create mode 100644 grbl/defaults/defaults_shapeoko3.h create mode 100644 grbl/defaults/defaults_sherline.h create mode 100644 grbl/defaults/defaults_simulator.h create mode 100644 grbl/defaults/defaults_zen_toolworks_7x7.h diff --git a/grbl/defaults.h b/grbl/defaults.h index 41bcf0ff5..e66b17038 100644 --- a/grbl/defaults.h +++ b/grbl/defaults.h @@ -18,318 +18,60 @@ along with Grbl. If not, see . */ -/* The defaults.h file serves as a central default settings file for different machine - types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings - here are supplied by users, so your results may vary. However, this should give you - a good starting point as you get to know your machine and tweak the settings for your - our nefarious needs. */ +/* The defaults.h file serves as a central default settings selector for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + files listed here are supplied by users, so your results may vary. However, this should + give you a good starting point as you get to know your machine and tweak the settings for + your nefarious needs. + Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */ #ifndef defaults_h -#define defaults_h +// Don't #define defaults_h here, let the selected file do it. Prevents incuding more than one. #ifdef DEFAULTS_GENERIC // Grbl generic default settings. Should work across different machines. - #define DEFAULT_X_STEPS_PER_MM 250.0 - #define DEFAULT_Y_STEPS_PER_MM 250.0 - #define DEFAULT_Z_STEPS_PER_MM 250.0 - #define DEFAULT_X_MAX_RATE 500.0 // mm/min - #define DEFAULT_Y_MAX_RATE 500.0 // mm/min - #define DEFAULT_Z_MAX_RATE 500.0 // mm/min - #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 - #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 - #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 - #define DEFAULT_X_MAX_TRAVEL 200.0 // mm - #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm - #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm - #define DEFAULT_STEP_PULSE_MICROSECONDS 10 - #define DEFAULT_STEPPING_INVERT_MASK 0 - #define DEFAULT_DIRECTION_INVERT_MASK 0 - #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) - #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) - #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm - #define DEFAULT_ARC_TOLERANCE 0.002 // mm - #define DEFAULT_REPORT_INCHES 0 // false - #define DEFAULT_INVERT_ST_ENABLE 0 // false - #define DEFAULT_INVERT_LIMIT_PINS 0 // false - #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false - #define DEFAULT_HARD_LIMIT_ENABLE 0 // false - #define DEFAULT_HOMING_ENABLE 0 // false - #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir - #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min - #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min - #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) - #define DEFAULT_HOMING_PULLOFF 1.0 // mm + #include "defaults/defaults_generic.h" #endif - - #ifdef DEFAULTS_SHERLINE_5400 // Description: Sherline 5400 mill with three NEMA 23 Keling KL23H256-21-8B 185 oz-in stepper motors, // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding. - #define MICROSTEPS 2 - #define STEPS_PER_REV 200.0 - #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew - #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) - #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) - #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) - #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm) - #define DEFAULT_Y_MAX_RATE 635.0 // mm/min - #define DEFAULT_Z_MAX_RATE 635.0 // mm/min - #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 - #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 - #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 - #define DEFAULT_X_MAX_TRAVEL 225.0 // mm - #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm - #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm - #define DEFAULT_STEP_PULSE_MICROSECONDS 10 - #define DEFAULT_STEPPING_INVERT_MASK 0 - #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 250.0 + #define DEFAULT_Y_STEPS_PER_MM 250.0 + #define DEFAULT_Z_STEPS_PER_MM 250.0 + #define DEFAULT_X_MAX_RATE 500.0 // mm/min + #define DEFAULT_Y_MAX_RATE 500.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 200.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) + #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_AUTO_START 1 // true + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm + +#endif diff --git a/grbl/defaults/defaults_oxcnc.h b/grbl/defaults/defaults_oxcnc.h new file mode 100644 index 000000000..4e7d56f93 --- /dev/null +++ b/grbl/defaults/defaults_oxcnc.h @@ -0,0 +1,64 @@ +/* + defaults_oxcnc.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Grbl settings for OpenBuilds OX CNC Machine + // http://www.openbuilds.com/builds/openbuilds-ox-cnc-machine.341/ + #define DEFAULT_X_STEPS_PER_MM 26.670 + #define DEFAULT_Y_STEPS_PER_MM 26.670 + #define DEFAULT_Z_STEPS_PER_MM 50 + #define DEFAULT_X_MAX_RATE 500.0 // mm/min + #define DEFAULT_Y_MAX_RATE 500.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (10.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 500.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 750.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) + #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_AUTO_START 1 // true + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm + +#endif diff --git a/grbl/defaults/defaults_shapeoko.h b/grbl/defaults/defaults_shapeoko.h new file mode 100644 index 000000000..aaa9834ed --- /dev/null +++ b/grbl/defaults/defaults_shapeoko.h @@ -0,0 +1,71 @@ +/* + defaults_shapeoko.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + + // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos + // grblShield with a 24V, 4.2A power supply. + #define MICROSTEPS_XY 8 + #define STEP_REVS_XY 400 + #define MM_PER_REV_XY (0.08*18*MM_PER_INCH) // 0.08 in belt pitch, 18 pulley teeth + #define MICROSTEPS_Z 2 + #define STEP_REVS_Z 400 + #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z) + #define DEFAULT_X_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min + #define DEFAULT_X_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (15.0*60*60) // 15*60*60 mm/min^2 = 15 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 200.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 200.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 200.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: Shapeoko CNC mill with three NEMA 17 stepper motors, driven by Synthetos + // grblShield at 28V. + #define MICROSTEPS_XY 8 + #define STEP_REVS_XY 200 + #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth + #define MICROSTEPS_Z 2 + #define STEP_REVS_Z 200 + #define MM_PER_REV_Z 1.250 // 1.25 mm/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z) + #define DEFAULT_X_MAX_RATE 5000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (250.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 290.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: Shapeoko CNC mill with three NEMA 23 stepper motors, driven by CarbideMotion + #define MICROSTEPS_XY 8 + #define STEP_REVS_XY 200 + #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth + #define MICROSTEPS_Z 8 + #define STEP_REVS_Z 200 + #define MM_PER_REV_Z (2.0*20) // 2mm belt pitch, 20 pulley teeth + #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z) + #define DEFAULT_X_MAX_RATE 5000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 5000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 5000.0 // mm/min + #define DEFAULT_X_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (400.0*60*60) // 400*60*60 mm/min^2 = 400 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 425.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 465.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 80.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: Sherline 5400 mill with three NEMA 23 Keling KL23H256-21-8B 185 oz-in stepper motors, + // driven by three Pololu A4988 stepper drivers with a 30V, 6A power supply at 1.5A per winding. + #define MICROSTEPS 2 + #define STEPS_PER_REV 200.0 + #define MM_PER_REV (0.050*MM_PER_INCH) // 0.050 inch/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_X_MAX_RATE 635.0 // mm/min (25 ipm) + #define DEFAULT_Y_MAX_RATE 635.0 // mm/min + #define DEFAULT_Z_MAX_RATE 635.0 // mm/min + #define DEFAULT_X_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 50*60*60 mm/min^2 = 50 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 225.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 125.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 170.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Settings only for Grbl Simulator (www.github.com/grbl/grbl-sim) + // Grbl generic default settings. Should work across different machines. + #define DEFAULT_X_STEPS_PER_MM 1000.0 + #define DEFAULT_Y_STEPS_PER_MM 1000.0 + #define DEFAULT_Z_STEPS_PER_MM 1000.0 + #define DEFAULT_X_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 1000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 1000.0 // mm/min + #define DEFAULT_X_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (100.0*60*60) // 10*60*60 mm/min^2 = 10 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 1000.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK 0 + #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-254, 255 keeps steppers enabled) + #define DEFAULT_STATUS_REPORT_MASK ((BITFLAG_RT_STATUS_MACHINE_POSITION)|(BITFLAG_RT_STATUS_WORK_POSITION)) + #define DEFAULT_JUNCTION_DEVIATION 0.02 // mm + #define DEFAULT_ARC_TOLERANCE 0.002 // mm + #define DEFAULT_REPORT_INCHES 0 // false + #define DEFAULT_AUTO_START 1 // true + #define DEFAULT_INVERT_ST_ENABLE 0 // false + #define DEFAULT_INVERT_LIMIT_PINS 0 // false + #define DEFAULT_SOFT_LIMIT_ENABLE 0 // false + #define DEFAULT_HARD_LIMIT_ENABLE 0 // false + #define DEFAULT_HOMING_ENABLE 0 // false + #define DEFAULT_HOMING_DIR_MASK 0 // move positive dir + #define DEFAULT_HOMING_FEED_RATE 25.0 // mm/min + #define DEFAULT_HOMING_SEEK_RATE 500.0 // mm/min + #define DEFAULT_HOMING_DEBOUNCE_DELAY 250 // msec (0-65k) + #define DEFAULT_HOMING_PULLOFF 1.0 // mm + +#endif diff --git a/grbl/defaults/defaults_zen_toolworks_7x7.h b/grbl/defaults/defaults_zen_toolworks_7x7.h new file mode 100644 index 000000000..a6e87876a --- /dev/null +++ b/grbl/defaults/defaults_zen_toolworks_7x7.h @@ -0,0 +1,69 @@ +/* + defaults_zen_toolworks_7x7.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: Zen Toolworks 7x7 mill with three Shinano SST43D2121 65oz-in NEMA 17 stepper motors. + // Leadscrew is different from some ZTW kits, where most are 1.25mm/rev rather than 8.0mm/rev here. + // Driven by 30V, 6A power supply and TI DRV8811 stepper motor drivers. + #define MICROSTEPS 8 + #define STEPS_PER_REV 200.0 + #define MM_PER_REV 8.0 // 8 mm/rev leadscrew + #define DEFAULT_X_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Y_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_Z_STEPS_PER_MM (STEPS_PER_REV*MICROSTEPS/MM_PER_REV) + #define DEFAULT_X_MAX_RATE 6000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 6000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 6000.0 // mm/min + #define DEFAULT_X_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (600.0*60*60) // 600*60*60 mm/min^2 = 600 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 190.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 180.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 150.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1< Date: Sat, 23 May 2015 11:57:30 -0600 Subject: [PATCH 54/74] Homing and limit updates. Minor bug fixes. - Updated new homing cycle to error out when a pull-off motion detects the limit is still active. - Created a limits_get_state() function to centralize it. It reports state as a bit-wise booleans according to axis numbering. - Updated the print uint8 functions. Generalized it to allow both base2 and base10 printouts, while allowing base2 prints with N_AXIS digits for limit state status reports. Doing this saved about 100bytes of flash as well. - Applied CoreXY status reporting bug fix by @phd0. Thanks! --- doc/log/commit_log_v0.9i.txt | 81 ++++++++++++++++++++++++++++++++++++ grbl/defaults.h | 4 +- grbl/grbl.h | 2 +- grbl/limits.c | 60 ++++++++++++++++---------- grbl/limits.h | 4 ++ grbl/motion_control.c | 6 +-- grbl/print.c | 67 +++++++++++++++-------------- grbl/print.h | 5 +++ grbl/report.c | 5 +-- grbl/system.c | 4 +- 10 files changed, 170 insertions(+), 68 deletions(-) diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index db7df6216..de40f6895 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,84 @@ +---------------- +Date: 2015-05-22 +Author: Sonny Jeon +Subject: Merge pull request #702 from ashelly/default-split + +Moving defaults to individual files in subdirectory + +---------------- +Date: 2015-05-22 +Author: ashelly +Subject: Moving defaults to individual files in subdirectory + + +---------------- +Date: 2015-05-22 +Author: Sonny Jeon +Subject: Merge pull request #700 from ashelly/header-split + +Header split + +---------------- +Date: 2015-05-22 +Author: ashelly +Subject: Fixing up comment blocks in headers + + +---------------- +Date: 2015-05-22 +Author: ashelly +Subject: Splitting Cpu map into separate files. + +Makes comparison, addition of new ones easier + + +---------------- +Date: 2015-05-17 +Author: Sonny Jeon +Subject: Critical M0/2/30 fix. Homing updates. + +- Critical fix for M0 program pause. Due to its recent change, it would +cause Grbl to suspend but wouldn’t notify the user of why Grbl was not +doing anything. The state would show IDLE and a cycle start would +resume it. Grbl now enters a HOLD state to better indicate the state +change. + +- Critical fix for M2 and M30 program end. As with M0, the state +previously would show IDLE while suspended. Grbl now does not suspend +upon program end and leaves job control to the GUI. Grbl simply reports +a `[Pgm End]` as a feedback message and resets certain g-code modes. + +- M2/30 g-code reseting fix. Previously Grbl would soft-reset after an +M2/30, but this was not complaint to the (linuxcnc) g-code standard. It +simply resets [G1,G17,G90,G94,G40,G54,M5,M9,M48] and keeps all other +modes the same. + +- M0/M2/M30 check-mode fix. It now does not suspend the machine during +check-mode. + +- Minor bug fix related to commands similar to G90.1, but not G90.1, +not reporting an unsupported command. + +- Homing cycle refactoring. To help reduce the chance of users +misunderstanding their limit switch wiring, Grbl only moves a short +distance for the locate cycles only. In addition, the homing cycle +pulls-off the limit switch by the pull-off distance to re-engage and +locate home. This should improve its accuracy. + +- HOMING_FORCE_ORIGIN now sets the origin to the pull-off location, +rather than where the limit switch was triggered. + +- Updated default junction deviation to 0.01mm. Recent tests showed +that this improves Grbl’s cornering behavior a bit. + +- Added the ShapeOko3 defaults. + +- Added new feedback message `[Pgm End]` for M2/30 notification. + +- Limit pin reporting is now a $10 status report option. Requested by +OEMs to help simplify support troubleshooting. + + ---------------- Date: 2015-03-29 Author: Sonny Jeon diff --git a/grbl/defaults.h b/grbl/defaults.h index e66b17038..ae8c725b0 100644 --- a/grbl/defaults.h +++ b/grbl/defaults.h @@ -26,7 +26,9 @@ Ensure one and only one of these DEFAULTS_XXX values is defined in config.h */ #ifndef defaults_h -// Don't #define defaults_h here, let the selected file do it. Prevents incuding more than one. + +// Only define the DEFAULT_XXX with where to find the corresponding default_XXX.h file. +// Don't #define defaults_h here, let the selected file do it. Prevents including more than one. #ifdef DEFAULTS_GENERIC // Grbl generic default settings. Should work across different machines. diff --git a/grbl/grbl.h b/grbl/grbl.h index eb361d0b4..00c3ba43e 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150516" +#define GRBL_VERSION_BUILD "20150523" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 4df6f1e2d..65869d189 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -55,6 +55,7 @@ void limits_init() } +// Disables hard limits. void limits_disable() { LIMIT_PCMSK &= ~LIMIT_MASK; // Disable specific pins of the Pin Change Interrupt @@ -62,6 +63,24 @@ void limits_disable() } +// Returns limit state as a bit-wise uint8 variable. Each bit indicates an axis limit, where +// triggered is 1 and not triggered is 0. Invert mask is applied. Axes are defined by their +// number in bit position, i.e. Z_AXIS is (1<<2) or bit 2, and Y_AXIS is (1<<1) or bit 1. +uint8_t limits_get_state() +{ + uint8_t limit_state = 0; + uint8_t pin = (LIMIT_PIN & LIMIT_MASK); + if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { pin ^= LIMIT_MASK; } + if (pin) { + uint8_t idx; + for (idx=0; idx 0); - + // The active cycle axes should now be homed and machine limits have been located. By // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, @@ -289,9 +304,8 @@ void limits_go_home(uint8_t cycle_mask) } } plan_sync_position(); // Sync planner position to homed machine position. - - // Set system state to homing before returning. - sys.state = STATE_HOMING; + + // sys.state = STATE_HOMING; // Ensure system state set as homing before returning. } diff --git a/grbl/limits.h b/grbl/limits.h index 0a5084a95..74512ceb8 100644 --- a/grbl/limits.h +++ b/grbl/limits.h @@ -26,8 +26,12 @@ // Initialize the limits module void limits_init(); +// Disables hard limits. void limits_disable(); +// Returns limit state as a bit-wise uint8 variable. +uint8_t limits_get_state(); + // Perform one portion of the homing cycle based on the input settings. void limits_go_home(uint8_t cycle_mask); diff --git a/grbl/motion_control.c b/grbl/motion_control.c index ad10a742e..07852006e 100644 --- a/grbl/motion_control.c +++ b/grbl/motion_control.c @@ -225,9 +225,7 @@ void mc_homing_cycle() // with machines with limits wired on both ends of travel to one limit pin. // TODO: Move the pin-specific LIMIT_PIN call to limits.c as a function. #ifdef LIMITS_TWO_SWITCHES_ON_AXES - uint8_t limit_state = (LIMIT_PIN & LIMIT_MASK); - if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { limit_state ^= LIMIT_MASK; } - if (limit_state) { + if (limits_get_state()) { mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); return; @@ -256,7 +254,7 @@ void mc_homing_cycle() // Gcode parser position was circumvented by the limits_go_home() routine, so sync position now. gc_sync_position(); - + // If hard limits feature enabled, re-enable hard limits pin change register after homing cycle. limits_init(); } diff --git a/grbl/print.c b/grbl/print.c index 1dd8d7bca..f029c4ff0 100644 --- a/grbl/print.c +++ b/grbl/print.c @@ -60,38 +60,36 @@ void printPgmString(const char *s) // } -void print_uint8_base2(uint8_t n) +// Prints an uint8 variable with base and number of desired digits. +void print_unsigned_int8(uint8_t n, uint8_t base, uint8_t digits) { - unsigned char buf[8]; - uint8_t i = 0; + unsigned char buf[digits]; + uint8_t i = 0; - for (; i < 8; i++) { - buf[i] = n & 1; - n >>= 1; - } + for (; i < digits; i++) { + buf[i] = n % base ; + n /= base; + } - for (; i > 0; i--) - serial_write('0' + buf[i - 1]); + for (; i > 0; i--) + serial_write('0' + buf[i - 1]); } -void print_uint8_base10(uint8_t n) -{ - if (n == 0) { - serial_write('0'); - return; - } - - unsigned char buf[3]; - uint8_t i = 0; +// Prints an uint8 variable in base 2. +void print_uint8_base2(uint8_t n) { + print_unsigned_int8(n,2,8); +} - while (n > 0) { - buf[i++] = n % 10 + '0'; - n /= 10; - } - for (; i > 0; i--) - serial_write(buf[i - 1]); +// Prints an uint8 variable in base 10. +void print_uint8_base10(uint8_t n) +{ + uint8_t digits; + if (n < 10) { digits = 1; } + else if (n < 100) { digits = 2; } + else { digits = 3; } + print_unsigned_int8(n,10,digits); } @@ -119,7 +117,7 @@ void printInteger(long n) { if (n < 0) { serial_write('-'); - print_uint32_base10((-n)); + print_uint32_base10(-n); } else { print_uint32_base10(n); } @@ -194,12 +192,13 @@ void printFloat_RateValue(float n) { void printFloat_SettingValue(float n) { printFloat(n,N_DECIMAL_SETTINGVALUE); } -// Debug tool to print free memory in bytes at the called point. Not used otherwise. -void printFreeMemory() -{ - extern int __heap_start, *__brkval; - uint16_t free; // Up to 64k values. - free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); - printInteger((int32_t)free); - printString(" "); -} +// Debug tool to print free memory in bytes at the called point. +// NOTE: Keep commented unless using. Part of this function always gets compiled in. +// void printFreeMemory() +// { +// extern int __heap_start, *__brkval; +// uint16_t free; // Up to 64k values. +// free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +// printInteger((int32_t)free); +// printString(" "); +// } diff --git a/grbl/print.h b/grbl/print.h index 658e892fc..e6399aa9d 100644 --- a/grbl/print.h +++ b/grbl/print.h @@ -31,8 +31,13 @@ void printInteger(long n); void print_uint32_base10(uint32_t n); +// Prints uint8 variable with base and number of desired digits. +void print_unsigned_int8(uint8_t n, uint8_t base, uint8_t digits); + +// Prints an uint8 variable in base 2. void print_uint8_base2(uint8_t n); +// Prints an uint8 variable in base 10. void print_uint8_base10(uint8_t n); void printFloat(float n, uint8_t decimal_places); diff --git a/grbl/report.c b/grbl/report.c index f32203aa1..09ff1b839 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -496,10 +496,7 @@ void report_realtime_status() if (bit_istrue(settings.status_report_mask,BITFLAG_RT_STATUS_LIMIT_PINS)) { printPgmString(PSTR(",Lim:")); - for (idx=0; idx Date: Sat, 23 May 2015 12:43:52 -0600 Subject: [PATCH 55/74] Moved cpu_map. - Moved cpu_map files to a cpu_map directory, like the defaults file organization. --- {grbl => Grbl/cpu_map}/cpu_map_atmega2560.h | 3 ++- {grbl => Grbl/cpu_map}/cpu_map_atmega328p.h | 10 ++++---- doc/log/commit_log_v0.9i.txt | 19 +++++++++++++++ grbl/cpu_map.h | 27 ++++++--------------- 4 files changed, 33 insertions(+), 26 deletions(-) rename {grbl => Grbl/cpu_map}/cpu_map_atmega2560.h (99%) rename {grbl => Grbl/cpu_map}/cpu_map_atmega328p.h (96%) diff --git a/grbl/cpu_map_atmega2560.h b/Grbl/cpu_map/cpu_map_atmega2560.h similarity index 99% rename from grbl/cpu_map_atmega2560.h rename to Grbl/cpu_map/cpu_map_atmega2560.h index b8a0aa2ae..8c2cebc0a 100644 --- a/grbl/cpu_map_atmega2560.h +++ b/Grbl/cpu_map/cpu_map_atmega2560.h @@ -20,10 +20,12 @@ /* This cpu_map file serves as a central pin mapping settings file for AVR Mega 2560 */ + #ifdef GRBL_PLATFORM #error "cpu_map already defined: GRBL_PLATFORM=" GRBL_PLATFORM #endif + #define GRBL_PLATFORM "Atmega2560" // Serial port pins @@ -133,4 +135,3 @@ #define SPINDLE_PWM_PORT PORTH #define SPINDLE_PWM_BIT 4 // MEGA2560 Digital Pin 97 #endif // End of VARIABLE_SPINDLE - diff --git a/grbl/cpu_map_atmega328p.h b/Grbl/cpu_map/cpu_map_atmega328p.h similarity index 96% rename from grbl/cpu_map_atmega328p.h rename to Grbl/cpu_map/cpu_map_atmega328p.h index 8bb071dd4..ea233f9a7 100644 --- a/grbl/cpu_map_atmega328p.h +++ b/Grbl/cpu_map/cpu_map_atmega328p.h @@ -18,16 +18,17 @@ along with Grbl. If not, see . */ -/* This cpu_map file serves as a central pin mapping settings file for AVR 328p - used on the Arduino Uno */ - - +/* Grbl officially supports the Arduino Uno, but the other supplied pin mappings are + supplied by users, so your results may vary. This cpu_map file serves as a central + pin mapping settings file for AVR 328p used on the Arduino Uno. */ + #ifdef GRBL_PLATFORM #error "cpu_map already defined: GRBL_PLATFORM=" GRBL_PLATFORM #endif #define GRBL_PLATFORM "Atmega328p" + // Define serial port pins and interrupt vectors. #define SERIAL_RX USART_RX_vect #define SERIAL_UDRE USART_UDRE_vect @@ -143,4 +144,3 @@ #define SPINDLE_PWM_PORT PORTB #define SPINDLE_PWM_BIT 3 // Uno Digital Pin 11 #endif // End of VARIABLE_SPINDLE - diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index de40f6895..4cd5b9777 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,22 @@ +---------------- +Date: 2015-05-23 +Author: Sonny Jeon +Subject: Homing and limit updates. Minor bug fixes. + +- Updated new homing cycle to error out when a pull-off motion detects +the limit is still active. + +- Created a limits_get_state() function to centralize it. It reports +state as a bit-wise booleans according to axis numbering. + +- Updated the print uint8 functions. Generalized it to allow both base2 +and base10 printouts, while allowing base2 prints with N_AXIS digits +for limit state status reports. Doing this saved about 100bytes of +flash as well. + +- Applied CoreXY status reporting bug fix by @phd0. Thanks! + + ---------------- Date: 2015-05-22 Author: Sonny Jeon diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 1781795d6..1804d2506 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -18,43 +18,30 @@ along with Grbl. If not, see . */ -/* The cpu_map.h file serves as a central pin mapping selection file for different processor +/* The cpu_map.h files serve as a central pin mapping selection file for different processor types, i.e. AVR 328p or AVR Mega 2560. Each processor has its own pin mapping file. (i.e. cpu_map_atmega328p.h) Grbl officially supports the Arduino Uno, but the other supplied pin mappings are supplied by users, so your results may vary. */ -// NOTE: This is still a work in progress. We are still centralizing the configurations to -// this file, so your success may vary for other CPUs. +// NOTE: With new processors, only add the define name and filename to use. #ifndef cpu_map_h #define cpu_map_h -//---------------------------------------------------------------------------------------- - #ifdef CPU_MAP_ATMEGA328P // (Arduino Uno) Officially supported by Grbl. - - #include "cpu_map_atmega328p.h" - + #include "cpu_map/cpu_map_atmega328p.h" #endif - -//---------------------------------------------------------------------------------------- - #ifdef CPU_MAP_ATMEGA2560 // (Arduino Mega 2560) Working @EliteEng - - #include "cpu_map_atmega2560.h" - + #include "cpu_map/cpu_map_atmega2560.h" #endif -//---------------------------------------------------------------------------------------- - /* #ifdef CPU_MAP_CUSTOM_PROC - // For a custom pin map or different processor, copy and edit ne of the default cpu map - // files above and modify it to your needs. Then, copy and paste one of the sections above - // and change the #defined name and included file. Make sure the defined name is also - // changed in the config.h file. + // For a custom pin map or different processor, copy and edit one of the available cpu + // map files and modify it to your needs. Make sure the defined name is also changed in + // the config.h file. #endif */ From 0eb8bca3d9920ae7a08ace6f9fdceec432617620 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 23 May 2015 16:40:20 -0600 Subject: [PATCH 56/74] CoreXY planner bug fix. - CoreXY motions were moving to the negative value of the intended target. Now fixed. --- grbl/planner.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grbl/planner.c b/grbl/planner.c index 7989e004b..1e0bd3551 100644 --- a/grbl/planner.c +++ b/grbl/planner.c @@ -277,8 +277,8 @@ uint8_t plan_check_full_buffer() #ifdef COREXY target_steps[A_MOTOR] = lround(target[A_MOTOR]*settings.steps_per_mm[A_MOTOR]); target_steps[B_MOTOR] = lround(target[B_MOTOR]*settings.steps_per_mm[B_MOTOR]); - block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS])); - block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + block->steps[A_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS])); + block->steps[B_MOTOR] = labs((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS])); #endif for (idx=0; idxstep_event_count = max(block->step_event_count, block->steps[idx]); if (idx == A_MOTOR) { - delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; - } else if (idx == B_MOTOR) { delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) + (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; + } else if (idx == B_MOTOR) { + delta_mm = ((target_steps[X_AXIS]-pl.position[X_AXIS]) - (target_steps[Y_AXIS]-pl.position[Y_AXIS]))/settings.steps_per_mm[idx]; } else { delta_mm = (target_steps[idx] - pl.position[idx])/settings.steps_per_mm[idx]; } From 8a84f8987d629bc8f44dcfdcb448e0531dc77e9e Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Tue, 26 May 2015 10:49:37 -0600 Subject: [PATCH 57/74] Updated README --- README.md | 10 ++++++---- grbl/config.h | 7 ------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index aab14fdb4..053c0ddea 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,11 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-03-29)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-03-29)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-05-23)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-05-23)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). + - Homing cycle updated. Located based on switch trigger, rather than release point. - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. _**Archives:**_ @@ -46,15 +47,16 @@ _**Archives:**_ *** -##Update Summary for v0.9i from v0.9h +##Update Summary for v0.9i - **IMPORTANT:** - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!** + - **Homing cycle updated. Locates based on trigger point, rather than release point.** - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - - **Additional Compile-Time Feature Options:** Limit/control pin state reporting, force power-up alarm state, GUI reporting mode, and more. + - **Additional Compile-Time Feature Options:** Control pin state reporting, force power-up alarm state, GUI reporting mode, and more. ##Update Summary for v0.9h from v0.8 - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600)** diff --git a/grbl/config.h b/grbl/config.h index 3375e5caa..955cdee4e 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -163,13 +163,6 @@ // uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below. // #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable. -// Enable limit pin states feedback in status reports. The data is presented as 0 (low) or 1(high), -// where the order is XYZ. For example, if the Y- and Z-limit pins are active, Grbl will include the -// following string in the status report "Lim:011". This is generally useful for setting up a new -// CNC machine, but we do not recommend keeping this option enabled, as it will consume CPU resources -// with little to no benefit during normal operation and it may not be supported by most GUIs. -// #define REPORT_LIMIT_PIN_STATE // Default disabled. Uncomment to enable. - // Enable control pin states feedback in status reports. The data is presented as simple binary of // the control pin port (0 (low) or 1(high)), masked to show only the input pins. Non-control pins on the // port will always show a 0 value. See cpu_map.h for the pin bitmap. As with the limit pin reporting, From 558e1a2dfc554e6ede75a578f524b05a365e0077 Mon Sep 17 00:00:00 2001 From: Michel Pollet Date: Wed, 27 May 2015 14:05:47 +0100 Subject: [PATCH 58/74] Rename Grbl to grbl Otherwise compilation fails on linux, or other case sensitive systems Signed-off-by: Michel Pollet --- {Grbl => grbl}/cpu_map/cpu_map_atmega2560.h | 0 {Grbl => grbl}/cpu_map/cpu_map_atmega328p.h | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {Grbl => grbl}/cpu_map/cpu_map_atmega2560.h (100%) rename {Grbl => grbl}/cpu_map/cpu_map_atmega328p.h (100%) diff --git a/Grbl/cpu_map/cpu_map_atmega2560.h b/grbl/cpu_map/cpu_map_atmega2560.h similarity index 100% rename from Grbl/cpu_map/cpu_map_atmega2560.h rename to grbl/cpu_map/cpu_map_atmega2560.h diff --git a/Grbl/cpu_map/cpu_map_atmega328p.h b/grbl/cpu_map/cpu_map_atmega328p.h similarity index 100% rename from Grbl/cpu_map/cpu_map_atmega328p.h rename to grbl/cpu_map/cpu_map_atmega328p.h From d0919142c53c9bdd8e44c69292262ca5fce02ae6 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 27 May 2015 08:19:22 -0600 Subject: [PATCH 59/74] Added X-Carve defaults. - Added X-Carve 500mm and 1000mm default files. - Tweaked all default files. Removed obsolete AUTO_START and updated some JUNCTION_DEVIATION defaults after testing showed these needed to be reduced slightly. --- Grbl/defaults/defaults_x_carve_1000mm.h | 69 ++++++++++++++++++++++ Grbl/defaults/defaults_x_carve_500mm.h | 69 ++++++++++++++++++++++ grbl/defaults.h | 12 ++++ grbl/defaults/defaults_generic.h | 3 +- grbl/defaults/defaults_oxcnc.h | 1 - grbl/defaults/defaults_shapeoko.h | 3 +- grbl/defaults/defaults_shapeoko2.h | 3 +- grbl/defaults/defaults_sherline.h | 3 +- grbl/defaults/defaults_simulator.h | 3 +- grbl/defaults/defaults_zen_toolworks_7x7.h | 1 - 10 files changed, 155 insertions(+), 12 deletions(-) create mode 100644 Grbl/defaults/defaults_x_carve_1000mm.h create mode 100644 Grbl/defaults/defaults_x_carve_500mm.h diff --git a/Grbl/defaults/defaults_x_carve_1000mm.h b/Grbl/defaults/defaults_x_carve_1000mm.h new file mode 100644 index 000000000..e07a23f27 --- /dev/null +++ b/Grbl/defaults/defaults_x_carve_1000mm.h @@ -0,0 +1,69 @@ +/* + defaults_x_carve_1000mm.h - defaults settings configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos + // grblShield at 24V. + #define MICROSTEPS_XY 8 + #define STEP_REVS_XY 200 + #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth + #define MICROSTEPS_Z 2 + #define STEP_REVS_Z 200 + #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew + #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z) + #define DEFAULT_X_MAX_RATE 8000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 740.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 790.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1<. +*/ + +/* The defaults.h file serves as a central default settings file for different machine + types, from DIY CNC mills to CNC conversions of off-the-shelf machines. The settings + here are supplied by users, so your results may vary. However, this should give you + a good starting point as you get to know your machine and tweak the settings for your + nefarious needs. */ + +#ifndef defaults_h +#define defaults_h + + // Description: X-Carve 3D Carver CNC mill with three 200 step/rev motors driven by Synthetos + // grblShield at 24V. + #define MICROSTEPS_XY 8 + #define STEP_REVS_XY 200 + #define MM_PER_REV_XY (2.0*20) // 2mm belt pitch, 20 pulley teeth + #define MICROSTEPS_Z 2 + #define STEP_REVS_Z 200 + #define MM_PER_REV_Z 2.117 // ACME 3/8-12 Leadscrew + #define DEFAULT_X_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Y_STEPS_PER_MM (MICROSTEPS_XY*STEP_REVS_XY/MM_PER_REV_XY) + #define DEFAULT_Z_STEPS_PER_MM (MICROSTEPS_Z*STEP_REVS_Z/MM_PER_REV_Z) + #define DEFAULT_X_MAX_RATE 8000.0 // mm/min + #define DEFAULT_Y_MAX_RATE 8000.0 // mm/min + #define DEFAULT_Z_MAX_RATE 500.0 // mm/min + #define DEFAULT_X_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Y_ACCELERATION (500.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_Z_ACCELERATION (50.0*60*60) // 25*60*60 mm/min^2 = 25 mm/sec^2 + #define DEFAULT_X_MAX_TRAVEL 290.0 // mm + #define DEFAULT_Y_MAX_TRAVEL 290.0 // mm + #define DEFAULT_Z_MAX_TRAVEL 100.0 // mm + #define DEFAULT_STEP_PULSE_MICROSECONDS 10 + #define DEFAULT_STEPPING_INVERT_MASK 0 + #define DEFAULT_DIRECTION_INVERT_MASK ((1< Date: Wed, 27 May 2015 08:32:24 -0600 Subject: [PATCH 60/74] Another git case-sensitive folder fix. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - I’m now officially annoyed. --- {Grbl => grbl}/defaults/defaults_x_carve_1000mm.h | 1 + {Grbl => grbl}/defaults/defaults_x_carve_500mm.h | 1 + 2 files changed, 2 insertions(+) rename {Grbl => grbl}/defaults/defaults_x_carve_1000mm.h (99%) rename {Grbl => grbl}/defaults/defaults_x_carve_500mm.h (99%) diff --git a/Grbl/defaults/defaults_x_carve_1000mm.h b/grbl/defaults/defaults_x_carve_1000mm.h similarity index 99% rename from Grbl/defaults/defaults_x_carve_1000mm.h rename to grbl/defaults/defaults_x_carve_1000mm.h index e07a23f27..f88e5ad12 100644 --- a/Grbl/defaults/defaults_x_carve_1000mm.h +++ b/grbl/defaults/defaults_x_carve_1000mm.h @@ -67,3 +67,4 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #endif + \ No newline at end of file diff --git a/Grbl/defaults/defaults_x_carve_500mm.h b/grbl/defaults/defaults_x_carve_500mm.h similarity index 99% rename from Grbl/defaults/defaults_x_carve_500mm.h rename to grbl/defaults/defaults_x_carve_500mm.h index f7d21c988..ee572eae8 100644 --- a/Grbl/defaults/defaults_x_carve_500mm.h +++ b/grbl/defaults/defaults_x_carve_500mm.h @@ -67,3 +67,4 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #endif + \ No newline at end of file From e14cff3ddcf04bfd0502b47fd7b521991deca0b5 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 29 May 2015 21:32:45 -0600 Subject: [PATCH 61/74] Added G61 exact path support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - G61 exact path is the Grbl default path control mode, so it’s now added as a supported g-code. --- README.md | 7 ++-- doc/log/commit_log_v0.9i.txt | 68 ++++++++++++++++++++++++++++++++++++ grbl/gcode.c | 14 +++++--- grbl/gcode.h | 25 +++++++------ grbl/grbl.h | 2 +- 5 files changed, 98 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 053c0ddea..3984d9c41 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-05-23)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-05-23)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-05-29)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-05-29)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. @@ -52,7 +52,7 @@ _**Archives:**_ - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!** - **Homing cycle updated. Locates based on trigger point, rather than release point.** - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** - - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. + - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. G61 exact path mode. - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. @@ -91,6 +91,7 @@ List of Supported G-Codes in Grbl v0.9i Master: - Tool Length Offset Modes: G43.1, G49 - Cutter Compensation Modes: G40 - Coordinate System Modes: G54, G55, G56, G57, G58, G59 + - Control Modes: G61 - Program Flow: M0, M1, M2, M30* - Coolant Control: M7*, M8, M9 - Spindle Control: M3, M4, M5 diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 4cd5b9777..98655e1ef 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,71 @@ +---------------- +Date: 2015-05-27 +Author: Sonny Jeon +Subject: Another git case-sensitive folder fix. + +- I’m now officially annoyed. + + +---------------- +Date: 2015-05-27 +Author: Sonny Jeon +Subject: Added X-Carve defaults. + +- Added X-Carve 500mm and 1000mm default files. + +- Tweaked all default files. Removed obsolete AUTO_START and updated +some JUNCTION_DEVIATION defaults after testing showed these needed to +be reduced slightly. + + +---------------- +Date: 2015-05-27 +Author: Sonny Jeon +Subject: Merge pull request #710 from buserror/fix-directory-case-sensitivity + +Rename Grbl to grbl + +---------------- +Date: 2015-05-27 +Author: Michel Pollet +Subject: Rename Grbl to grbl + +Otherwise compilation fails on linux, or other case sensitive systems + +Signed-off-by: Michel Pollet + + +---------------- +Date: 2015-05-26 +Author: Sonny Jeon +Subject: Updated README + + +---------------- +Date: 2015-05-26 +Author: Sonny Jeon +Subject: Merge pull request #706 from grbl/edge + +Merge edge branch. + +---------------- +Date: 2015-05-23 +Author: Sonny Jeon +Subject: CoreXY planner bug fix. + +- CoreXY motions were moving to the negative value of the intended +target. Now fixed. + + +---------------- +Date: 2015-05-23 +Author: Sonny Jeon +Subject: Moved cpu_map. + +- Moved cpu_map files to a cpu_map directory, like the defaults file +organization. + + ---------------- Date: 2015-05-23 Author: Sonny Jeon diff --git a/grbl/gcode.c b/grbl/gcode.c index b3093a8a1..c47808e50 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -259,6 +259,11 @@ uint8_t gc_execute_line(char *line) word_bit = MODAL_GROUP_G12; gc_block.modal.coord_select = int_value-54; // Shift to array indexing. break; + case 61: + word_bit = MODAL_GROUP_G13; + if (mantissa != 0) { FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); } // [G61.1 not supported] + // gc_block.modal.control = CONTROL_MODE_EXACT_PATH; // G61 + break; default: FAIL(STATUS_GCODE_UNSUPPORTED_COMMAND); // [Unsupported G command] } if (mantissa > 0) { FAIL(STATUS_GCODE_COMMAND_VALUE_NOT_INTEGER); } // [Unsupported or invalid Gxx.x command] @@ -519,8 +524,8 @@ uint8_t gc_execute_line(char *line) } } - // [16. Set path control mode ]: NOT SUPPORTED. - // [17. Set distance mode ]: N/A. G90.1 and G91.1 NOT SUPPORTED. + // [16. Set path control mode ]: N/A. Only G61. G61.1 and G64 NOT SUPPORTED. + // [17. Set distance mode ]: N/A. Only G91.1. G90.1 NOT SUPPORTED. // [18. Set retract mode ]: NOT SUPPORTED. // [19. Remaining non-modal actions ]: Check go to predefined position, set G10, or set axis offsets. @@ -900,7 +905,8 @@ uint8_t gc_execute_line(char *line) memcpy(gc_state.coord_system,coordinate_data,sizeof(coordinate_data)); } - // [16. Set path control mode ]: NOT SUPPORTED + // [16. Set path control mode ]: G61.1/G64 NOT SUPPORTED + // gc_state.modal.control = gc_block.modal.control; // NOTE: Always default. // [17. Set distance mode ]: gc_state.modal.distance = gc_block.modal.distance; @@ -1089,5 +1095,5 @@ uint8_t gc_execute_line(char *line) group 8 = {*M7} enable mist coolant (* Compile-option) group 9 = {M48, M49} enable/disable feed and speed override switches group 10 = {G98, G99} return mode canned cycles - group 13 = {G61, G61.1, G64} path control mode + group 13 = {G61.1, G64} path control mode (G61 is supported) */ diff --git a/grbl/gcode.h b/grbl/gcode.h index 10d4792a4..9a289aff4 100644 --- a/grbl/gcode.h +++ b/grbl/gcode.h @@ -39,14 +39,15 @@ #define MODAL_GROUP_G7 7 // [G40] Cutter radius compensation mode. G41/42 NOT SUPPORTED. #define MODAL_GROUP_G8 8 // [G43.1,G49] Tool length offset #define MODAL_GROUP_G12 9 // [G54,G55,G56,G57,G58,G59] Coordinate system selection +#define MODAL_GROUP_G13 10 // [G61] Control mode -#define MODAL_GROUP_M4 10 // [M0,M1,M2,M30] Stopping -#define MODAL_GROUP_M7 11 // [M3,M4,M5] Spindle turning -#define MODAL_GROUP_M8 12 // [M7,M8,M9] Coolant control +#define MODAL_GROUP_M4 11 // [M0,M1,M2,M30] Stopping +#define MODAL_GROUP_M7 12 // [M3,M4,M5] Spindle turning +#define MODAL_GROUP_M8 13 // [M7,M8,M9] Coolant control -#define OTHER_INPUT_F 12 -#define OTHER_INPUT_S 13 -#define OTHER_INPUT_T 14 +// #define OTHER_INPUT_F 14 +// #define OTHER_INPUT_S 15 +// #define OTHER_INPUT_T 16 // Define command actions for within execution-type modal groups (motion, stopping, non-modal). Used // internally by the parser to know which command to execute. @@ -102,6 +103,9 @@ // Modal Group G7: Cutter radius compensation mode #define CUTTER_COMP_DISABLE 0 // G40 (Default: Must be zero) +// Modal Group G13: Control mode +#define CONTROL_MODE_EXACT_PATH 0 // G61 (Default: Must be zero) + // Modal Group M7: Spindle control #define SPINDLE_DISABLE 0 // M5 (Default: Must be zero) #define SPINDLE_ENABLE_CW 1 // M3 @@ -119,6 +123,8 @@ // Modal Group G12: Active work coordinate system // N/A: Stores coordinate system value (54-59) to change to. + +// Define parameter word mapping. #define WORD_F 0 #define WORD_I 1 #define WORD_J 2 @@ -134,19 +140,18 @@ #define WORD_Z 12 - - // NOTE: When this struct is zeroed, the above defines set the defaults for the system. typedef struct { uint8_t motion; // {G0,G1,G2,G3,G38.2,G80} uint8_t feed_rate; // {G93,G94} uint8_t units; // {G20,G21} uint8_t distance; // {G90,G91} - // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only one supported. + // uint8_t distance_arc; // {G91.1} NOTE: Don't track. Only default supported. uint8_t plane_select; // {G17,G18,G19} - // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only one supported. + // uint8_t cutter_comp; // {G40} NOTE: Don't track. Only default supported. uint8_t tool_length; // {G43.1,G49} uint8_t coord_select; // {G54,G55,G56,G57,G58,G59} + // uint8_t control; // {G61} NOTE: Don't track. Only default supported. uint8_t program_flow; // {M0,M1,M2,M30} uint8_t coolant; // {M7,M8,M9} uint8_t spindle; // {M3,M4,M5} diff --git a/grbl/grbl.h b/grbl/grbl.h index 00c3ba43e..e8c2789e3 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150523" +#define GRBL_VERSION_BUILD "20150529" // Define standard libraries used by Grbl. #include From 185de028361969e165df82620659711186d07279 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 18 Jun 2015 09:23:17 -0600 Subject: [PATCH 62/74] Added restore settings defaults command. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New restore setting defaults command. Only wipes ‘$$’ setting in EEPROM and reloads them based on the defaults used when Grbl was compiled. Used with a `$RST` command NOTE: `$RST` is intentionally not listed in the Grbl ‘$’ help message. --- Makefile | 2 +- doc/log/commit_log_v0.9i.txt | 9 +++++++++ grbl/grbl.h | 2 +- grbl/report.c | 2 ++ grbl/report.h | 1 + grbl/settings.h | 2 +- grbl/system.c | 9 ++++++++- 7 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 79fb3bf0d..be87bfeb5 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ FUSES = -U hfuse:w:0xd2:m -U lfuse:w:0xff:m # Tune the lines below only if you know what you are doing: AVRDUDE = avrdude $(PROGRAMMER) -p $(DEVICE) -B 10 -F -COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I. -ffunction-sections +COMPILE = avr-gcc -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -I. -ffunction-sections -fdata-sections OBJECTS = $(addprefix $(BUILDDIR)/,$(notdir $(SOURCE:.c=.o))) diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 98655e1ef..f10079f91 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,12 @@ +---------------- +Date: 2015-05-29 +Author: Sonny Jeon +Subject: Added G61 exact path support. + +- G61 exact path is the Grbl default path control mode, so it’s now +added as a supported g-code. + + ---------------- Date: 2015-05-27 Author: Sonny Jeon diff --git a/grbl/grbl.h b/grbl/grbl.h index e8c2789e3..073a571d7 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150529" +#define GRBL_VERSION_BUILD "20150618" // Define standard libraries used by Grbl. #include diff --git a/grbl/report.c b/grbl/report.c index 09ff1b839..86782bcb2 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -138,6 +138,8 @@ void report_feedback_message(uint8_t message_code) printPgmString(PSTR("Check Door")); break; case MESSAGE_PROGRAM_END: printPgmString(PSTR("Pgm End")); break; + case MESSAGE_RESTORE_DEFAULTS: + printPgmString(PSTR("Restoring defaults")); break; } printPgmString(PSTR("]\r\n")); } diff --git a/grbl/report.h b/grbl/report.h index 71260857a..69a1d8318 100644 --- a/grbl/report.h +++ b/grbl/report.h @@ -69,6 +69,7 @@ #define MESSAGE_DISABLED 5 #define MESSAGE_SAFETY_DOOR_AJAR 6 #define MESSAGE_PROGRAM_END 7 +#define MESSAGE_RESTORE_DEFAULTS 8 // Prints system status messages. void report_status_message(uint8_t status_code); diff --git a/grbl/settings.h b/grbl/settings.h index 6f215e09f..957c81f4c 100644 --- a/grbl/settings.h +++ b/grbl/settings.h @@ -101,7 +101,7 @@ void settings_init(); // Helper functions to clear and restore EEPROM defaults void settings_restore_global_settings(); void settings_clear_parameters(); -void settings_clear_startup_line(); +void settings_clear_startup_lines(); void settings_clear_build_info(); // A helper method to set new settings from command line diff --git a/grbl/system.c b/grbl/system.c index 11a71eb02..cd62f6cec 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -200,7 +200,14 @@ uint8_t system_execute_line(char *line) } while (line[char_counter++] != 0); settings_store_build_info(line); } - break; + break; + case 'R' : // Restore defaults [IDLE/ALARM] + if (line[++char_counter] != 'S') { return(STATUS_INVALID_STATEMENT); } + if (line[++char_counter] != 'T') { return(STATUS_INVALID_STATEMENT); } + if (line[++char_counter] != 0) { return(STATUS_INVALID_STATEMENT); } + report_feedback_message(MESSAGE_RESTORE_DEFAULTS); + settings_restore_global_settings(); + break; case 'N' : // Startup lines. [IDLE/ALARM] if ( line[++char_counter] == 0 ) { // Print startup lines for (helper_var=0; helper_var < N_STARTUP_LINE; helper_var++) { From e6db56451118718fb9ef83624cda6e6ab0ab6ea5 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 18 Jun 2015 09:27:13 -0600 Subject: [PATCH 63/74] Updated README --- README.md | 4 ++-- doc/log/commit_log_v0.9i.txt | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3984d9c41..a899d7c2d 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-05-29)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-05-29)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-18)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-18)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index f10079f91..9159e6234 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,15 @@ +---------------- +Date: 2015-06-18 +Author: Sonny Jeon +Subject: Added restore settings defaults command. + +- New restore setting defaults command. Only wipes ‘$$’ setting in +EEPROM and reloads them based on the defaults used when Grbl was +compiled. Used with a `$RST` command + +NOTE: `$RST` is intentionally not listed in the Grbl ‘$’ help message. + + ---------------- Date: 2015-05-29 Author: Sonny Jeon From 81505e6a8111dd0fcbd4c8c0e88b5c65de5b4904 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sat, 20 Jun 2015 10:27:24 -0600 Subject: [PATCH 64/74] New EEPROM restore functions. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Tweaked the previous EEPROM restore implementation and added new functionality. - `$RST=$` restores the `$$` grbl settings back to firmware defaults, which are set when compiled. - `$RST=#` restores the `$#` parameters in EEPROM. At times it’s useful to clear these and start over, rather than manually writing each entry. -`$RST=*` wipe all of the data in EEPROM that Grbl uses and restores them to defaults. This includes `$$` settings, `$#` parameters, `$N` startup lines, and `$i` build info string. NOTE: This doesn’t write zeros throughout the EEPROM. It only writes where Grbl looks for data. For a complete wipe, please use the Arduino IDE’s EEPROM clear example. - Refactored the restore and wipe functions in settings.c to accommodate the new commands. --- README.md | 4 +- doc/log/commit_log_v0.9i.txt | 6 ++ grbl/grbl.h | 2 +- grbl/settings.c | 140 ++++++++++++++++------------------- grbl/settings.h | 14 ++-- grbl/system.c | 11 ++- 6 files changed, 92 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index a899d7c2d..b5ca02dea 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-18)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-18)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-20)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-20)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 9159e6234..3ace5088f 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,9 @@ +---------------- +Date: 2015-06-18 +Author: Sonny Jeon +Subject: Updated README + + ---------------- Date: 2015-06-18 Author: Sonny Jeon diff --git a/grbl/grbl.h b/grbl/grbl.h index 073a571d7..5e730ef3b 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150618" +#define GRBL_VERSION_BUILD "20150620" // Define standard libraries used by Grbl. #include diff --git a/grbl/settings.c b/grbl/settings.c index 87535d566..f7fb6eb52 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -56,69 +56,65 @@ void write_global_settings() // Method to restore EEPROM-saved Grbl global settings back to defaults. -void settings_restore_global_settings() { - settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS; - settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME; - settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK; - settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK; - settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK; - settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION; - settings.arc_tolerance = DEFAULT_ARC_TOLERANCE; - settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK; - settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE; - settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE; - settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY; - settings.homing_pulloff = DEFAULT_HOMING_PULLOFF; - - settings.flags = 0; - if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; } - if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } - if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } - if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; } - if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } - if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; } +void settings_restore(uint8_t restore_flag) { + if (restore_flag & SETTINGS_RESTORE_DEFAULTS) { + settings.pulse_microseconds = DEFAULT_STEP_PULSE_MICROSECONDS; + settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME; + settings.step_invert_mask = DEFAULT_STEPPING_INVERT_MASK; + settings.dir_invert_mask = DEFAULT_DIRECTION_INVERT_MASK; + settings.status_report_mask = DEFAULT_STATUS_REPORT_MASK; + settings.junction_deviation = DEFAULT_JUNCTION_DEVIATION; + settings.arc_tolerance = DEFAULT_ARC_TOLERANCE; + settings.homing_dir_mask = DEFAULT_HOMING_DIR_MASK; + settings.homing_feed_rate = DEFAULT_HOMING_FEED_RATE; + settings.homing_seek_rate = DEFAULT_HOMING_SEEK_RATE; + settings.homing_debounce_delay = DEFAULT_HOMING_DEBOUNCE_DELAY; + settings.homing_pulloff = DEFAULT_HOMING_PULLOFF; + + settings.flags = 0; + if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; } + if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } + if (DEFAULT_INVERT_LIMIT_PINS) { settings.flags |= BITFLAG_INVERT_LIMIT_PINS; } + if (DEFAULT_SOFT_LIMIT_ENABLE) { settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; } + if (DEFAULT_HARD_LIMIT_ENABLE) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } + if (DEFAULT_HOMING_ENABLE) { settings.flags |= BITFLAG_HOMING_ENABLE; } - settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM; - settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM; - settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM; - settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE; - settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE; - settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE; - settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION; - settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION; - settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION; - settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL); - settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL); - settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL); - - write_global_settings(); -} - - -// Helper function to clear the EEPROM space containing parameter data. -void settings_clear_parameters() { - uint8_t idx; - float coord_data[N_AXIS]; - memset(&coord_data, 0, sizeof(coord_data)); - for (idx=0; idx < SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } -} - - -// Helper function to clear the EEPROM space containing the startup lines. -void settings_clear_startup_lines() { - #if N_STARTUP_LINE > 0 - eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0); - #endif - #if N_STARTUP_LINE > 1 - eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0); - #endif + settings.steps_per_mm[X_AXIS] = DEFAULT_X_STEPS_PER_MM; + settings.steps_per_mm[Y_AXIS] = DEFAULT_Y_STEPS_PER_MM; + settings.steps_per_mm[Z_AXIS] = DEFAULT_Z_STEPS_PER_MM; + settings.max_rate[X_AXIS] = DEFAULT_X_MAX_RATE; + settings.max_rate[Y_AXIS] = DEFAULT_Y_MAX_RATE; + settings.max_rate[Z_AXIS] = DEFAULT_Z_MAX_RATE; + settings.acceleration[X_AXIS] = DEFAULT_X_ACCELERATION; + settings.acceleration[Y_AXIS] = DEFAULT_Y_ACCELERATION; + settings.acceleration[Z_AXIS] = DEFAULT_Z_ACCELERATION; + settings.max_travel[X_AXIS] = (-DEFAULT_X_MAX_TRAVEL); + settings.max_travel[Y_AXIS] = (-DEFAULT_Y_MAX_TRAVEL); + settings.max_travel[Z_AXIS] = (-DEFAULT_Z_MAX_TRAVEL); + + write_global_settings(); + } + + if (restore_flag & SETTINGS_RESTORE_PARAMETERS) { + uint8_t idx; + float coord_data[N_AXIS]; + memset(&coord_data, 0, sizeof(coord_data)); + for (idx=0; idx < SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } + } + + if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) { + #if N_STARTUP_LINE > 0 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK, 0); + #endif + #if N_STARTUP_LINE > 1 + eeprom_put_char(EEPROM_ADDR_STARTUP_BLOCK+(LINE_BUFFER_SIZE+1), 0); + #endif + } + + if (restore_flag & SETTINGS_RESTORE_BUILD_INFO) { eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0); } } -// Helper function to clear the EEPROM space containing the user build info string. -void settings_clear_build_info() { eeprom_put_char(EEPROM_ADDR_BUILD_INFO , 0); } - - // Reads startup line from EEPROM. Updated pointed line string data. uint8_t settings_read_startup_line(uint8_t n, char *line) { @@ -282,27 +278,21 @@ uint8_t settings_store_global_setting(uint8_t parameter, float value) { void settings_init() { if(!read_global_settings()) { report_status_message(STATUS_SETTING_READ_FAIL); - - settings_restore_global_settings(); - - // Force clear startup lines and build info user data. Parameters should be ok. - // TODO: For next version, remove these clears. Only here because line buffer increased. - settings_clear_startup_lines(); - settings_clear_build_info(); - + settings_restore(SETTINGS_RESTORE_ALL); // Force restore all EEPROM data. report_grbl_settings(); } + // NOTE: Checking paramater data, startup lines, and build info string should be done here, + // but it seems fairly redundant. Each of these can be manually checked and reset or restored. // Check all parameter data into a dummy variable. If error, reset to zero, otherwise do nothing. - float coord_data[N_AXIS]; - uint8_t i; - for (i=0; i<=SETTING_INDEX_NCOORD; i++) { - if (!settings_read_coord_data(i, coord_data)) { - report_status_message(STATUS_SETTING_READ_FAIL); - } - } + // float coord_data[N_AXIS]; + // uint8_t i; + // for (i=0; i<=SETTING_INDEX_NCOORD; i++) { + // if (!settings_read_coord_data(i, coord_data)) { + // report_status_message(STATUS_SETTING_READ_FAIL); + // } + // } // NOTE: Startup lines are checked and executed by protocol_main_loop at the end of initialization. - // TODO: Build info should be checked here, but will wait until v1.0 to address this. Ok for now. } diff --git a/grbl/settings.h b/grbl/settings.h index 957c81f4c..3442b9e1b 100644 --- a/grbl/settings.h +++ b/grbl/settings.h @@ -46,6 +46,13 @@ #define BITFLAG_RT_STATUS_SERIAL_RX bit(3) #define BITFLAG_RT_STATUS_LIMIT_PINS bit(4) +// Define settings restore bitflags. +#define SETTINGS_RESTORE_ALL 0xFF // All bitflags +#define SETTINGS_RESTORE_DEFAULTS bit(0) +#define SETTINGS_RESTORE_PARAMETERS bit(1) +#define SETTINGS_RESTORE_STARTUP_LINES bit(2) +#define SETTINGS_RESTORE_BUILD_INFO bit(3) + // Define EEPROM memory address location values for Grbl settings and parameters // NOTE: The Atmega328p has 1KB EEPROM. The upper half is reserved for parameters and // the startup script. The lower half contains the global settings and space for future @@ -98,11 +105,8 @@ extern settings_t settings; // Initialize the configuration subsystem (load settings from EEPROM) void settings_init(); -// Helper functions to clear and restore EEPROM defaults -void settings_restore_global_settings(); -void settings_clear_parameters(); -void settings_clear_startup_lines(); -void settings_clear_build_info(); +// Helper function to clear and restore EEPROM defaults +void settings_restore(uint8_t restore_flag); // A helper method to set new settings from command line uint8_t settings_store_global_setting(uint8_t parameter, float value); diff --git a/grbl/system.c b/grbl/system.c index cd62f6cec..1e2ab1bb3 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -204,9 +204,16 @@ uint8_t system_execute_line(char *line) case 'R' : // Restore defaults [IDLE/ALARM] if (line[++char_counter] != 'S') { return(STATUS_INVALID_STATEMENT); } if (line[++char_counter] != 'T') { return(STATUS_INVALID_STATEMENT); } - if (line[++char_counter] != 0) { return(STATUS_INVALID_STATEMENT); } + if (line[++char_counter] != '=') { return(STATUS_INVALID_STATEMENT); } + if (line[char_counter+2] != 0) { return(STATUS_INVALID_STATEMENT); } + switch (line[++char_counter]) { + case '$': settings_restore(SETTINGS_RESTORE_DEFAULTS); break; + case '#': settings_restore(SETTINGS_RESTORE_PARAMETERS); break; + case '*': settings_restore(SETTINGS_RESTORE_ALL); break; + default: return(STATUS_INVALID_STATEMENT); + } report_feedback_message(MESSAGE_RESTORE_DEFAULTS); - settings_restore_global_settings(); + mc_reset(); // Force reset to ensure settings are initialized correctly. break; case 'N' : // Startup lines. [IDLE/ALARM] if ( line[++char_counter] == 0 ) { // Print startup lines From cc38ae2471c756d3c02b11fff82166fa80d80823 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 25 Jun 2015 15:05:47 -0600 Subject: [PATCH 65/74] Restore parameters minor bug fix. - `$RST=#` was not wiping the G30 positions from EEPROM. Minor but now fixed. --- README.md | 4 ++-- doc/log/commit_log_v0.9i.txt | 26 ++++++++++++++++++++++++++ grbl/settings.c | 2 +- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b5ca02dea..12af2b81f 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-20)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-20)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-25)_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-25)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 3ace5088f..26ad54935 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,29 @@ +---------------- +Date: 2015-06-20 +Author: Sonny Jeon +Subject: New EEPROM restore functions. + +- Tweaked the previous EEPROM restore implementation and added new +functionality. + +- `$RST=$` restores the `$$` grbl settings back to firmware defaults, +which are set when compiled. + +- `$RST=#` restores the `$#` parameters in EEPROM. At times it’s useful +to clear these and start over, rather than manually writing each entry. + +-`$RST=*` wipe all of the data in EEPROM that Grbl uses and restores +them to defaults. This includes `$$` settings, `$#` parameters, `$N` +startup lines, and `$i` build info string. + +NOTE: This doesn’t write zeros throughout the EEPROM. It only writes +where Grbl looks for data. For a complete wipe, please use the Arduino +IDE’s EEPROM clear example. + +- Refactored the restore and wipe functions in settings.c to +accommodate the new commands. + + ---------------- Date: 2015-06-18 Author: Sonny Jeon diff --git a/grbl/settings.c b/grbl/settings.c index f7fb6eb52..2b3291813 100644 --- a/grbl/settings.c +++ b/grbl/settings.c @@ -99,7 +99,7 @@ void settings_restore(uint8_t restore_flag) { uint8_t idx; float coord_data[N_AXIS]; memset(&coord_data, 0, sizeof(coord_data)); - for (idx=0; idx < SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } + for (idx=0; idx <= SETTING_INDEX_NCOORD; idx++) { settings_write_coord_data(idx, coord_data); } } if (restore_flag & SETTINGS_RESTORE_STARTUP_LINES) { From 0427fd5b9f960c8122bfaf0732211bb43a8deb2b Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 17 Jul 2015 08:19:57 -0600 Subject: [PATCH 66/74] Version bump to v0.9j - Version bump requested by OEMs to easily determine whether the firmware supports the new EEPROM reset feature. Other than that, no significant changes. --- README.md | 28 +++++++++++++++++----------- doc/log/commit_log_v0.9i.txt | 9 +++++++++ grbl/config.h | 3 +++ grbl/grbl.h | 4 ++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 12af2b81f..4d6d6a921 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,16 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) _(2015-06-25)_ -* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) _(2015-06-25)_ - - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9i:** +* [Grbl v0.9j Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1I8Ey4S) _(2015-07-17)_ +* [Grbl v0.9j Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1OjUSia) _(2015-07-17)_ + - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9 :** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. - Variable spindle is now enabled by default. Z-limit(D12) and spindle enable(D11) have switched to access the hardware PWM on D11. Homing will not work if you do not re-wire your Z-limit switch to D12. _**Archives:**_ +* [Grbl v0.9i Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1EiviDk) +* [Grbl v0.9i Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1NYIfKl) * [Grbl v0.9g Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1m8E1Qa) * [Grbl v0.9g Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1kOAzig) * [Grbl v0.8c Atmega328p 16mhz 9600baud](http://bit.ly/SSdCJE) @@ -47,19 +49,23 @@ _**Archives:**_ *** +##Update Summary for v0.9j + - **Restore EEPROM feature:** A new set of restore EEPROM features to help OEMs and users reset their Grbl installation to the build defaults. See Configuring Grbl Wiki for details. + ##Update Summary for v0.9i - **IMPORTANT:** - - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!** - **Homing cycle updated. Locates based on trigger point, rather than release point.** - **System tweaks: $14 cycle auto-start has been removed. No more QUEUE state.** - - **New G-Codes:** Additional probing cycle commands G38.3, G38.4, G38.5 now supported. G40 cutter radius compensation cancel. G91.1 arc IJK distance mode incremental. G61 exact path mode. - - **CoreXY Support:** Grbl now supports CoreXY kinematics on an introductory-level. Most functions have been verified to work, but there may be bugs here or there. Please report any problems you find! - - **Safety Door Support:** Safety door switches are now supported. Grbl will force a feed hold, shutdown the spindle and coolant, and wait until the door switch has closed and the user has issued a resume. Upon resuming, the spindle and coolant will re-energize after a configurable delay and continue. Useful for OEMs that require this feature. - - **Full Limit and Control Pin Configurability:** Limits and control pins operation can now be interpreted by Grbl however you'd like, with the internal pull-up resistors enabled or disabled, or reading a high or low as a trigger. This should cover all wiring and NO or NC switch scenarios. - - **Additional Compile-Time Feature Options:** Control pin state reporting, force power-up alarm state, GUI reporting mode, and more. + - **New G-Codes** + - **CoreXY Support** + - **Safety Door Support** + - **Full Limit and Control Pin Configurability** + - **Additional Compile-Time Feature Options** ##Update Summary for v0.9h from v0.8 - - **IMPORTANT: Default serial baudrate is now 115200! (Up from 9600)** + - **IMPORTANT:** + - **Default serial baudrate is now 115200! (Up from 9600)** + - **Z-limit(D12) and spindle enable(D11) pins have switched to support variable spindle!** - **Super Smooth Stepper Algorithm** - **Stability and Robustness Updates** - **(x4)+ Faster Planner** @@ -80,7 +86,7 @@ _**Archives:**_ - ``` -List of Supported G-Codes in Grbl v0.9i Master: +List of Supported G-Codes in Grbl v0.9 Master: - Non-Modal Commands: G4, G10L2, G10L20, G28, G30, G28.1, G30.1, G53, G92, G92.1 - Motion Modes: G0, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80 - Feed Rate Modes: G93, G94 diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 26ad54935..49d67a757 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,12 @@ +---------------- +Date: 2015-06-25 +Author: Sonny Jeon +Subject: Restore parameters minor bug fix. + +- `$RST=#` was not wiping the G30 positions from EEPROM. Minor but now +fixed. + + ---------------- Date: 2015-06-20 Author: Sonny Jeon diff --git a/grbl/config.h b/grbl/config.h index 955cdee4e..63ee4aa34 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -256,6 +256,9 @@ // the spindle direction pin(D13) as a separate spindle enable pin along with spindle speed PWM on pin D11. // NOTE: This configure option only works with VARIABLE_SPINDLE enabled and a 328p processor (Uno). // NOTE: With no direction pin, the spindle clockwise M4 g-code command will be removed. M3 and M5 still work. +// NOTE: BEWARE! The Arduino bootloader toggles the D13 pin when it powers up. If you flash Grbl with +// a programmer (you can use a spare Arduino as "Arduino as ISP". Search the web on how to wire this.), +// this D13 LED toggling should go away. We haven't tested this though. Please report how it goes! // #define USE_SPINDLE_DIR_AS_ENABLE_PIN // Default disabled. Uncomment to enable. // With this enabled, Grbl sends back an echo of the line it has received, which has been pre-parsed (spaces diff --git a/grbl/grbl.h b/grbl/grbl.h index 5e730ef3b..ea4f9bda9 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -22,8 +22,8 @@ #define grbl_h // Grbl versioning system -#define GRBL_VERSION "0.9i" -#define GRBL_VERSION_BUILD "20150620" +#define GRBL_VERSION "0.9j" +#define GRBL_VERSION_BUILD "20150717" // Define standard libraries used by Grbl. #include From 3a68c22fabf03aa35f92a33338aeabb92e617c47 Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Fri, 14 Aug 2015 14:13:52 -0600 Subject: [PATCH 67/74] Individual control pin invert compile-option. - Control pins may be individually inverted through a CONTROL_INVERT_MASK macro. This mask is define in the cpu_map.h file. --- doc/log/commit_log_v0.9i.txt | 10 ++++++++++ grbl/config.h | 5 +++-- grbl/cpu_map/cpu_map_atmega2560.h | 1 + grbl/cpu_map/cpu_map_atmega328p.h | 1 + grbl/grbl.h | 2 +- grbl/system.c | 4 ++-- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 49d67a757..4208a601b 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,13 @@ +---------------- +Date: 2015-07-17 +Author: Sonny Jeon +Subject: Version bump to v0.9j + +- Version bump requested by OEMs to easily determine whether the +firmware supports the new EEPROM reset feature. Other than that, no +significant changes. + + ---------------- Date: 2015-06-25 Author: Sonny Jeon diff --git a/grbl/config.h b/grbl/config.h index 63ee4aa34..e8a600b93 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -153,8 +153,9 @@ // Inverts pin logic of the control command pins. This essentially means when this option is enabled // you can use normally-closed switches, rather than the default normally-open switches. -// NOTE: Will eventually be added to Grbl settings in v1.0. -// #define INVERT_CONTROL_PIN // Default disabled. Uncomment to enable. +// NOTE: If you require individual control pins inverted, keep this macro disabled and simply alter +// the CONTROL_INVERT_MASK definition in cpu_map.h files. +// #define INVERT_ALL_CONTROL_PINS // Default disabled. Uncomment to enable. // Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful // for some pre-built electronic boards. diff --git a/grbl/cpu_map/cpu_map_atmega2560.h b/grbl/cpu_map/cpu_map_atmega2560.h index 8c2cebc0a..0287f4417 100644 --- a/grbl/cpu_map/cpu_map_atmega2560.h +++ b/grbl/cpu_map/cpu_map_atmega2560.h @@ -108,6 +108,7 @@ #define CONTROL_INT_vect PCINT2_vect #define CONTROL_PCMSK PCMSK2 // Pin change interrupt register #define CONTROL_MASK ((1< diff --git a/grbl/system.c b/grbl/system.c index 1e2ab1bb3..1a11d3e07 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -41,8 +41,8 @@ void system_init() ISR(CONTROL_INT_vect) { uint8_t pin = (CONTROL_PIN & CONTROL_MASK); - #ifndef INVERT_CONTROL_PIN - pin ^= CONTROL_MASK; + #ifndef INVERT_ALL_CONTROL_PINS + pin ^= CONTROL_INVERT_MASK; #endif // Enter only if any CONTROL pin is detected as active. if (pin) { From 90ad129ad262bd6e785cf11b8387a1c376cdd11a Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Sun, 16 Aug 2015 22:43:30 -0600 Subject: [PATCH 68/74] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d6d6a921..c18c710fb 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Grbl includes full acceleration management with look ahead. That means the contr *** ### Official Supporters of the Grbl CNC Project -[![Carbide3D](http://carbide3d.com/files/logo_240px.png)](http://carbide3d.com) [![Inventables](https://dzevsq2emy08i.cloudfront.net/paperclip/press_image_uploads/62/low_res/inventables-logo.png)](http://inventables.com) +![Official Supporters](https://dl.dropboxusercontent.com/u/2221997/Contributors.png) *** From d226555810cc95a10971f57f685483d1a81af79f Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Wed, 30 Sep 2015 20:53:35 -0600 Subject: [PATCH 69/74] Minor bug fixes. - G38.x was not printing correctly in the $G g-code state reports. Now fixed. - Potential bug regarding volatile variables inside a struct. It has never been a problem in v0.9, but ran into this during v1.0 development. Just to be safe, the fixes are applied here. - Updated pre-built firmwares with these two bug fixes. --- README.md | 4 ++-- doc/log/commit_log_v0.9i.txt | 14 ++++++++++++++ grbl/gcode.c | 2 +- grbl/grbl.h | 2 +- grbl/limits.c | 22 +++++++++++----------- grbl/main.c | 4 ++-- grbl/motion_control.c | 22 +++++++++++----------- grbl/probe.c | 6 +++--- grbl/protocol.c | 28 ++++++++++++++-------------- grbl/report.c | 2 +- grbl/serial.c | 10 +++++----- grbl/stepper.c | 4 ++-- grbl/system.c | 10 +++++----- grbl/system.h | 12 ++++++------ 14 files changed, 78 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index c18c710fb..7facb9a11 100644 --- a/README.md +++ b/README.md @@ -27,8 +27,8 @@ Grbl includes full acceleration management with look ahead. That means the contr *** _**Master Branch:**_ -* [Grbl v0.9j Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1I8Ey4S) _(2015-07-17)_ -* [Grbl v0.9j Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1OjUSia) _(2015-07-17)_ +* [Grbl v0.9j Atmega328p 16mhz 115200baud with generic defaults](http://bit.ly/1I8Ey4S) _(2015-09-30)_ +* [Grbl v0.9j Atmega328p 16mhz 115200baud with ShapeOko2 defaults](http://bit.ly/1OjUSia) _(2015-09-30)_ - **IMPORTANT INFO WHEN UPGRADING TO GRBL v0.9 :** - Baudrate is now **115200** (Up from 9600). - Homing cycle updated. Located based on switch trigger, rather than release point. diff --git a/doc/log/commit_log_v0.9i.txt b/doc/log/commit_log_v0.9i.txt index 4208a601b..a3401c2a6 100644 --- a/doc/log/commit_log_v0.9i.txt +++ b/doc/log/commit_log_v0.9i.txt @@ -1,3 +1,17 @@ +---------------- +Date: 2015-08-16 +Author: Sonny Jeon +Subject: Update README.md + +---------------- +Date: 2015-08-14 +Author: Sonny Jeon +Subject: Individual control pin invert compile-option. + +- Control pins may be individually inverted through a +CONTROL_INVERT_MASK macro. This mask is define in the cpu_map.h file. + + ---------------- Date: 2015-07-17 Author: Sonny Jeon diff --git a/grbl/gcode.c b/grbl/gcode.c index c47808e50..a0a8ad13d 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -1037,7 +1037,7 @@ uint8_t gc_execute_line(char *line) protocol_buffer_synchronize(); // Sync and finish all remaining buffered motions before moving on. if (gc_state.modal.program_flow == PROGRAM_FLOW_PAUSED) { if (sys.state != STATE_CHECK_MODE) { - bit_true_atomic(sys.rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. + bit_true_atomic(sys_rt_exec_state, EXEC_FEED_HOLD); // Use feed hold for program pause. protocol_execute_realtime(); // Execute suspend. } } else { // == PROGRAM_FLOW_COMPLETED diff --git a/grbl/grbl.h b/grbl/grbl.h index 091359299..85e94e5a1 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -23,7 +23,7 @@ // Grbl versioning system #define GRBL_VERSION "0.9j" -#define GRBL_VERSION_BUILD "20150811" +#define GRBL_VERSION_BUILD "20150930" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index 65869d189..9742a3219 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -101,16 +101,16 @@ uint8_t limits_get_state() // locked out until a homing cycle or a kill lock command. Allows the user to disable the hard // limit setting if their limits are constantly triggering after a reset and move their axes. if (sys.state != STATE_ALARM) { - if (!(sys.rt_exec_alarm)) { + if (!(sys_rt_exec_alarm)) { #ifdef HARD_LIMIT_FORCE_STATE_CHECK // Check limit pin state. if (limits_get_state()) { mc_reset(); // Initiate system kill. - bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event } #else mc_reset(); // Initiate system kill. - bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event + bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event #endif } } @@ -122,11 +122,11 @@ uint8_t limits_get_state() { WDTCSR &= ~(1< Date: Thu, 22 Oct 2015 13:34:55 -0700 Subject: [PATCH 70/74] Initally added Azteeg PRO whioch is mostly thew same as ramps Fixed enable pins so three enable pins are activated/deactivated as required by ramps --- config.h | 2 +- cpu_map.h | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- stepper.c | 46 ++++++++++++++-- 3 files changed, 196 insertions(+), 10 deletions(-) diff --git a/config.h b/config.h index 728dd02f1..a539166d0 100644 --- a/config.h +++ b/config.h @@ -43,7 +43,7 @@ // Default cpu mappings. Grbl officially supports the Arduino Uno only. Other processor types // may exist from user-supplied templates or directly user-defined in cpu_map.h -#define CPU_MAP_ATMEGA2560_GSHIELD // Arduino Uno CPU +#define CPU_MAP_ATMEGA2560_AZTEEGPRO // Arduino Uno CPU // Define runtime command special characters. These characters are 'picked-off' directly from the // serial read data stream and are not passed to the grbl line execution parser. Select characters diff --git a/cpu_map.h b/cpu_map.h index 5fd1be988..00903ba0d 100644 --- a/cpu_map.h +++ b/cpu_map.h @@ -537,10 +537,20 @@ // #define DIRECTION_MASK ((1< Date: Wed, 4 Nov 2015 13:35:00 -0800 Subject: [PATCH 71/74] Initial merge with upstream/grbl and ramps hack --- grbl/config.h | 2 +- grbl/cpu_map.h | 8 +++- grbl/limits.c | 127 +++++++++++++++++++++---------------------------- 3 files changed, 62 insertions(+), 75 deletions(-) diff --git a/grbl/config.h b/grbl/config.h index dfedffb83..cb3635021 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -38,7 +38,7 @@ // Default cpu mappings. Grbl officially supports the Arduino Uno only. Other processor types // may exist from user-supplied templates or directly user-defined in cpu_map.h -#define CPU_MAP_ATMEGA2560_AZTEEGPRO // Arduino Uno CPU +#define CPU_MAP_ATMEGA2560_RAMPS // mega 2560 and ramps (or azteegpro) //#define CPU_MAP_ATMEGA328P // Arduino Uno CPU // Define realtime command special characters. These characters are 'picked-off' directly from the diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 1804d2506..c5a86f341 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -20,7 +20,7 @@ /* The cpu_map.h files serve as a central pin mapping selection file for different processor types, i.e. AVR 328p or AVR Mega 2560. Each processor has its own pin mapping file. - (i.e. cpu_map_atmega328p.h) Grbl officially supports the Arduino Uno, but the + (i.e. cpu_map_atmega328p.h) Grbl officially supports the Arduino Uno, but the other supplied pin mappings are supplied by users, so your results may vary. */ // NOTE: With new processors, only add the define name and filename to use. @@ -37,7 +37,11 @@ #include "cpu_map/cpu_map_atmega2560.h" #endif -/* +#ifdef CPU_MAP_ATMEGA2560_RAMPS // (Arduino Mega 2560 RAMPS) Working @wolfmanjm + #include "cpu_map/cpu_map_atmega2560_RAMPS.h" +#endif + +/* #ifdef CPU_MAP_CUSTOM_PROC // For a custom pin map or different processor, copy and edit one of the available cpu // map files and modify it to your needs. Make sure the defined name is also changed in diff --git a/grbl/limits.c b/grbl/limits.c index 36817861b..0acff4cee 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -4,7 +4,7 @@ Copyright (c) 2012-2015 Sungeun K. Jeon Copyright (c) 2009-2011 Simen Svale Skogsrud - + Grbl 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 @@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License along with Grbl. If not, see . */ - + #include "grbl.h" @@ -30,7 +30,7 @@ #define HOMING_AXIS_LOCATE_SCALAR 5.0 // Must be > 1 to ensure limit switch is cleared. #endif -void limits_init() +void limits_init() { LIMIT_DDR &= ~(LIMIT_MASK); // Set as input pins @@ -44,9 +44,9 @@ void limits_init() LIMIT_PCMSK |= LIMIT_MASK; // Enable specific pins of the Pin Change Interrupt PCICR |= (1 << LIMIT_INT); // Enable Pin Change Interrupt } else { - limits_disable(); + limits_disable(); } - + #ifdef ENABLE_SOFTWARE_DEBOUNCE MCUSR &= ~(1<>>>>>> upstream/master:grbl/limits.c st_reset(); // Immediately force kill steppers and reset step segment buffer. plan_reset(); // Reset planner buffer to zero planner current position and to clear previous motions. @@ -269,17 +252,17 @@ void limits_go_home(uint8_t cycle_mask) approach = !approach; // After first cycle, homing enters locating phase. Shorten search to pull-off distance. - if (approach) { - max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR; + if (approach) { + max_travel = settings.homing_pulloff*HOMING_AXIS_LOCATE_SCALAR; homing_rate = settings.homing_feed_rate; } else { - max_travel = settings.homing_pulloff; + max_travel = settings.homing_pulloff; homing_rate = settings.homing_seek_rate; } - + } while (n_cycle-- > 0); - - // The active cycle axes should now be homed and machine limits have been located. By + + // The active cycle axes should now be homed and machine limits have been located. By // default, Grbl defines machine space as all negative, as do most CNCs. Since limit switches // can be on either side of an axes, check and set axes machine zero appropriately. Also, // set up pull-off maneuver from axes limit switches that have been homed. This provides @@ -295,35 +278,35 @@ void limits_go_home(uint8_t cycle_mask) if (cycle_mask & bit(idx)) { #ifdef HOMING_FORCE_SET_ORIGIN set_axis_position = 0; - #else + #else if ( bit_istrue(settings.homing_dir_mask,bit(idx)) ) { set_axis_position = lround((settings.max_travel[idx]+settings.homing_pulloff)*settings.steps_per_mm[idx]); } else { set_axis_position = lround(-settings.homing_pulloff*settings.steps_per_mm[idx]); } #endif - + #ifdef COREXY - if (idx==X_AXIS) { + if (idx==X_AXIS) { off_axis_position = (sys.position[B_MOTOR] - sys.position[A_MOTOR])/2; sys.position[A_MOTOR] = set_axis_position - off_axis_position; - sys.position[B_MOTOR] = set_axis_position + off_axis_position; + sys.position[B_MOTOR] = set_axis_position + off_axis_position; } else if (idx==Y_AXIS) { off_axis_position = (sys.position[A_MOTOR] + sys.position[B_MOTOR])/2; sys.position[A_MOTOR] = off_axis_position - set_axis_position; sys.position[B_MOTOR] = off_axis_position + set_axis_position; } else { sys.position[idx] = set_axis_position; - } - #else + } + #else sys.position[idx] = set_axis_position; #endif } } plan_sync_position(); // Sync planner position to homed machine position. - - // sys.state = STATE_HOMING; // Ensure system state set as homing before returning. + + // sys.state = STATE_HOMING; // Ensure system state set as homing before returning. } @@ -334,7 +317,7 @@ void limits_soft_check(float *target) uint8_t idx; uint8_t soft_limit_error = false; for (idx=0; idx 0 || target[idx] < settings.max_travel[idx]) { soft_limit_error = true; } } - #else + #else // NOTE: max_travel is stored as negative if (target[idx] > 0 || target[idx] < settings.max_travel[idx]) { soft_limit_error = true; } #endif - + if (soft_limit_error) { - // Force feed hold if cycle is active. All buffered blocks are guaranteed to be within + // Force feed hold if cycle is active. All buffered blocks are guaranteed to be within // workspace volume so just come to a controlled stop so position is not lost. When complete // enter alarm mode. if (sys.state == STATE_CYCLE) { @@ -359,7 +342,7 @@ void limits_soft_check(float *target) if (sys.abort) { return; } } while ( sys.state != STATE_IDLE ); } - + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. bit_true_atomic(sys_rt_exec_alarm, (EXEC_ALARM_SOFT_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate soft limit critical event protocol_execute_realtime(); // Execute to enter critical event loop and system abort From 80c63a8e56c80637d19fed509706baf6de67be0e Mon Sep 17 00:00:00 2001 From: Jim Morris Date: Wed, 4 Nov 2015 13:35:44 -0800 Subject: [PATCH 72/74] added ramps specific cpu map file --- grbl/cpu_map/cpu_map_atmega2560_RAMPS.h | 160 ++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 grbl/cpu_map/cpu_map_atmega2560_RAMPS.h diff --git a/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h b/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h new file mode 100644 index 000000000..d1abb7f4b --- /dev/null +++ b/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h @@ -0,0 +1,160 @@ +/* + cpu_map_atmega2560.h - CPU and pin mapping configuration file + Part of Grbl + + Copyright (c) 2012-2015 Sungeun K. Jeon + + Grbl 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 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 . +*/ + +/* This cpu_map file serves as a central pin mapping settings file for AVR Mega 2560 */ + + +#ifdef GRBL_PLATFORM +#error "cpu_map already defined: GRBL_PLATFORM=" GRBL_PLATFORM +#endif + + +#define GRBL_PLATFORM "Atmega2560" + + // Serial port pins +#define SERIAL_RX USART0_RX_vect +#define SERIAL_UDRE USART0_UDRE_vect + + // Increase Buffers to make use of extra SRAM +#define RX_BUFFER_SIZE 256 +#define TX_BUFFER_SIZE 128 + + // Define step pulse output pins. +#define X_STEP_DDR DDRF +#define X_STEP_PORT PORTF +#define X_STEP_PIN PINF +#define X_STEP_BIT 0 // MEGA2560 A0 + +#define Y_STEP_DDR DDRF +#define Y_STEP_PORT PORTF +#define Y_STEP_PIN PINF +#define Y_STEP_BIT 6 // MEGA2560 A6 + +#define Z_STEP_DDR DDRL +#define Z_STEP_PORT PORTL +#define Z_STEP_PIN PINL +#define Z_STEP_BIT 3 // MEGA2560 Digital Pin 46 + + + // Define step direction output pins. +#define X_DIRECTION_DDR DDRF +#define X_DIRECTION_PORT PORTF +#define X_DIRECTION_PIN PINF +#define X_DIRECTION_BIT 1 // MEGA2560 A1 + +#define Y_DIRECTION_DDR DDRF +#define Y_DIRECTION_PORT PORTF +#define Y_DIRECTION_PIN PINF +#define Y_DIRECTION_BIT 7 // MEGA2560 A7 + +#define Z_DIRECTION_DDR DDRL +#define Z_DIRECTION_PORT PORTL +#define Z_DIRECTION_PIN PINL +#define Z_DIRECTION_BIT 1 // MEGA2560 Digital Pin 48 + + // Define stepper driver enable/disable output pin. +#define X_STEPPERS_DISABLE_DDR DDRD +#define X_STEPPERS_DISABLE_PORT PORTD +#define X_STEPPERS_DISABLE_BIT 7 // MEGA2560 Digital Pin 38 +#define X_STEPPERS_DISABLE_MASK (1< Date: Wed, 4 Nov 2015 13:36:07 -0800 Subject: [PATCH 73/74] deleted old cpu_map --- cpu_map.h | 777 ------------------------------------------------------ 1 file changed, 777 deletions(-) delete mode 100644 cpu_map.h diff --git a/cpu_map.h b/cpu_map.h deleted file mode 100644 index 00903ba0d..000000000 --- a/cpu_map.h +++ /dev/null @@ -1,777 +0,0 @@ -/* - cpu_map.h - CPU and pin mapping configuration file - Part of Grbl v0.9 - - Copyright (c) 2012-2014 Sungeun K. Jeon - - Grbl 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 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 . -*/ - -/* The cpu_map.h file serves as a central pin mapping settings file for different processor - types, i.e. AVR 328p or AVR Mega 2560. Grbl officially supports the Arduino Uno, but the - other supplied pin mappings are supplied by users, so your results may vary. */ - -// NOTE: This is still a work in progress. We are still centralizing the configurations to -// this file, so your success may vary for other CPUs. - -#ifndef cpu_map_h -#define cpu_map_h - - -//---------------------------------------------------------------------------------------- - -#ifdef CPU_MAP_ATMEGA328P_TRADITIONAL // (Arduino Uno) Officially supported by Grbl. - - // Define serial port pins and interrupt vectors. - #define SERIAL_RX USART_RX_vect - #define SERIAL_UDRE USART_UDRE_vect - - // Define step pulse output pins. NOTE: All step bit pins must be on the same port. - #define STEP_DDR DDRD - #define STEP_PORT PORTD - #define X_STEP_BIT 2 // Uno Digital Pin 2 - #define Y_STEP_BIT 3 // Uno Digital Pin 3 - #define Z_STEP_BIT 4 // Uno Digital Pin 4 - #define STEP_MASK ((1< Date: Fri, 6 Nov 2015 21:19:56 -0800 Subject: [PATCH 74/74] Set the probe pin to ZMIN --- grbl/cpu_map/cpu_map_atmega2560_RAMPS.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h b/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h index d1abb7f4b..f3f1ca227 100644 --- a/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h +++ b/grbl/cpu_map/cpu_map_atmega2560_RAMPS.h @@ -134,10 +134,10 @@ #define CONTROL_INVERT_MASK CONTROL_MASK // May be re-defined to only invert certain control pins. // Define probe switch input pin. -#define PROBE_DDR DDRK -#define PROBE_PIN PINK -#define PROBE_PORT PORTK -#define PROBE_BIT 3 // MEGA2560 Analog Pin 11 +#define PROBE_DDR DDRD +#define PROBE_PIN PIND +#define PROBE_PORT PORTD +#define PROBE_BIT 3 // MEGA2560 Digital pin 18 (ZMIN) #define PROBE_MASK (1<