diff --git a/README.md b/README.md index 1d0bc68..e029fbf 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,8 @@ Grbl includes full acceleration management with look ahead. That means the contr - **Laser Mode** : The new "laser" mode will cause Grbl to move continuously through consecutive G1, G2, and G3 commands with spindle speed changes. When "laser" mode is disabled, Grbl will instead come to a stop to ensure a spindle comes up to speed properly. Spindle speed overrides also work with laser mode so you can tweak the laser power, if you need to during the job. Switch between "laser" mode and "normal" mode via a `$` setting. +- **Sleep Mode** : Grbl may now be put to "sleep" via a `$SLP` command. This will disable everything, including the stepper drivers. Nice to have when you are leaving your machine unattended and want to power down everything automatically. Only a reset exits the sleep state. + - **Significant Interface Improvements**: Just this one time and done simultaneously with adding override data and controls, Grbl has tweaked the communication interface to make it easier for developers to write and maintain their GUIs. _NOTE: GUIs need to specifically update their code to be compatible with v1.1 and later._ - **New Status Reports**: To account for the additional override data, status reports have been tweaked to cram more data into it, while still being smaller than before. Documentation is included, outlining how it has been changed. diff --git a/doc/log/commit_log_v1.1.txt b/doc/log/commit_log_v1.1.txt index dde1665..bfc9ddf 100644 --- a/doc/log/commit_log_v1.1.txt +++ b/doc/log/commit_log_v1.1.txt @@ -1,3 +1,21 @@ +---------------- +Date: 2016-09-28 +Author: Sonny Jeon +Subject: New jog cancel real-time command. Parser typo fix from last push. + +- Added a new jog cancel real-time command. Rather than depending on a +feed hold to cancel a jogging motion, this realtime command can be used +instead. The main advantage is if a feed hold is used, you can +accidentally hold the machine right when Grbl returns to IDLE after +completing a jog. And the GUI doesn’t have to worry about tracking this +either. + +- Fixed a typo in the g-code parser edits from the last push. Was +causing the G10 set coordinate system command to not work correctly. + +- Updated the documentation with the jog cancel command. + + ---------------- Date: 2016-09-27 Author: Sonny Jeon diff --git a/doc/markdown/change_summary.md b/doc/markdown/change_summary.md index ae14643..137e8b0 100644 --- a/doc/markdown/change_summary.md +++ b/doc/markdown/change_summary.md @@ -2,7 +2,7 @@ -------- -### _Specific details are available in the interface.md document._ +### _Specific details are available in the other markdown documents._ -------- #### GUI Interface Tweaks from Grbl v0.9 @@ -33,7 +33,9 @@ Grbl v1.1's interface protocol has been tweaked in the attempt to make GUI devel - `>G54G20:ok` : The open chevron indicates startup line execution. The `:ok` suffix shows it executed correctly without adding an unmatched `ok` response on a new line. -On a final note, this interface tweak came about out of necessity, as more data is being sent back from Grbl and it is capable of doing many more things. It's not intended to be altered again in the near future, if at all. This is likely the only and last major change to this. If you have any comments or suggestions before Grbl v1.1 goes to master, please do immediately so we can all vet the new alteration before its installed. +In addition, all `$x=val` settings, `error:`, and `ALARM:` messages no longer contain human-readable strings, but rather codes that are defined in other documents. The `$` help message is also reduced to just showing the available commands. Doing this saves incredible amounts of flash space. Otherwise, the new overrides features would not have fit. + +On a final note, these interface tweaks came about out of necessity, because more data is being sent back from Grbl, it is capable of doing many more things, and flash space is at a premium. It's not intended to be altered again in the near future, if at all. This is likely the only and last major change to this. If you have any comments or suggestions before Grbl v1.1 goes to master, please do immediately so we can all vet the new alteration before its installed. ---- @@ -92,3 +94,13 @@ On a final note, this interface tweak came about out of necessity, as more data - Grbl is executing g-code block that does not contain a motion, like `G20G54` or `G4P1` dwell. (NOTE: Looking to fixing this later.) ------- + +#### New Commands + +- `$SLP` - Grbl v1.1 now has a sleep mode that can be invoked by this command. It requires Grbl to be in either an IDLE or ALARM state. Once invoked, Grbl will de-energize all connected systems, including the spindle, coolant, and stepper drivers. It'll enter a suspend state that can only be exited by a reset. When reset, Grbl will re-initiatize in an ALARM state because the steppers were disabled and position can not be guaranteed. + - NOTE: Grbl-Mega can invoke the sleep mode at any time, when the sleep timeout feature is enabled in config.h. It does so when Grbl has not received any external input after a timeout period. + +- `$J=line` New jogging commands. This command behaves much like a normal G1 command, but there are some key differences. Jog commands don't alter the g-code parser state, meaning a GUI doesn't have to manage it anymore. Jog commands may be queued and cancelled at any time, where they are automatically flushed from the planner buffer without requiring a reset. See the jogging documentation on how they work and how they may be used to implement a low-latency joystick or rotary dial. + +- Laser mode `$` setting - When enabled, laser mode will move through consecutive G1, G2, and G3 motion commands that have different spindle speed values without stopping. A spindle speed of zero will disable the laser without stopping as well. However, when spindle states change, like M3 or M5, stops are still enforced. + - NOTE: Parking motions are automatically disabled when laser mode is enabled to prevent burning. \ No newline at end of file diff --git a/doc/markdown/interface.md b/doc/markdown/interface.md index b38a8eb..29f2cad 100644 --- a/doc/markdown/interface.md +++ b/doc/markdown/interface.md @@ -23,7 +23,7 @@ The start up message always prints upon startup and after a reset. Whenever you Every string Grbl receives is assumed to be a G-code block/line for it to execute, except for some special system commands Grbl uses for configuration, provide feedback to the user on what and how it's doing, or perform some task such as a homing cycle. To see a list of these system commands, type `$` followed by an enter, and Grbl will respond with: ``` -[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $C $X $H ~ ! ? ctrl-x] +[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x] ``` - _**NOTE:** Grbl v1.1's new override real-time commands are not included in the help message. They use the extended-ASCII character set, which are not easily type-able, and require a GUI that supports them. This is for two reasons: Establish enough characters for all of the overrides with extra for later growth, and prevent accidental keystrokes or characters in a g-code file from enacting an override inadvertently. _ @@ -249,6 +249,8 @@ Feedback messages provide non-critical information on what Grbl is doing, what i - `[MSG:Pgm End]` - M2/30 program end message to denote g-code modes have been restored to defaults according to the M2/30 g-code description. - `[MSG:Restoring defaults]` - Appears as an acknowledgement message when restoring EEPROM defaults via a `$RST=` command. An 'ok' still appears immediately after to denote the `$RST=` was parsed and executed. + + - `[MSG:Sleeping]` - Appears as an acknowledgement message when Grbl's sleep mode is invoked by issuing a `$SLP` command when idle. Note that Grbl-Mega may invoke this at any time when the sleep timer option has been enabled and the timeout has been exceeded. Grbl may only be exited by a reset in the sleep state and will automatically enter an alarm state since the steppers were disabled. - **Queried Feedback Messages:** @@ -362,7 +364,7 @@ Feedback messages provide non-critical information on what Grbl is doing, what i - **Machine State:** - - Valid states types: `Idle, Run, Hold, Jog, Alarm, Door, Check, Home` + - Valid states types: `Idle, Run, Hold, Jog, Alarm, Door, Check, Home, Sleep` - Sub-states may be included via `:` a colon delimiter and numeric code. diff --git a/grbl/config.h b/grbl/config.h index 6acee3a..78266e6 100644 --- a/grbl/config.h +++ b/grbl/config.h @@ -420,7 +420,7 @@ // available RAM, like when re-compiling for a Mega2560. 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 16 // Uncomment to override default in planner.h. +// #define BLOCK_BUFFER_SIZE 17 // Uncomment to override default in planner.h. // Governs the size of the intermediary step segment buffer between the step execution algorithm // and the planner blocks. Each segment is set of steps executed at a constant velocity over a @@ -453,15 +453,6 @@ // #define RX_BUFFER_SIZE 128 // (1-254) Uncomment to override defaults in serial.h // #define TX_BUFFER_SIZE 90 // (1-254) -// A simple software debouncing feature for hard limit switches. When enabled, the interrupt -// monitoring the hard limit switch pins will enable the Arduino's watchdog timer to re-check -// the limit pin state after a delay of about 32msec. This can help with CNC machines with -// problematic false triggering of their hard limit switches, but it WILL NOT fix issues with -// electrical interference on the signal cables from external sources. It's recommended to first -// use shielded signal cables with their shielding connected to ground (old USB/computer cables -// 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. - // Configures the position after a probing cycle during Grbl's check mode. Disabled sets // the position to the probe target, when enabled sets the position to the start position. // #define SET_CHECK_MODE_PROBE_TO_START // Default disabled. Uncomment to enable. @@ -548,8 +539,8 @@ // Configure options for the parking motion, if enabled. #define PARKING_AXIS Z_AXIS // Define which axis that performs the parking motion #define PARKING_TARGET -5.0 // Parking axis target. In mm, as machine coordinate [-max_travel,0]. -#define PARKING_RATE -1.0 // Parking fast rate after pull-out. In mm/min or (-1.0) for seek rate. -#define PARKING_PULLOUT_RATE 250.0 // Pull-out/plunge slow feed rate in mm/min. +#define PARKING_RATE 500.0 // Parking fast rate after pull-out in mm/min. +#define PARKING_PULLOUT_RATE 100.0 // Pull-out/plunge slow feed rate in mm/min. #define PARKING_PULLOUT_INCREMENT 5.0 // Spindle pull-out and plunge distance in mm. Incremental distance. // Must be positive value or equal to zero. diff --git a/grbl/cpu_map.h b/grbl/cpu_map.h index 8be34a6..3a052cb 100644 --- a/grbl/cpu_map.h +++ b/grbl/cpu_map.h @@ -125,7 +125,7 @@ // Variable spindle configuration below. Do not change unless you know what you are doing. // NOTE: Only used when variable spindle is enabled. #define SPINDLE_PWM_MAX_VALUE 255.0 // Don't change. 328p fast PWM mode fixes top value as 255. - #define SPINDLE_PWM_OFF_VALUE 0 + #define SPINDLE_PWM_OFF_VALUE 0.0 #define SPINDLE_TCCRA_REGISTER TCCR2A #define SPINDLE_TCCRB_REGISTER TCCR2B #define SPINDLE_OCR_REGISTER OCR2A diff --git a/grbl/gcode.c b/grbl/gcode.c index 16a5bec..ba8fb10 100644 --- a/grbl/gcode.c +++ b/grbl/gcode.c @@ -901,7 +901,7 @@ uint8_t gc_execute_line(char *line) if (gc_state.spindle_speed != gc_block.values.s) { #ifdef VARIABLE_SPINDLE // Do not stop motion if in laser mode and a G1, G2, or G3 motion is being executed. - if ( !(bit_istrue(settings.flags,BITFLAG_LASER_MODE) && (axis_command == AXIS_COMMAND_MOTION_MODE) && + if ( (bit_isfalse(settings.flags,BITFLAG_LASER_MODE) && (axis_command == AXIS_COMMAND_MOTION_MODE) && ((gc_block.modal.motion == MOTION_MODE_LINEAR ) || (gc_block.modal.motion == MOTION_MODE_CW_ARC) || (gc_block.modal.motion == MOTION_MODE_CCW_ARC)) ) ) { // Update running spindle only if not in check mode and not already enabled. if (gc_state.modal.spindle != SPINDLE_DISABLE) { spindle_run(gc_state.modal.spindle, gc_block.values.s); } diff --git a/grbl/grbl.h b/grbl/grbl.h index ac5d6c5..d0a262c 100644 --- a/grbl/grbl.h +++ b/grbl/grbl.h @@ -22,8 +22,8 @@ #define grbl_h // Grbl versioning system -#define GRBL_VERSION "1.1b" -#define GRBL_VERSION_BUILD "20160928" +#define GRBL_VERSION "1.1c" +#define GRBL_VERSION_BUILD "20161011" // Define standard libraries used by Grbl. #include diff --git a/grbl/limits.c b/grbl/limits.c index f71f93f..7e64294 100644 --- a/grbl/limits.c +++ b/grbl/limits.c @@ -88,53 +88,35 @@ uint8_t limits_get_state() // limit switch can cause a lot of problems, like false readings and multiple interrupt calls. // If a switch is triggered at all, something bad has happened and treat it as such, regardless // if a limit switch is being disengaged. It's impossible to reliably tell the state of a -// bouncing pin without a debouncing method. A simple software debouncing feature may be enabled -// through the config.h file, where an extra timer delays the limit pin read by several milli- -// seconds to help with, not fix, bouncing switches. +// bouncing pin because the Arduino microcontroller does not retain any state information when +// detecting a pin change. If we poll the pins in the ISR, you can miss the correct reading if the +// switch is bouncing. // NOTE: Do not attach an e-stop to the limit pins, because this interrupt is disabled during // homing cycles and will not respond correctly. Upon user request or need, there may be a // special pinout for an e-stop, but it is generally recommended to just directly connect // your e-stop switch to the Arduino reset pin, since it is the most correct way to do this. -#ifndef ENABLE_SOFTWARE_DEBOUNCE - ISR(LIMIT_INT_vect) // DEFAULT: Limit pin change interrupt process. - { - // Ignore limit switches if already in an alarm state or in-process of executing an alarm. - // When in the alarm state, Grbl should have been reset or will force a reset, so any pending - // moves in the planner and serial buffers are all cleared and newly sent blocks will be - // 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)) { - #ifdef HARD_LIMIT_FORCE_STATE_CHECK - // Check limit pin state. - if (limits_get_state()) { - mc_reset(); // Initiate system kill. - system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event - } - #else - mc_reset(); // Initiate system kill. - system_set_exec_alarm(EXEC_ALARM_HARD_LIMIT); // Indicate hard limit critical event - #endif - } - } - } -#else // OPTIONAL: Software debounce limit pin routine. - // Upon limit pin change, enable watchdog timer to create a short delay. - ISR(LIMIT_INT_vect) { if (!(WDTCSR & (1<feed_rate = PARKING_PULLOUT_RATE; - mc_parking_motion(parking_target, pl_data); + mc_parking_motion(restore_target, pl_data); } } #endif @@ -728,8 +713,13 @@ static void protocol_exec_rt_suspend() if (gc_state.modal.spindle != SPINDLE_DISABLE) { report_feedback_message(MESSAGE_SPINDLE_RESTORE); - spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); - delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND); + if (bit_istrue(settings.flags,BITFLAG_LASER_MODE)) { + // When in laser mode, ignore spindle spin-up delay. Set to turn on laser when cycle starts. + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); + } else { + spindle_set_state((restore_condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)), restore_spindle_speed); + delay_sec(SAFETY_DOOR_SPINDLE_DELAY, DELAY_MODE_SYS_SUSPEND); + } } if (sys.toggle_ovr_mask & TOGGLE_OVR_STOP_RESTORE_CYCLE) { system_set_exec_state_flag(EXEC_CYCLE_START); // Set to resume program. diff --git a/grbl/report.c b/grbl/report.c index 4e924ab..828e51c 100644 --- a/grbl/report.c +++ b/grbl/report.c @@ -231,6 +231,8 @@ void report_feedback_message(uint8_t message_code) printPgmString(PSTR("Restoring defaults")); break; case MESSAGE_SPINDLE_RESTORE: printPgmString(PSTR("Restoring spindle")); break; + case MESSAGE_SLEEP_MODE: + printPgmString(PSTR("Sleeping")); break; } report_util_feedback_line_feed(); } @@ -245,7 +247,7 @@ void report_init_message() // Grbl help message void report_grbl_help() { #ifdef REPORT_GUI_MODE - printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $C $X $H ~ ! ? ctrl-x]\r\n")); + printPgmString(PSTR("[HLP:$$ $# $G $I $N $x=val $Nx=line $J=line $SLP $C $X $H ~ ! ? ctrl-x]\r\n")); #else printPgmString(PSTR("$$ (view Grbl settings)\r\n" "$# (view # parameters)\r\n" @@ -255,6 +257,7 @@ void report_grbl_help() { "$x=value (save Grbl setting)\r\n" "$Nx=line (save startup block)\r\n" "$J=line (jog)\r\n" + "$SLP (sleep mode)\r\n" "$C (check gcode mode)\r\n" "$X (kill alarm lock)\r\n" "$H (run homing cycle)\r\n" @@ -571,6 +574,7 @@ void report_realtime_status() else { printPgmString(PSTR("= REPORT_WCO_REFRESH_BUSY_COUNT) { - // if (sys.state & (STATE_HOMING | STATE_CYCLE | STATE_HOLD | STATE_JOG | STATE_SAFETY_DOOR)) { - // sys.report_wco_counter = 1; // Reset counter for slow refresh - // } else { sys.report_wco_counter = (REPORT_WCO_REFRESH_BUSY_COUNT-REPORT_WCO_REFRESH_IDLE_COUNT+1); } - // if (sys.report_ovr_counter >= REPORT_OVR_REFRESH_BUSY_COUNT) { - // sys.report_ovr_counter = (REPORT_OVR_REFRESH_BUSY_COUNT-1); // Set override on next report. - // } - // printPgmString(PSTR("|WCO:")); - // float axis_offset; - // uint8_t idx; - // for (idx=0; idx= settings.rpm_max) || (rpm > settings.rpm_max)) { + if ((settings.rpm_min >= settings.rpm_max) || (rpm >= settings.rpm_max)) { // No PWM range possible. Set simple on/off spindle control pin state. return(SPINDLE_PWM_MAX_VALUE); } else if (rpm < settings.rpm_min) { diff --git a/grbl/stepper.c b/grbl/stepper.c index 1b281bf..0e029f8 100644 --- a/grbl/stepper.c +++ b/grbl/stepper.c @@ -232,7 +232,7 @@ void st_go_idle() // Set stepper driver idle state, disabled or enabled, depending on settings and circumstances. bool pin_state = false; // Keep enabled. - if (((settings.stepper_idle_lock_time != 0xff) || sys_rt_exec_alarm) && sys.state != STATE_HOMING) { + if (((settings.stepper_idle_lock_time != 0xff) || sys_rt_exec_alarm || sys.state == STATE_SLEEP) && sys.state != STATE_HOMING) { // Force stepper dwell to lock axes for a defined amount of time to ensure the axes come to a complete // stop and not drift from residual inertial forces at the end of the last movement. delay_ms(settings.stepper_idle_lock_time); @@ -738,13 +738,22 @@ void st_prep_buffer() prep.maximum_speed = prep.exit_speed; } } - - #ifdef VARIABLE_SPINDLE - st_prep_block->spindle_pwm = spindle_compute_pwm_value((0.01*sys.spindle_speed_ovr)*pl_block->spindle_speed); + + #ifdef VARIABLE_SPINDLE + bit_true(sys.step_control, STEP_CONTROL_UPDATE_SPINDLE_PWM); // Force update whenever updating block. #endif - } - + + #ifdef VARIABLE_SPINDLE + if (sys.step_control & STEP_CONTROL_UPDATE_SPINDLE_PWM) { + // Configure correct spindle PWM state for block. Updates with planner changes and spindle speed overrides. + if (pl_block->condition & (PL_COND_FLAG_SPINDLE_CW | PL_COND_FLAG_SPINDLE_CCW)) { + st_prep_block->spindle_pwm = spindle_compute_pwm_value((0.01*sys.spindle_speed_ovr)*pl_block->spindle_speed); + } else { st_prep_block->spindle_pwm = SPINDLE_PWM_OFF_VALUE; } + bit_false(sys.step_control,STEP_CONTROL_UPDATE_SPINDLE_PWM); + } + #endif + // Initialize new segment segment_t *prep_segment = &segment_buffer[segment_buffer_head]; diff --git a/grbl/system.c b/grbl/system.c index 1815fb3..d56ee1e 100644 --- a/grbl/system.c +++ b/grbl/system.c @@ -186,6 +186,10 @@ uint8_t system_execute_line(char *line) } } else { return(STATUS_SETTING_DISABLED); } break; + case 'S' : // Puts Grbl to sleep [IDLE/ALARM] + if ((line[2] != 'L') || (line[3] != 'P') || (line[4] != 0)) { return(STATUS_INVALID_STATEMENT); } + system_set_exec_state_flag(EXEC_SLEEP); // Set to execute sleep mode immediately + break; case 'I' : // Print or store build info. [IDLE/ALARM] if ( line[++char_counter] == 0 ) { settings_read_build_info(line); diff --git a/grbl/system.h b/grbl/system.h index 90acc0f..5e338c5 100644 --- a/grbl/system.h +++ b/grbl/system.h @@ -35,6 +35,7 @@ #define EXEC_RESET bit(4) // bitmask 00010000 #define EXEC_SAFETY_DOOR bit(5) // bitmask 00100000 #define EXEC_MOTION_CANCEL bit(6) // bitmask 01000000 +#define EXEC_SLEEP bit(7) // bitmask 10000000 // Alarm executor codes. Valid values (1-255). Zero is reserved. #define EXEC_ALARM_HARD_LIMIT 1 @@ -79,7 +80,7 @@ #define STATE_HOLD bit(4) // Active feed hold #define STATE_JOG bit(5) // Jogging mode. #define STATE_SAFETY_DOOR bit(6) // Safety door is ajar. Feed holds and de-energizes system. -// #define STATE_SLEEP bit(7) // Sleep state. [Grbl-Mega Only] +#define STATE_SLEEP bit(7) // Sleep state. // Define system suspend flags. Used in various ways to manage suspend states and procedures. #define SUSPEND_DISABLE 0 // Must be zero. @@ -97,6 +98,7 @@ #define STEP_CONTROL_END_MOTION bit(0) #define STEP_CONTROL_EXECUTE_HOLD bit(1) #define STEP_CONTROL_EXECUTE_SYS_MOTION bit(2) +#define STEP_CONTROL_UPDATE_SPINDLE_PWM bit(3) // Define control pin index for Grbl internal use. Pin maps may change, but these values don't. #ifdef ENABLE_SAFETY_DOOR_INPUT_PIN