From 3c9c516a4770b3a7d7d63b4d51cbb5b28c1131fd Mon Sep 17 00:00:00 2001 From: Sonny Jeon Date: Thu, 21 Mar 2013 19:22:07 -0600 Subject: [PATCH] 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. - --- config.h | 17 ++++---- defaults.h | 18 ++++++++- gcode.c | 11 +++-- limits.c | 28 ++++++++++++- limits.h | 8 +++- main.c | 4 +- motion_control.c | 102 ++++++++++++++++++++++++----------------------- motion_control.h | 7 +++- nuts_bolts.h | 5 ++- planner.c | 8 +--- planner.h | 4 +- protocol.c | 10 +++-- report.c | 48 ++++++++++++---------- report.h | 5 ++- settings.c | 49 ++++++++++++++--------- settings.h | 7 ++-- 16 files changed, 201 insertions(+), 130 deletions(-) diff --git a/config.h b/config.h index 93fd1ee..d1587fa 100644 --- a/config.h +++ b/config.h @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -107,13 +107,12 @@ // The "Stepper Driver Interrupt" employs the Pramod Ranade inverse time algorithm to manage the // Bresenham line stepping algorithm. The value ISR_TICKS_PER_SECOND is the frequency(Hz) at which -// the Ranade algorithm ticks at. Maximum step frequencies are limited by the Ranade frequency by -// approximately 0.75-0.9 * ISR_TICK_PER_SECOND. Meaning for 20kHz, the max step frequency is roughly -// 15-18kHz. An Arduino can safely complete a single interrupt of the current stepper driver algorithm -// theoretically up to a frequency of 35-40kHz, but CPU overhead increases exponentially as this -// frequency goes up. So there will be little left for other processes like arcs. -// In future versions, more work will be done to increase the step rates but still stay around -// 20kHz by performing two steps per step event, rather than just one. +// the Ranade algorithm ticks at. Recommended step frequencies are limited by the Ranade frequency by +// approximately 0.75-0.9 * ISR_TICK_PER_SECOND. Meaning for 30kHz, the max step frequency is roughly +// 22.5-27kHz, but 30kHz is still possible, just not optimal. An Arduino can safely complete a single +// interrupt of the current stepper driver algorithm theoretically up to a frequency of 35-40kHz, but +// CPU overhead increases exponentially as this frequency goes up. So there will be little left for +// other processes like arcs. #define ISR_TICKS_PER_SECOND 30000L // Integer (Hz) // The temporal resolution of the acceleration management subsystem. Higher number give smoother @@ -208,7 +207,7 @@ // The number of linear motions in the planner buffer to be planned at any give time. The vast // majority of RAM that Grbl uses is based on this buffer size. Only increase if there is extra -// available RAM, like when re-compiling for a Teensy or Sanguino. Or decrease if the Arduino +// available RAM, like when re-compiling for a Mega or Sanguino. Or decrease if the Arduino // begins to crash due to the lack of available RAM or if the CPU is having trouble keeping // up with planning new incoming motions as they are executed. // #define BLOCK_BUFFER_SIZE 18 // Uncomment to override default in planner.h. diff --git a/defaults.h b/defaults.h index 293e934..df3903c 100644 --- a/defaults.h +++ b/defaults.h @@ -2,7 +2,7 @@ defaults.h - defaults settings configuration file Part of Grbl - Copyright (c) 2012 Sungeun K. Jeon + Copyright (c) 2012-2013 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 @@ -42,6 +42,7 @@ #define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_AUTO_START 1 // true #define DEFAULT_INVERT_ST_ENABLE 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 @@ -51,6 +52,9 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255) #define DEFAULT_DECIMAL_PLACES 3 + #define DEFAULT_X_MAX_TRAVEL 200 // mm + #define DEFAULT_Y_MAX_TRAVEL 200 // mm + #define DEFAULT_Z_MAX_TRAVEL 200 // mm #endif #ifdef DEFAULTS_SHERLINE_5400 @@ -72,6 +76,7 @@ #define DEFAULT_REPORT_INCHES 1 // false #define DEFAULT_AUTO_START 1 // true #define DEFAULT_INVERT_ST_ENABLE 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 @@ -81,6 +86,9 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255) #define DEFAULT_DECIMAL_PLACES 3 + #define DEFAULT_X_MAX_TRAVEL 200 // mm + #define DEFAULT_Y_MAX_TRAVEL 200 // mm + #define DEFAULT_Z_MAX_TRAVEL 200 // mm #endif #ifdef DEFAULTS_SHAPEOKO @@ -105,6 +113,7 @@ #define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_AUTO_START 1 // true #define DEFAULT_INVERT_ST_ENABLE 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 @@ -114,6 +123,9 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #define DEFAULT_STEPPER_IDLE_LOCK_TIME 255 // msec (0-255) #define DEFAULT_DECIMAL_PLACES 3 + #define DEFAULT_X_MAX_TRAVEL 200 // mm + #define DEFAULT_Y_MAX_TRAVEL 200 // mm + #define DEFAULT_Z_MAX_TRAVEL 200 // mm #endif #ifdef DEFAULTS_ZEN_TOOLWORKS_7x7 @@ -136,6 +148,7 @@ #define DEFAULT_REPORT_INCHES 0 // false #define DEFAULT_AUTO_START 1 // true #define DEFAULT_INVERT_ST_ENABLE 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 @@ -145,6 +158,9 @@ #define DEFAULT_HOMING_PULLOFF 1.0 // mm #define DEFAULT_STEPPER_IDLE_LOCK_TIME 25 // msec (0-255) #define DEFAULT_DECIMAL_PLACES 3 + #define DEFAULT_X_MAX_TRAVEL 200 // mm + #define DEFAULT_Y_MAX_TRAVEL 200 // mm + #define DEFAULT_Z_MAX_TRAVEL 200 // mm #endif #endif diff --git a/gcode.c b/gcode.c index 4445787..b52de4b 100644 --- a/gcode.c +++ b/gcode.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -322,7 +322,7 @@ uint8_t gc_execute_line(char *line) target[i] = gc.position[i]; } } - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], -1.0, false); + mc_line(target, -1.0, false); } // Retreive G28/30 go-home position data (in machine coordinates) from EEPROM float coord_data[N_AXIS]; @@ -331,7 +331,7 @@ uint8_t gc_execute_line(char *line) } else { if (!settings_read_coord_data(SETTING_INDEX_G30,coord_data)) { return(STATUS_SETTING_READ_FAIL); } } - mc_line(coord_data[X_AXIS], coord_data[Y_AXIS], coord_data[Z_AXIS], -1.0, false); + mc_line(coord_data, -1.0, false); memcpy(gc.position, coord_data, sizeof(coord_data)); // gc.position[] = coord_data[]; axis_words = 0; // Axis words used. Lock out from motion modes by clearing flags. break; @@ -404,7 +404,7 @@ uint8_t gc_execute_line(char *line) break; case MOTION_MODE_SEEK: if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} - else { mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], -1.0, false); } + else { mc_line(target, -1.0, false); } break; case MOTION_MODE_LINEAR: // TODO: Inverse time requires F-word with each statement. Need to do a check. Also need @@ -412,8 +412,7 @@ uint8_t gc_execute_line(char *line) // and after an inverse time move and then check for non-zero feed rate each time. This // should be efficient and effective. if (!axis_words) { FAIL(STATUS_INVALID_STATEMENT);} - else { mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], - (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); } + else { mc_line(target, (gc.inverse_feed_rate_mode) ? inverse_feed_rate : gc.feed_rate, gc.inverse_feed_rate_mode); } break; case MOTION_MODE_CW_ARC: case MOTION_MODE_CCW_ARC: // Check if at least one of the axes of the selected plane has been specified. If in center diff --git a/limits.c b/limits.c index 1da9c54..a235057 100644 --- a/limits.c +++ b/limits.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2012 Sungeun K. Jeon + Copyright (c) 2012-2013 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 @@ -244,3 +244,29 @@ void limits_go_home() st_go_idle(); // Call main stepper shutdown routine. } + + +// Performs a soft limit check. Called from mc_line() only. Assumes the machine has been homed, +// and the workspace volume is in all negative space. +void limits_soft_check(float *target) +{ + if ( target[X_AXIS] > 0 || target[X_AXIS] < -settings.max_travel[X_AXIS] || + target[Y_AXIS] > 0 || target[Y_AXIS] < -settings.max_travel[Y_AXIS] || + target[Z_AXIS] > 0 || target[Z_AXIS] < -settings.max_travel[Z_AXIS] ) { + + // 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) { + st_feed_hold(); + while (sys.state == STATE_HOLD) { + protocol_execute_runtime(); + if (sys.abort) { return; } + } + } + + mc_reset(); // Issue system reset and ensure spindle and coolant are shutdown. + sys.execute |= EXEC_CRIT_EVENT; // Indicate soft limit critical event + protocol_execute_runtime(); // Execute to enter critical event loop and system abort + } +} diff --git a/limits.h b/limits.h index 847c667..ac94dd6 100644 --- a/limits.h +++ b/limits.h @@ -3,6 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud + Copyright (c) 2013 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 @@ -21,10 +22,13 @@ #ifndef limits_h #define limits_h -// initialize the limits module +// Initialize the limits module void limits_init(); -// perform the homing cycle +// Perform the homing cycle void limits_go_home(); +// Check for soft limit violations +void limits_soft_check(float *target); + #endif \ No newline at end of file diff --git a/main.c b/main.c index b1e7734..84b0313 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -106,7 +106,7 @@ int main(void) // When the serial protocol returns, there are no more characters in the serial read buffer to // be processed and executed. This indicates that individual commands are being issued or // streaming is finished. In either case, auto-cycle start, if enabled, any queued moves. - if (sys.auto_start) { st_cycle_start(); } + mc_auto_cycle_start(); } return 0; /* never reached */ diff --git a/motion_control.c b/motion_control.c index ca23c87..15601e6 100644 --- a/motion_control.c +++ b/motion_control.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 Sungeun K. Jeon Copyright (c) 2011 Jens Geisler Grbl is free software: you can redistribute it and/or modify @@ -41,19 +41,15 @@ // (1 minute)/feed_rate time. // NOTE: This is the primary gateway to the grbl planner. All line motions, including arc line // segments, must pass through this routine before being passed to the planner. The seperation of -// mc_line and plan_buffer_line is done primarily to make backlash compensation or canned cycle -// integration simple and direct. -// TODO: Check for a better way to avoid having to push the arguments twice for non-backlash cases. -// However, this keeps the memory requirements lower since it doesn't have to call and hold two -// plan_buffer_lines in memory. Grbl only has to retain the original line input variables during a -// backlash segment(s). -void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rate) +// mc_line and plan_buffer_line is done primarily to place non-planner-type functions from being +// in the planner and to let backlash compensation or canned cycle integration simple and direct. +void mc_line(float *target, float feed_rate, uint8_t invert_feed_rate) { - // TODO: Perform soft limit check here. Just check if the target x,y,z values are outside the - // work envelope. Should be straightforward and efficient. By placing it here, rather than in - // the g-code parser, it directly picks up motions from everywhere in Grbl. - - // If in check gcode mode, prevent motion by blocking planner. + // If enabled, check for soft limit violations. Placed here all line motions are picked up + // from everywhere in Grbl. + if (bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)) { limits_soft_check(target); } + + // If in check gcode mode, prevent motion by blocking planner. Soft limits still work. if (sys.state == STATE_CHECK_MODE) { return; } // TODO: Backlash compensation may be installed here. Only need direction info to track when @@ -68,22 +64,15 @@ void mc_line(float x, float y, float z, float feed_rate, uint8_t invert_feed_rat do { protocol_execute_runtime(); // Check for any run-time commands if (sys.abort) { return; } // Bail, if system abort. - } while ( plan_check_full_buffer() ); - plan_buffer_line(x, y, z, feed_rate, invert_feed_rate); + if ( plan_check_full_buffer() ) { mc_auto_cycle_start(); } // Auto-cycle start when buffer is full. + else { break; } + } while (1); + + plan_buffer_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], feed_rate, invert_feed_rate); // If idle, indicate to the system there is now a planned block in the buffer ready to cycle // start. Otherwise ignore and continue on. if (!sys.state) { sys.state = STATE_QUEUED; } - - // Auto-cycle start immediately after planner finishes. Enabled/disabled by grbl settings. During - // a feed hold, auto-start is disabled momentarily until the cycle is resumed by the cycle-start - // runtime command. - // NOTE: This is allows the user to decide to exclusively use the cycle start runtime command to - // begin motion or let grbl auto-start it for them. This is useful when: manually cycle-starting - // when the buffer is completely full and primed; auto-starting, if there was only one g-code - // command sent during manual operation; or if a system is prone to buffer starvation, auto-start - // helps make sure it minimizes any dwelling/motion hiccups and keeps the cycle going. - // if (sys.auto_start) { st_cycle_start(); } } @@ -191,14 +180,14 @@ void mc_arc(float *position, float *target, float *offset, uint8_t axis_0, uint8 arc_target[axis_0] = center_axis0 + r_axis0; arc_target[axis_1] = center_axis1 + r_axis1; arc_target[axis_linear] += linear_per_segment; - mc_line(arc_target[X_AXIS], arc_target[Y_AXIS], arc_target[Z_AXIS], feed_rate, invert_feed_rate); + mc_line(arc_target, feed_rate, invert_feed_rate); // Bail mid-circle on system abort. Runtime command check already performed by mc_line. if (sys.abort) { return; } } } // Ensure last segment arrives at target location. - mc_line(target[X_AXIS], target[Y_AXIS], target[Z_AXIS], feed_rate, invert_feed_rate); + mc_line(target, feed_rate, invert_feed_rate); } @@ -230,31 +219,35 @@ void mc_go_home() protocol_execute_runtime(); // Check for reset and set system abort. if (sys.abort) { return; } // Did not complete. Alarm state set by mc_alarm. - // The machine should now be homed and machine zero has been located. Upon completion, - // reset system position and sync internal position vectors. - clear_vector_float(sys.position); // Set machine zero - sys_sync_current_position(); - sys.state = STATE_IDLE; // Set system state to IDLE to complete motion and indicate homed. - - // Pull-off axes (that have been homed) from limit switches before continuing motion. + // The machine 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 machine zero appropriately. + // At the same time, 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 tripping when hard limits are enabled. - int8_t x_dir, y_dir, z_dir; - x_dir = y_dir = z_dir = 0; - if (HOMING_LOCATE_CYCLE & (1< (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) diff --git a/planner.c b/planner.c index baaba6c..c1a4d4f 100644 --- a/planner.c +++ b/planner.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 Sungeun K. Jeon Copyright (c) 2011 Jens Geisler Grbl is free software: you can redistribute it and/or modify @@ -360,11 +360,7 @@ inline block_t *plan_get_current_block() // Returns the availability status of the block ring buffer. True, if full. uint8_t plan_check_full_buffer() { - if (block_buffer_tail == next_buffer_head) { - // TODO: Move this back into motion control. Shouldn't be here, but it's efficient. - if (sys.auto_start) { st_cycle_start(); } // Auto-cycle start when buffer is full. - return(true); - } + if (block_buffer_tail == next_buffer_head) { return(true); } return(false); } diff --git a/planner.h b/planner.h index a16c8c9..ce5126d 100644 --- a/planner.h +++ b/planner.h @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -52,7 +52,7 @@ typedef struct { uint32_t d_next; // Scaled distance to next step } block_t; -// Initialize the motion plan subsystem +// Initialize the motion plan subsystem void plan_init(); // Add a new linear movement to the buffer. x, y and z is the signed, absolute target position in diff --git a/protocol.c b/protocol.c index c97770a..56aad3c 100644 --- a/protocol.c +++ b/protocol.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -105,15 +105,17 @@ void protocol_execute_runtime() if (rt_exec & (EXEC_ALARM | EXEC_CRIT_EVENT)) { sys.state = STATE_ALARM; // Set system alarm state - // Critical event. Only hard limit qualifies. Update this as new critical events surface. + // Critical event. Only hard/soft limit errors currently qualify. if (rt_exec & EXEC_CRIT_EVENT) { - report_alarm_message(ALARM_HARD_LIMIT); + report_alarm_message(ALARM_LIMIT_ERROR); report_feedback_message(MESSAGE_CRITICAL_EVENT); bit_false(sys.execute,EXEC_RESET); // Disable any existing reset do { // Nothing. Block EVERYTHING until user issues reset or power cycles. Hard limits // typically occur while unattended or not paying attention. Gives the user time - // to do what is needed before resetting, like killing the incoming stream. + // 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. } while (bit_isfalse(sys.execute,EXEC_RESET)); // Standard alarm event. Only abort during motion qualifies. diff --git a/report.c b/report.c index 6b810ad..c115dc7 100644 --- a/report.c +++ b/report.c @@ -2,7 +2,7 @@ report.c - reporting and messaging methods Part of Grbl - Copyright (c) 2012 Sungeun K. Jeon + Copyright (c) 2012-2013 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 @@ -74,6 +74,8 @@ void report_status_message(uint8_t status_code) printPgmString(PSTR("Busy or queued")); break; case STATUS_ALARM_LOCK: printPgmString(PSTR("Alarm lock")); break; + case STATUS_SOFT_LIMIT_ERROR: + printPgmString(PSTR("Homing not enabled")); break; } printPgmString(PSTR("\r\n")); } @@ -84,8 +86,8 @@ void report_alarm_message(int8_t alarm_code) { printPgmString(PSTR("ALARM: ")); switch (alarm_code) { - case ALARM_HARD_LIMIT: - printPgmString(PSTR("Hard limit")); break; + case ALARM_LIMIT_ERROR: + printPgmString(PSTR("Hard/soft limit")); break; case ALARM_ABORT_CYCLE: printPgmString(PSTR("Abort during cycle")); break; } @@ -112,7 +114,7 @@ void report_feedback_message(uint8_t message_code) case MESSAGE_ENABLED: printPgmString(PSTR("Enabled")); break; case MESSAGE_DISABLED: - printPgmString(PSTR("Disabled")); break; + printPgmString(PSTR("Disabled")); break; } printPgmString(PSTR("]\r\n")); } @@ -153,25 +155,29 @@ void report_grbl_settings() { printPgmString(PSTR(" (z v_max, mm/min)\r\n$6=")); printFloat(settings.acceleration[X_AXIS]/(60*60)); // Convert from mm/min^2 for human readability printPgmString(PSTR(" (x accel, mm/sec^2)\r\n$7=")); printFloat(settings.acceleration[Y_AXIS]/(60*60)); // Convert from mm/min^2 for human readability printPgmString(PSTR(" (y accel, mm/sec^2)\r\n$8=")); printFloat(settings.acceleration[Z_AXIS]/(60*60)); // Convert from mm/min^2 for human readability - printPgmString(PSTR(" (z accel, mm/sec^2)\r\n$9=")); printInteger(settings.pulse_microseconds); - printPgmString(PSTR(" (step pulse, usec)\r\n$10=")); printFloat(settings.default_feed_rate); - printPgmString(PSTR(" (default feed, mm/min)\r\n$11=")); printInteger(settings.invert_mask); + printPgmString(PSTR(" (z accel, mm/sec^2)\r\n$9=")); printFloat(settings.max_travel[X_AXIS]); + printPgmString(PSTR(" (x max travel, mm)\r\n$10=")); printFloat(settings.max_travel[Y_AXIS]); + printPgmString(PSTR(" (y max travel, mm)\r\n$11=")); printFloat(settings.max_travel[Z_AXIS]); + printPgmString(PSTR(" (z max travel, mm)\r\n$12=")); printInteger(settings.pulse_microseconds); + printPgmString(PSTR(" (step pulse, usec)\r\n$13=")); printFloat(settings.default_feed_rate); + printPgmString(PSTR(" (default feed, mm/min)\r\n$14=")); printInteger(settings.invert_mask); printPgmString(PSTR(" (step port invert mask, int:")); print_uint8_base2(settings.invert_mask); - printPgmString(PSTR(")\r\n$12=")); printInteger(settings.stepper_idle_lock_time); - printPgmString(PSTR(" (step idle delay, msec)\r\n$13=")); printFloat(settings.junction_deviation); - printPgmString(PSTR(" (junction deviation, mm)\r\n$14=")); printFloat(settings.arc_tolerance); - printPgmString(PSTR(" (arc tolerance, mm)\r\n$15=")); printInteger(settings.decimal_places); - printPgmString(PSTR(" (n-decimals, int)\r\n$16=")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); - printPgmString(PSTR(" (report inches, bool)\r\n$17=")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START)); - printPgmString(PSTR(" (auto start, bool)\r\n$18=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); - printPgmString(PSTR(" (invert step enable, bool)\r\n$19=")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); - printPgmString(PSTR(" (hard limits, bool)\r\n$20=")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); - printPgmString(PSTR(" (homing cycle, bool)\r\n$21=")); printInteger(settings.homing_dir_mask); + printPgmString(PSTR(")\r\n$15=")); printInteger(settings.stepper_idle_lock_time); + printPgmString(PSTR(" (step idle delay, msec)\r\n$16=")); printFloat(settings.junction_deviation); + printPgmString(PSTR(" (junction deviation, mm)\r\n$17=")); printFloat(settings.arc_tolerance); + printPgmString(PSTR(" (arc tolerance, mm)\r\n$18=")); printInteger(settings.decimal_places); + printPgmString(PSTR(" (n-decimals, int)\r\n$19=")); printInteger(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); + printPgmString(PSTR(" (report inches, bool)\r\n$20=")); printInteger(bit_istrue(settings.flags,BITFLAG_AUTO_START)); + printPgmString(PSTR(" (auto start, bool)\r\n$21=")); printInteger(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); + printPgmString(PSTR(" (invert step enable, bool)\r\n$22=")); printInteger(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); + printPgmString(PSTR(" (soft limits, bool)\r\n$23=")); printInteger(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); + printPgmString(PSTR(" (hard limits, bool)\r\n$24=")); printInteger(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); + printPgmString(PSTR(" (homing cycle, bool)\r\n$25=")); printInteger(settings.homing_dir_mask); printPgmString(PSTR(" (homing dir invert mask, int:")); print_uint8_base2(settings.homing_dir_mask); - printPgmString(PSTR(")\r\n$22=")); printFloat(settings.homing_feed_rate); - printPgmString(PSTR(" (homing feed, mm/min)\r\n$23=")); printFloat(settings.homing_seek_rate); - printPgmString(PSTR(" (homing seek, mm/min)\r\n$24=")); printInteger(settings.homing_debounce_delay); - printPgmString(PSTR(" (homing debounce, msec)\r\n$25=")); printFloat(settings.homing_pulloff); + printPgmString(PSTR(")\r\n$26=")); printFloat(settings.homing_feed_rate); + printPgmString(PSTR(" (homing feed, mm/min)\r\n$27=")); printFloat(settings.homing_seek_rate); + printPgmString(PSTR(" (homing seek, mm/min)\r\n$28=")); printInteger(settings.homing_debounce_delay); + printPgmString(PSTR(" (homing debounce, msec)\r\n$29=")); printFloat(settings.homing_pulloff); printPgmString(PSTR(" (homing pull-off, mm)\r\n")); } diff --git a/report.h b/report.h index 8f1555c..cd7f42d 100644 --- a/report.h +++ b/report.h @@ -2,7 +2,7 @@ report.h - reporting and messaging methods Part of Grbl - Copyright (c) 2012 Sungeun K. Jeon + Copyright (c) 2012-2013 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 @@ -35,9 +35,10 @@ #define STATUS_SETTING_READ_FAIL 10 #define STATUS_IDLE_ERROR 11 #define STATUS_ALARM_LOCK 12 +#define STATUS_SOFT_LIMIT_ERROR 13 // Define Grbl alarm codes. Less than zero to distinguish alarm error from status error. -#define ALARM_HARD_LIMIT -1 +#define ALARM_LIMIT_ERROR -1 #define ALARM_ABORT_CYCLE -2 // Define Grbl feedback message codes. diff --git a/settings.c b/settings.c index 2f75e6e..9225a91 100644 --- a/settings.c +++ b/settings.c @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -88,6 +88,7 @@ void settings_reset(bool reset_all) { if (DEFAULT_REPORT_INCHES) { settings.flags |= BITFLAG_REPORT_INCHES; } if (DEFAULT_AUTO_START) { settings.flags |= BITFLAG_AUTO_START; } if (DEFAULT_INVERT_ST_ENABLE) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } + 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.homing_dir_mask = DEFAULT_HOMING_DIR_MASK; @@ -97,6 +98,9 @@ void settings_reset(bool reset_all) { settings.homing_pulloff = DEFAULT_HOMING_PULLOFF; settings.stepper_idle_lock_time = DEFAULT_STEPPER_IDLE_LOCK_TIME; settings.decimal_places = DEFAULT_DECIMAL_PLACES; + 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(); } @@ -165,41 +169,50 @@ uint8_t settings_store_global_setting(int parameter, float value) { case 6: settings.acceleration[X_AXIS] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 7: settings.acceleration[Y_AXIS] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. case 8: settings.acceleration[Z_AXIS] = value*60*60; break; // Convert to mm/min^2 for grbl internal use. - case 9: + case 9: settings.max_travel[X_AXIS] = value; break; + case 10: settings.max_travel[Y_AXIS] = value; break; + case 11: settings.max_travel[Z_AXIS] = value; break; + case 12: if (value < 3) { return(STATUS_SETTING_STEP_PULSE_MIN); } settings.pulse_microseconds = round(value); break; - case 10: settings.default_feed_rate = value; break; - case 11: settings.invert_mask = trunc(value); break; - case 12: settings.stepper_idle_lock_time = round(value); break; - case 13: settings.junction_deviation = fabs(value); break; - case 14: settings.arc_tolerance = value; break; - case 15: settings.decimal_places = round(value); break; - case 16: + case 13: settings.default_feed_rate = value; break; + case 14: settings.invert_mask = trunc(value); break; + case 15: settings.stepper_idle_lock_time = round(value); break; + case 16: settings.junction_deviation = fabs(value); break; + case 17: settings.arc_tolerance = value; break; + case 18: settings.decimal_places = round(value); break; + case 19: if (value) { settings.flags |= BITFLAG_REPORT_INCHES; } else { settings.flags &= ~BITFLAG_REPORT_INCHES; } break; - case 17: // Reset to ensure change. Immediate re-init may cause problems. + case 20: // Reset to ensure change. Immediate re-init may cause problems. if (value) { settings.flags |= BITFLAG_AUTO_START; } else { settings.flags &= ~BITFLAG_AUTO_START; } break; - case 18: // Reset to ensure change. Immediate re-init may cause problems. + case 21: // Reset to ensure change. Immediate re-init may cause problems. if (value) { settings.flags |= BITFLAG_INVERT_ST_ENABLE; } else { settings.flags &= ~BITFLAG_INVERT_ST_ENABLE; } break; - case 19: + case 22: + if (value) { + if (bit_isfalse(settings.flags, BITFLAG_HOMING_ENABLE)) { return(STATUS_SOFT_LIMIT_ERROR); } + settings.flags |= BITFLAG_SOFT_LIMIT_ENABLE; + } else { settings.flags &= ~BITFLAG_SOFT_LIMIT_ENABLE; } + break; + case 23: if (value) { settings.flags |= BITFLAG_HARD_LIMIT_ENABLE; } else { settings.flags &= ~BITFLAG_HARD_LIMIT_ENABLE; } limits_init(); // Re-init to immediately change. NOTE: Nice to have but could be problematic later. break; - case 20: + case 24: if (value) { settings.flags |= BITFLAG_HOMING_ENABLE; } else { settings.flags &= ~BITFLAG_HOMING_ENABLE; } break; - case 21: settings.homing_dir_mask = trunc(value); break; - case 22: settings.homing_feed_rate = value; break; - case 23: settings.homing_seek_rate = value; break; - case 24: settings.homing_debounce_delay = round(value); break; - case 25: settings.homing_pulloff = value; break; + case 25: settings.homing_dir_mask = trunc(value); break; + case 26: settings.homing_feed_rate = value; break; + case 27: settings.homing_seek_rate = value; break; + case 28: settings.homing_debounce_delay = round(value); break; + case 29: settings.homing_pulloff = value; break; default: return(STATUS_INVALID_STATEMENT); } diff --git a/settings.h b/settings.h index 221c4fb..3369845 100644 --- a/settings.h +++ b/settings.h @@ -3,7 +3,7 @@ Part of Grbl Copyright (c) 2009-2011 Simen Svale Skogsrud - Copyright (c) 2011-2012 Sungeun K. Jeon + Copyright (c) 2011-2013 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 @@ -29,7 +29,7 @@ // 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 -#define SETTINGS_VERSION 52 +#define SETTINGS_VERSION 53 // Define bit flag masks for the boolean settings in settings.flag. #define BITFLAG_REPORT_INCHES bit(0) @@ -37,6 +37,7 @@ #define BITFLAG_INVERT_ST_ENABLE bit(2) #define BITFLAG_HARD_LIMIT_ENABLE bit(3) #define BITFLAG_HOMING_ENABLE bit(4) +#define BITFLAG_SOFT_LIMIT_ENABLE bit(5) // 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 @@ -74,7 +75,7 @@ typedef struct { uint8_t stepper_idle_lock_time; // If max value 255, steppers do not disable. uint8_t decimal_places; float max_velocity[N_AXIS]; -// float mm_soft_limit[N_AXIS]; + float max_travel[N_AXIS]; // uint8_t status_report_mask; // Mask to indicate desired report data. } settings_t; extern settings_t settings;