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.
This commit is contained in:
Sonny Jeon 2015-02-23 18:45:26 -07:00
parent d034dc2181
commit c7db1c4546
6 changed files with 240 additions and 159 deletions

View File

@ -106,8 +106,8 @@
// this feature. Since the two switches are sharing a single pin, there is no way for Grbl to tell // 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 // 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 // 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 // limit switch for each axis, don't enable this option. By keeping it disabled, you can perform a
// on the limit switch and not have to move the machine off of it. // homing cycle while on the limit switch and not have to move the machine off of it.
// #define LIMITS_TWO_SWITCHES_ON_AXES // #define LIMITS_TWO_SWITCHES_ON_AXES
// Allows GRBL to track and report gcode line numbers. Enabling this means that the planning buffer // 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. // with little to no benefit during normal operation.
// #define REPORT_INPUT_PIN_STATES // Default disabled. Uncomment to enable. // #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: // 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 // 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 // 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 // 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. // step smoothing. See stepper.c for more details on the AMASS system works.
#define ADAPTIVE_MULTI_AXIS_STEP_SMOOTHING // Default enabled. Comment to disable. #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 // Sets the maximum step rate allowed to be written as a Grbl setting. This option enables an error
// by the CPU speed and will change if something other than an AVR running at 16MHz is used. // 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. // NOTE: For now disabled, will enable if flash space permits.
// #define MAX_STEP_RATE_HZ 30000 // Hz // #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. // 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. // #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. // TODO: Install compile-time option to send numeric status codes rather than strings.

View File

@ -22,8 +22,8 @@
#define grbl_h #define grbl_h
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "0.9h" #define GRBL_VERSION "0.9i"
#define GRBL_VERSION_BUILD "20150215" #define GRBL_VERSION_BUILD "20150223"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -79,8 +79,18 @@ void limits_disable()
// limit setting if their limits are constantly triggering after a reset and move their axes. // limit setting if their limits are constantly triggering after a reset and move their axes.
if (sys.state != STATE_ALARM) { if (sys.state != STATE_ALARM) {
if (!(sys.rt_exec_alarm)) { if (!(sys.rt_exec_alarm)) {
mc_reset(); // Initiate system kill. #ifdef HARD_LIMIT_FORCE_STATE_CHECK
bit_true_atomic(sys.rt_exec_alarm, (EXEC_ALARM_HARD_LIMIT|EXEC_CRITICAL_EVENT)); // Indicate hard limit critical event 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<<WDIE); // Disable watchdog timer. WDTCSR &= ~(1<<WDIE); // Disable watchdog timer.
if (sys.state != STATE_ALARM) { // Ignore if already in alarm state. if (sys.state != STATE_ALARM) { // Ignore if already in alarm state.
if (!(sys.rt_exec_alarm)) { if (!(sys.rt_exec_alarm)) {
uint8_t bits = LIMIT_PIN; uint8_t bits = (LIMIT_PIN & LIMIT_MASK);
// Check limit pin state. // Check limit pin state.
if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; } if (bit_isfalse(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) { bits ^= LIMIT_MASK; }
if (bits & LIMIT_MASK) { if (bits) {
mc_reset(); // Initiate system kill. 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
} }

View File

@ -49,6 +49,11 @@ int main(void)
if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; } if (bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)) { sys.state = STATE_ALARM; }
#endif #endif
// Force Grbl into an ALARM state upon a power-cycle or hard reset.
#ifdef FORCE_INITIALIZATION_ALARM
sys.state = STATE_ALARM;
#endif
// Grbl initialization loop upon power-up or a system abort. For the latter, all processes // Grbl initialization loop upon power-up or a system abort. For the latter, all processes
// will return to this loop to be cleanly re-initialized. // will return to this loop to be cleanly re-initialized.
for(;;) { for(;;) {

View File

@ -43,44 +43,48 @@ void report_status_message(uint8_t status_code)
printPgmString(PSTR("ok\r\n")); printPgmString(PSTR("ok\r\n"));
} else { } else {
printPgmString(PSTR("error: ")); printPgmString(PSTR("error: "));
switch(status_code) { #ifdef REPORT_GUI_MODE
case STATUS_EXPECTED_COMMAND_LETTER: print_uint8_base10(status_code);
printPgmString(PSTR("Expected command letter")); break; #else
case STATUS_BAD_NUMBER_FORMAT: switch(status_code) {
printPgmString(PSTR("Bad number format")); break; case STATUS_EXPECTED_COMMAND_LETTER:
case STATUS_INVALID_STATEMENT: printPgmString(PSTR("Expected command letter")); break;
printPgmString(PSTR("Invalid statement")); break; case STATUS_BAD_NUMBER_FORMAT:
case STATUS_NEGATIVE_VALUE: printPgmString(PSTR("Bad number format")); break;
printPgmString(PSTR("Value < 0")); break; case STATUS_INVALID_STATEMENT:
case STATUS_SETTING_DISABLED: printPgmString(PSTR("Invalid statement")); break;
printPgmString(PSTR("Setting disabled")); break; case STATUS_NEGATIVE_VALUE:
case STATUS_SETTING_STEP_PULSE_MIN: printPgmString(PSTR("Value < 0")); break;
printPgmString(PSTR("Value < 3 usec")); break; case STATUS_SETTING_DISABLED:
case STATUS_SETTING_READ_FAIL: printPgmString(PSTR("Setting disabled")); break;
printPgmString(PSTR("EEPROM read fail. Using defaults")); break; case STATUS_SETTING_STEP_PULSE_MIN:
case STATUS_IDLE_ERROR: printPgmString(PSTR("Value < 3 usec")); break;
printPgmString(PSTR("Not idle")); break; case STATUS_SETTING_READ_FAIL:
case STATUS_ALARM_LOCK: printPgmString(PSTR("EEPROM read fail. Using defaults")); break;
printPgmString(PSTR("Alarm lock")); break; case STATUS_IDLE_ERROR:
case STATUS_SOFT_LIMIT_ERROR: printPgmString(PSTR("Not idle")); break;
printPgmString(PSTR("Homing not enabled")); break; case STATUS_ALARM_LOCK:
case STATUS_OVERFLOW: printPgmString(PSTR("Alarm lock")); break;
printPgmString(PSTR("Line overflow")); break; case STATUS_SOFT_LIMIT_ERROR:
// case STATUS_MAX_STEP_RATE_EXCEEDED: printPgmString(PSTR("Homing not enabled")); break;
// printPgmString(PSTR("Step rate > 30kHz")); 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. // Common g-code parser errors.
case STATUS_GCODE_MODAL_GROUP_VIOLATION: case STATUS_GCODE_MODAL_GROUP_VIOLATION:
printPgmString(PSTR("Modal group violation")); break; printPgmString(PSTR("Modal group violation")); break;
case STATUS_GCODE_UNSUPPORTED_COMMAND: case STATUS_GCODE_UNSUPPORTED_COMMAND:
printPgmString(PSTR("Unsupported command")); break; printPgmString(PSTR("Unsupported command")); break;
case STATUS_GCODE_UNDEFINED_FEED_RATE: case STATUS_GCODE_UNDEFINED_FEED_RATE:
printPgmString(PSTR("Undefined feed rate")); break; printPgmString(PSTR("Undefined feed rate")); break;
default: default:
// Remaining g-code parser errors with error codes // Remaining g-code parser errors with error codes
printPgmString(PSTR("Invalid gcode ID:")); printPgmString(PSTR("Invalid gcode ID:"));
print_uint8_base10(status_code); // Print error code for user reference print_uint8_base10(status_code); // Print error code for user reference
} }
#endif
printPgmString(PSTR("\r\n")); printPgmString(PSTR("\r\n"));
} }
} }
@ -89,18 +93,22 @@ void report_status_message(uint8_t status_code)
void report_alarm_message(int8_t alarm_code) void report_alarm_message(int8_t alarm_code)
{ {
printPgmString(PSTR("ALARM: ")); printPgmString(PSTR("ALARM: "));
switch (alarm_code) { #ifdef REPORT_GUI_MODE
case ALARM_HARD_LIMIT_ERROR: print_uint8_base10(alarm_code);
printPgmString(PSTR("Hard limit")); break; #else
case ALARM_SOFT_LIMIT_ERROR: switch (alarm_code) {
printPgmString(PSTR("Soft limit")); break; case ALARM_HARD_LIMIT_ERROR:
case ALARM_ABORT_CYCLE: printPgmString(PSTR("Hard limit")); break;
printPgmString(PSTR("Abort during cycle")); break; case ALARM_SOFT_LIMIT_ERROR:
case ALARM_PROBE_FAIL: printPgmString(PSTR("Soft limit")); break;
printPgmString(PSTR("Probe fail")); break; case ALARM_ABORT_CYCLE:
case ALARM_HOMING_FAIL: printPgmString(PSTR("Abort during cycle")); break;
printPgmString(PSTR("Homing fail")); break; case ALARM_PROBE_FAIL:
} printPgmString(PSTR("Probe fail")); break;
case ALARM_HOMING_FAIL:
printPgmString(PSTR("Homing fail")); break;
}
#endif
printPgmString(PSTR("\r\n")); printPgmString(PSTR("\r\n"));
delay_ms(500); // Force delay to ensure message clears serial write buffer. delay_ms(500); // Force delay to ensure message clears serial write buffer.
} }
@ -140,20 +148,22 @@ void report_init_message()
// Grbl help message // Grbl help message
void report_grbl_help() { void report_grbl_help() {
printPgmString(PSTR("$$ (view Grbl settings)\r\n" #ifndef REPORT_GUI_MODE
"$# (view # parameters)\r\n" printPgmString(PSTR("$$ (view Grbl settings)\r\n"
"$G (view parser state)\r\n" "$# (view # parameters)\r\n"
"$I (view build info)\r\n" "$G (view parser state)\r\n"
"$N (view startup blocks)\r\n" "$I (view build info)\r\n"
"$x=value (save Grbl setting)\r\n" "$N (view startup blocks)\r\n"
"$Nx=line (save startup block)\r\n" "$x=value (save Grbl setting)\r\n"
"$C (check gcode mode)\r\n" "$Nx=line (save startup block)\r\n"
"$X (kill alarm lock)\r\n" "$C (check gcode mode)\r\n"
"$H (run homing cycle)\r\n" "$X (kill alarm lock)\r\n"
"~ (cycle start)\r\n" "$H (run homing cycle)\r\n"
"! (feed hold)\r\n" "~ (cycle start)\r\n"
"? (current status)\r\n" "! (feed hold)\r\n"
"ctrl-x (reset Grbl)\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 // NOTE: The numbering scheme here must correlate to storing in settings.c
void report_grbl_settings() { void report_grbl_settings() {
// Print Grbl settings. // Print Grbl settings.
printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); #ifdef REPORT_GUI_MODE
printPgmString(PSTR(" (step pulse, usec)\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time); printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds);
printPgmString(PSTR(" (step idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask); printPgmString(PSTR("\r\n$1=")); print_uint8_base10(settings.stepper_idle_lock_time);
printPgmString(PSTR(" (step port invert mask:")); print_uint8_base2(settings.step_invert_mask); 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$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(")\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(" (step enable invert, bool)\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(" (limit pins invert, bool)\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(" (probe pin invert, bool)\r\n$10=")); print_uint8_base10(settings.status_report_mask); printPgmString(PSTR("\r\n$11=")); printFloat_SettingValue(settings.junction_deviation);
printPgmString(PSTR(" (status report mask:")); print_uint8_base2(settings.status_report_mask); printPgmString(PSTR("\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance);
printPgmString(PSTR(")\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); printPgmString(PSTR("\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
printPgmString(PSTR(" (junction deviation, mm)\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); printPgmString(PSTR("\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
printPgmString(PSTR(" (arc tolerance, mm)\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); printPgmString(PSTR("\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
printPgmString(PSTR(" (report inches, bool)\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); printPgmString(PSTR("\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
printPgmString(PSTR(" (soft limits, bool)\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); printPgmString(PSTR("\r\n$23=")); print_uint8_base10(settings.homing_dir_mask);
printPgmString(PSTR(" (hard limits, bool)\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); printPgmString(PSTR("\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate);
printPgmString(PSTR(" (homing cycle, bool)\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); printPgmString(PSTR("\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate);
printPgmString(PSTR(" (homing dir invert mask:")); print_uint8_base2(settings.homing_dir_mask); printPgmString(PSTR("\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay);
printPgmString(PSTR(")\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); printPgmString(PSTR("\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff);
printPgmString(PSTR(" (homing feed, mm/min)\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); printPgmString(PSTR("\r\n"));
printPgmString(PSTR(" (homing seek, mm/min)\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); #else
printPgmString(PSTR(" (homing debounce, msec)\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds);
printPgmString(PSTR(" (homing pull-off, mm)\r\n")); 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 // Print axis settings
uint8_t idx, set_idx; uint8_t idx, set_idx;
uint8_t val = AXIS_SETTINGS_START_VAL; 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 2: printFloat_SettingValue(settings.acceleration[idx]/(60*60)); break;
case 3: printFloat_SettingValue(-settings.max_travel[idx]); break; case 3: printFloat_SettingValue(-settings.max_travel[idx]); break;
} }
printPgmString(PSTR(" (")); #ifdef REPORT_GUI_MODE
switch (idx) { printPgmString(PSTR("\r\n"));
case X_AXIS: printPgmString(PSTR("x")); break; #else
case Y_AXIS: printPgmString(PSTR("y")); break; printPgmString(PSTR(" ("));
case Z_AXIS: printPgmString(PSTR("z")); break; switch (idx) {
} case X_AXIS: printPgmString(PSTR("x")); break;
switch (set_idx) { case Y_AXIS: printPgmString(PSTR("y")); break;
case 0: printPgmString(PSTR(", step/mm")); break; case Z_AXIS: printPgmString(PSTR("z")); break;
case 1: printPgmString(PSTR(" max rate, mm/min")); break; }
case 2: printPgmString(PSTR(" accel, mm/sec^2")); break; switch (set_idx) {
case 3: printPgmString(PSTR(" max travel, mm")); break; case 0: printPgmString(PSTR(", step/mm")); break;
} case 1: printPgmString(PSTR(" max rate, mm/min")); break;
printPgmString(PSTR(")\r\n")); 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; val += AXIS_SETTINGS_INCREMENT;
} }

View File

@ -109,54 +109,57 @@ uint8_t system_execute_line(char *line)
float parameter, value; float parameter, value;
switch( line[char_counter] ) { switch( line[char_counter] ) {
case 0 : report_grbl_help(); break; case 0 : report_grbl_help(); break;
case '$' : // Prints Grbl settings case '$': case 'G': case 'C': case 'X':
if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } if ( line[(char_counter+1)] != 0 ) { return(STATUS_INVALID_STATEMENT); }
if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print. switch( line[char_counter] ) {
else { report_grbl_settings(); } case '$' : // Prints Grbl settings
break; if ( sys.state & (STATE_CYCLE | STATE_HOLD) ) { return(STATUS_IDLE_ERROR); } // Block during cycle. Takes too long to print.
case 'G' : // Prints gcode parser state else { report_grbl_settings(); }
// TODO: Move this to realtime commands for GUIs to request this data during suspend-state. break;
if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } case 'G' : // Prints gcode parser state
else { report_gcode_modes(); } // TODO: Move this to realtime commands for GUIs to request this data during suspend-state.
break; report_gcode_modes();
case 'C' : // Set check g-code mode [IDLE/CHECK] break;
if ( line[++char_counter] != 0 ) { return(STATUS_INVALID_STATEMENT); } case 'C' : // Set check g-code mode [IDLE/CHECK]
// Perform reset when toggling off. Check g-code mode should only work if Grbl // 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 // is idle and ready, regardless of alarm locks. This is mainly to keep things
// simple and consistent. // simple and consistent.
if ( sys.state == STATE_CHECK_MODE ) { if ( sys.state == STATE_CHECK_MODE ) {
mc_reset(); mc_reset();
report_feedback_message(MESSAGE_DISABLED); report_feedback_message(MESSAGE_DISABLED);
} else { } else {
if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode. if (sys.state) { return(STATUS_IDLE_ERROR); } // Requires no alarm mode.
sys.state = STATE_CHECK_MODE; sys.state = STATE_CHECK_MODE;
report_feedback_message(MESSAGE_ENABLED); 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; 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.
default : default :
// Block any system command that requires the state as IDLE/ALARM. (i.e. EEPROM, homing) // 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); } if ( !(sys.state == STATE_IDLE || sys.state == STATE_ALARM) ) { return(STATUS_IDLE_ERROR); }