diff --git a/grbl/config.h b/grbl/config.h index e51b27c..297742e 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 08e7dd7..ff92269 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 6f00b06..75b9f82 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 2f3d100..a31c5fe 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); }