Fixed unintended laser mode pausing. Updated documentation. Min SS OVR lowered to 10%.

- [laser] Tested a working version and pushed the wrong one for the
last! 20161203 was pausing upon every spindle speed change. That’s not
right. Fixed so nearly all motions are passed through and does not stop.

- Minimum spindle speed override lower from 50% to 10%. Lasers could
use the lower speeds.

- Fixed a very minor bug related to G80 error checking. Allowed no
error with non-modal motions with axis words. Not correct and fixed.

- Fixed a compile error when disabling VARIABLE_SPINDLE

- [doc] Updated some obsolete documentation.

- [doc] Started a “Laser Mode” document that summarizes how Grbl’s new
laser mode works.
This commit is contained in:
chamnit 2016-12-04 23:49:48 -07:00
parent b753c542c7
commit 94083e8314
10 changed files with 155 additions and 50 deletions

View File

@ -1,3 +1,50 @@
----------------
Date: 2016-12-03
Author: Sonny Jeon
Subject: v1.1e: New laser features. G-code parser refactoring. CoreXY homing fix.
- Increment to v1.1e due to new laser features.
- After several discussions with some prominent laser people, a few
tweaks to the new laser mode has been installed.
- LASER: M3 behaves in a constant power mode.
- LASER: M4 behaves in a dynamic power mode, where the laser power is
automatically adjusted based on how fast Grbl is moving relative to the
programmed feed rate. This is the same as the CONSTANT_POWER_PER_RATE
config.h option in the last version. NOTE: When not in motion in M4,
Grbl automatically turns off the laser. Again, it only operates while
moving!
- LASER: Only G1, G2, and G3 motion modes will turn on the laser. So,
this means that G0, G80 motion modes will always keep the laser
disabled. No matter if M3/M4 are active!
- LASER: A spindle stop override is automatically invoked when a laser
is put in a feed hold. This behavior may be disabled by a config.h
option.
- Lots of little tweaks to the g-code parser to help streamline it a
bit. It should no effect how it operates. Generally just added a parser
flag to track and execute certain scenarios a little more clearly.
- Jog motions now allow line numbers to be passed to it and will be
displayed in the status reports.
- Fixed a CoreXY homing bug.
- Fixed an issue when $13 is changed, WCO isnt sent immediately.
- Altered how spindle PWM is set in the stepper ISR. Updated on a step
segment basis now. May need to change this back if there are any
oddities from doing this.
- Updated some documentation. Clarified why M0 no longer showing up in
$G and why a `1.` floating point values are shown with no decimals,
like so `1`.
---------------- ----------------
Date: 2016-11-12 Date: 2016-11-12
Author: Sonny Jeon Author: Sonny Jeon

View File

@ -90,9 +90,8 @@ On a final note, these interface tweaks came about out of necessity, because mor
- Overrides are included in every 10 or 20 status reports (configurable) depending on what Grbl is doing or, if an override value or toggle state changes, automatically in the next report. - Overrides are included in every 10 or 20 status reports (configurable) depending on what Grbl is doing or, if an override value or toggle state changes, automatically in the next report.
- There are two override fields: - There are two override fields:
- `Ov:100,100,100` Organized as feed, rapid, and spindle speed overrides in percent. - `Ov:100,100,100` Organized as feed, rapid, and spindle speed overrides in percent.
- `T:SFM` with each letter `S`, `F`, and `M` are defined as spindle stop active, flood coolant toggled, and mist coolant toggled, respectively.
- Accessory states are shown alongside override reports when they are active. Like pin states, an accessory state report `A:SFM` contains a letter indicating an active accessory. Letters `S`, `C`, `F`, and `M` are defined as spindle CW, spindle CCW, flood coolant, and mist coolant, respectively. The pins are directly polled and shown here.
- Line numbers, when enabled in config.h, are omitted when: - Line numbers, when enabled in config.h, are omitted when:

View File

@ -0,0 +1,57 @@
## Grbl v1.1 Laser Mode
_DISCLAIMER: Lasers are extremely dangerous devices. They can instantly cause fires and permanently damage your vision. Please read and understand all related documentation for your laser prior to using it. The Grbl project is not resposible for any damage or issues the firmware may cause, as defined by its GPL license._
The main difference between traditional Grbl operation and the laser mode is how the spindle/laser output is controlled with motions involved. Every time a spindle state `M3 M4 M5` or spindle speed `Sxxx` is altered, Grbl would normally come to a stop, allow the spindle to change, and then continue. This is the normal operating procedure for a milling machine spindle. It needs time to change speeds. However, if a laser starts and stops like this for every spindle change, this leads to scorching and uneven cutting/engraving.
Outlined in this document is how Grbl alters its running conditions during the laser mode for both improved performance and enforcing some basic user safety precautions.
When laser mode is enabled:
- Grbl will move continuously through **consecutive** motion commands when programmed with a new `S` spindle speed (laser power). The spindle PWM pin will be updated instantaneously through each motion without stopping.
- Example: The following set of g-code commands will not pause between each of them when laser mode is enabled, but will pause when disabled.
```
G1 X10 S100 F50
G1 X0 S90
G2 X0 I5 S80
```
- Grbl will enforce a laser mode motion stop in a few circumstances. Primarily to ensure alterations stay in sync with the g-code program.
- Any `M3`, `M4`, `M5` spindle state _change_.
- A `S` spindle speed _change_ when `M3` is active and there is no motion programmed.
- A `G1 G2 G3` laser powered state _change_ to `G0 G80` laser disabled state when `M3` is active and there is no motion programmed.
- The laser will only turn on when Grbl is in a `G1`, `G2`, or `G3` motion mode.
- In other words, a `G0` rapid motion mode or `G38.x` probe cycle will never turn on and always disable the laser, but will still update the running modal state. When changed to a `G1 G2 G3` modal state, Grbl will immediately enable the laser based on the current running state.
- Please remember that `G0` is the default motion mode upon power up and reset. You will need to alter it to `G1`, `G2`, or `G3` if you want to manually turn on your laser. This is strictly a safety measure.
- Example: `G0 M3 S1000` will not turn on the laser, but will set the laser modal state to `M3` enabled and power of `S1000`. A following `G1` command will then immediately be set to `M3` and `S1000`.
- Grbl supports two different laser modes with the `M3` spindle CW and `M4` spindle CCW commands. These are both advantageous for different reasons.
- `M3` enables constant laser power mode. Constant laser power mode simply keeps the laser power as programmed, regardless if the machine is moving, accelerating, or stopped. This provides better control of the laser state. With a good g-code program, this can lead to more consistent cuts in more difficult materials.
- NOTE: Use `M3` to keep the laser on for focusing.
- For a clean cut, you generally want to add lead-in and lead-out motions around the line you want to cut to give some space for the machine to accelerate and decelerate.
- `M4` enables dynamic laser power mode. Dynamic laser power mode will automatically adjust laser power based on the current speed relative to the programmed rate. It'll essentially ensures the amount of laser energy along a cut is consistent even though the machine may be stopped or actively accelerating. This is very useful for clean, precise engraving and cutting on simple materials across a large range of g-code generation methods by CAM programs. It will generally run faster and may be all you need to use*.
- NOTE: Grbl calculates laser power based on the assumption that laser power is linear with speed and the material. Often, this is not the case. Lasers can cut differently at varying power levels and some materials may not cut well at a particular speed and/power. In short, this means that dynamic power mode may not work for all situations. Always do a test piece prior to using this with a new material or machine.
- When not in motion, `M4` dynamic mode turns off the laser. It only turns on when the machine moves. This generally makes the laser safer to operate, because, unlike `M3`, it will never burn a hole through your table, if you stop and forget to turn `M3` off in time.
- A `S0` spindle speed of zero will turn off the laser. When programmed with a valid laser motion, Grbl will disable the laser instantaneously without stopping for the duration of that motion and future motions until set greater than zero..
- `M3` constant laser mode, this is a great way to turn off the laser power while continuously moving between a `G1` laser motion and a `G0` rapid motion without having to stop. Program a short `G1 S0` motion right before the `G0` motion and a `G1 Sxxx` motion is commanded right after to go back to cutting.
-----
###CAM Developer Implementation Notes
TODO: Add some suggestions on how to write laser g-code for Grbl.
- When using `M3` constant laser power mode, try to avoid force-sync conditions during a job whenever possible. Basically every spindle speed change must be accompanied by a valid motion. Any motion is fine, since Grbl will automatically enable and disable the laser based on the modal state. Avoid a `G0` and `G1` command with no axis words in this mode and in the middle of a job.
- When using `M4` dynamic laser power mode, the only force-sync condition is changing `M3 M4 M5` spindle states. There are no others because dynamic power mode automatically disables the laser whenever it is not in motion.

View File

@ -85,7 +85,7 @@ Grbl v1.1 installed more than a dozen new realtime commands to control feed, rap
- Immediately alters the feed override value. An active feed motion is altered within tens of milliseconds. - Immediately alters the feed override value. An active feed motion is altered within tens of milliseconds.
- Does not alter rapid rates, which include G0, G28, and G30, or jog motions. - Does not alter rapid rates, which include G0, G28, and G30, or jog motions.
- Feed override value can not be 1% or greater than 200% - Feed override value can not be 10% or greater than 200%.
- If feed override value does not change, the command is ignored. - If feed override value does not change, the command is ignored.
- Feed override range and increments may be changed in config.h. - Feed override range and increments may be changed in config.h.
- The commands are: - The commands are:
@ -112,7 +112,7 @@ Grbl v1.1 installed more than a dozen new realtime commands to control feed, rap
- Immediately alters the spindle speed override value. An active spindle speed is altered within tens of milliseconds. - Immediately alters the spindle speed override value. An active spindle speed is altered within tens of milliseconds.
- Override values may be changed at any time, regardless of if the spindle is enabled or disabled. - Override values may be changed at any time, regardless of if the spindle is enabled or disabled.
- Spindle override value can not be 50% or greater than 200% - Spindle override value can not be 10% or greater than 200%
- If spindle override value does not change, the command is ignored. - If spindle override value does not change, the command is ignored.
- Spindle override range and increments may be altered in config.h. - Spindle override range and increments may be altered in config.h.
- The commands are: - The commands are:

View File

@ -232,9 +232,9 @@ This sets the spindle speed for the minimum 0.02V PWM pin output (0V is disabled
#### $32 - Laser mode, boolean #### $32 - Laser mode, boolean
When enabled, Grbl will move continuously through consecutive `G1`, `G2`, or `G3` motion commands when programmed with a `S` spindle speed (laser power). The spindle PWM pin will be updated instantaneously through each motion without stopping. However, Grbl will still stop motion if a spindle state is commanded and altered, like `M3`, `M4`, or `M5`. If the spindle needs to be disabled while under continuous motion, program a `S0`, zero spindle speed, to disable the spindle with a supported motion command. When enabled, Grbl will move continuously through consecutive `G1`, `G2`, or `G3` motion commands when programmed with a `S` spindle speed (laser power). The spindle PWM pin will be updated instantaneously through each motion without stopping. Please read the Grbl laser documentation and your laser device documentation prior to using this mode. Lasers are very dangerous. They can instantly damage your vision permanantly and cause fires. Grbl does not assume any responsibility for any issues the firmware may cause, as defined by its GPL license.
When disabled, Grbl will operate as it always has, stopping motion with every `S` spindle speed command. This is the normal operating When disabled, Grbl will operate as it always has, stopping motion with every `S` spindle speed command. This is the default operation of a milling machine to allow a pause to let the spindle change speeds.
#### $100, $101 and $102 [X,Y,Z] steps/mm #### $100, $101 and $102 [X,Y,Z] steps/mm

View File

@ -251,7 +251,7 @@
#define DEFAULT_SPINDLE_SPEED_OVERRIDE 100 // 100%. Don't change this value. #define DEFAULT_SPINDLE_SPEED_OVERRIDE 100 // 100%. Don't change this value.
#define MAX_SPINDLE_SPEED_OVERRIDE 200 // Percent of programmed spindle speed (100-255). Usually 200%. #define MAX_SPINDLE_SPEED_OVERRIDE 200 // Percent of programmed spindle speed (100-255). Usually 200%.
#define MIN_SPINDLE_SPEED_OVERRIDE 50 // Percent of programmed spindle speed (1-100). Usually 50%. #define MIN_SPINDLE_SPEED_OVERRIDE 10 // Percent of programmed spindle speed (1-100). Usually 10%.
#define SPINDLE_OVERRIDE_COARSE_INCREMENT 10 // (1-99). Usually 10%. #define SPINDLE_OVERRIDE_COARSE_INCREMENT 10 // (1-99). Usually 10%.
#define SPINDLE_OVERRIDE_FINE_INCREMENT 1 // (1-99). Usually 1%. #define SPINDLE_OVERRIDE_FINE_INCREMENT 1 // (1-99). Usually 1%.

View File

@ -631,10 +631,9 @@ uint8_t gc_execute_line(char *line)
// [20. Motion modes ]: // [20. Motion modes ]:
if (gc_block.modal.motion == MOTION_MODE_NONE) { if (gc_block.modal.motion == MOTION_MODE_NONE) {
// [G80 Errors]: Axis word exist and are not used by a non-modal command. // [G80 Errors]: Axis word are programmed while G80 is active.
if ((axis_words) && (axis_command != AXIS_COMMAND_NON_MODAL)) { // NOTE: Even non-modal commands or TLO that use axis words will throw this strict error.
FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); // [No axis words allowed] if (axis_words) { FAIL(STATUS_GCODE_AXIS_WORDS_EXIST); } // [No axis words allowed]
}
// Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or // Check remaining motion modes, if axis word are implicit (exist and not used by G10/28/30/92), or
// was explicitly commanded in the g-code block. // was explicitly commanded in the g-code block.
@ -859,28 +858,24 @@ uint8_t gc_execute_line(char *line)
|| (gc_block.modal.motion == MOTION_MODE_CCW_ARC)) ) { || (gc_block.modal.motion == MOTION_MODE_CCW_ARC)) ) {
gc_parser_flags |= GC_PARSER_LASER_DISABLE; gc_parser_flags |= GC_PARSER_LASER_DISABLE;
} }
// M3 constant power laser requires planner syncs to update the laser in certain conditions.
// certain conditions. // Any motion mode with axis words is allowed to be passed from a spindle speed update.
// NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted.
// TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length).
if (axis_words && (axis_command == AXIS_COMMAND_MOTION_MODE)) {
gc_parser_flags |= GC_PARSER_LASER_ISMOTION;
} else {
// M3 constant power laser requires planner syncs to update the laser when changing between
// a G1/2/3 motion mode state and vice versa when there is no motion in the line.
if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) { if (gc_state.modal.spindle == SPINDLE_ENABLE_CW) {
if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC) if ((gc_state.modal.motion == MOTION_MODE_LINEAR) || (gc_state.modal.motion == MOTION_MODE_CW_ARC)
|| (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) { || (gc_state.modal.motion == MOTION_MODE_CCW_ARC)) {
if (gc_parser_flags & GC_PARSER_LASER_DISABLE) { if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) {
gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode. gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; // Change from G1/2/3 motion mode.
} else {
// Any non-motion block with M3 enabled and G1/2/3 modal state requires a sync when
// the spindle speed changes. It is otherwise passed onto the planner.
if (gc_state.spindle_speed != gc_block.values.s) {
// NOTE: A G1/2/3 motion will always have axis words and be in AXIS_COMMAND_MOTION_MODE.
// A non-motion G1 or any non-modal command using axis words will alter axis_command.
if (!(axis_words) || (axis_command != AXIS_COMMAND_MOTION_MODE )) {
gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC;
}
}
} }
} else { } else {
// When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode. // When changing to a G1 motion mode without axis words from a non-G1/2/3 motion mode.
if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_DISABLE)) {
if (!(axis_words) || (axis_command != AXIS_COMMAND_MOTION_MODE )) {
gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC; gc_parser_flags |= GC_PARSER_LASER_FORCE_SYNC;
} }
} }
@ -909,9 +904,11 @@ uint8_t gc_execute_line(char *line)
if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) { if ((gc_state.spindle_speed != gc_block.values.s) || bit_istrue(gc_parser_flags,GC_PARSER_LASER_FORCE_SYNC)) {
if (gc_state.modal.spindle != SPINDLE_DISABLE) { if (gc_state.modal.spindle != SPINDLE_DISABLE) {
#ifdef VARIABLE_SPINDLE #ifdef VARIABLE_SPINDLE
if (bit_isfalse(gc_parser_flags,GC_PARSER_LASER_ISMOTION)) {
if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) { if (bit_istrue(gc_parser_flags,GC_PARSER_LASER_DISABLE)) {
spindle_sync(gc_state.modal.spindle, 0.0); spindle_sync(gc_state.modal.spindle, 0.0);
} else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); } } else { spindle_sync(gc_state.modal.spindle, gc_block.values.s); }
}
#else #else
spindle_sync(gc_state.modal.spindle, 0.0); spindle_sync(gc_state.modal.spindle, 0.0);
#endif #endif

View File

@ -169,6 +169,7 @@
#define GC_PARSER_PROBE_IS_NO_ERROR bit(4) #define GC_PARSER_PROBE_IS_NO_ERROR bit(4)
#define GC_PARSER_LASER_FORCE_SYNC bit(5) #define GC_PARSER_LASER_FORCE_SYNC bit(5)
#define GC_PARSER_LASER_DISABLE bit(6) #define GC_PARSER_LASER_DISABLE bit(6)
#define GC_PARSER_LASER_ISMOTION bit(7)
// NOTE: When this struct is zeroed, the above defines set the defaults for the system. // NOTE: When this struct is zeroed, the above defines set the defaults for the system.

View File

@ -23,7 +23,7 @@
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "1.1e" #define GRBL_VERSION "1.1e"
#define GRBL_VERSION_BUILD "20161203" #define GRBL_VERSION_BUILD "20161204"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -363,8 +363,10 @@ ISR(TIMER1_COMPA_vect)
} else { } else {
// Segment buffer empty. Shutdown. // Segment buffer empty. Shutdown.
st_go_idle(); st_go_idle();
#ifdef VARIABLE_SPINDLE
// Ensure pwm is set properly upon completion of rate-controlled motion. // Ensure pwm is set properly upon completion of rate-controlled motion.
if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); } if (st.exec_block->is_pwm_rate_adjusted) { spindle_set_speed(SPINDLE_PWM_OFF_VALUE); }
#endif
system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end system_set_exec_state_flag(EXEC_CYCLE_STOP); // Flag main program for cycle end
return; // Nothing to do but exit. return; // Nothing to do but exit.
} }
@ -655,6 +657,7 @@ void st_prep_buffer()
prep.current_speed = sqrt(pl_block->entry_speed_sqr); prep.current_speed = sqrt(pl_block->entry_speed_sqr);
} }
#ifdef VARIABLE_SPINDLE
// Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the // Setup laser mode variables. PWM rate adjusted motions will always complete a motion with the
// spindle off. // spindle off.
st_prep_block->is_pwm_rate_adjusted = false; st_prep_block->is_pwm_rate_adjusted = false;
@ -665,6 +668,7 @@ void st_prep_buffer()
st_prep_block->is_pwm_rate_adjusted = true; st_prep_block->is_pwm_rate_adjusted = true;
} }
} }
#endif
} }
/* --------------------------------------------------------------------------------- /* ---------------------------------------------------------------------------------