Increment to v1.1a, minor compile bug fix, tweaked communication protocol, more docs.

- Incremented to v1.1a, rather than keep 1.0e. This is because there
are existing v1.0 installations. Don’t want to confuse people further.

- Certain version of the Arduino IDE did not like the `inline` in the
function header. Removed from spindle_control files to fix the problem.

- Tweaked the communication protocol slightly. Added message type
indicators for all `[]`bracketed feedback messages. It’s been
problematic for GUI dev to try to determine the context of a message
and how it should be handled. These indictors should help tremendously
to remove context all together.

- Also altered how `$N` startup lines are presented when executed. They
now start with an open chevron ‘>’ followed by the line and an ‘:ok’ to
indicate it executed. The ‘ok’ is on the same line intentionally so it
doesn’t mess up a streaming protocol counter.

- Managed to save a 100+KB from refactoring parts of report.c. (Thanks
Vasilis!) Freed up room to alter the protocol a little.

- Wrote a markdown document on interface messaging to make it clear how
it’s intended to work. See interface.md in /doc/markdown

- Started to pull in some Wiki pages from the old grbl site and
beginning to update them for v1.1.

- Created new commit log for v1.1.
This commit is contained in:
Sonny Jeon 2016-09-22 23:15:55 -06:00
parent 968e97f9ef
commit e51e691eeb
15 changed files with 1459 additions and 337 deletions

205
doc/log/commit_log_v1.1.txt Normal file
View File

@ -0,0 +1,205 @@
----------------
Date: 2016-09-22
Author: Sonny Jeon
Subject: Merge pull request #1 from winder/dev
Add locale to code CSVs.
----------------
Date: 2016-09-22
Author: winder
Subject: Add locale to code CSVs.
----------------
Date: 2016-09-21
Author: chamnit
Subject: Grbl v1.0e huge beta release. Overrides and new reporting.
- Feature: Realtime feed, rapid, and spindle speed overrides. These
alter the running machine state within tens of milliseconds!
- Feed override: 100%, +/-10%, +/-1% commands with values 1-200% of
programmed feed
- Rapid override: 100%, 50%, 25% rapid rate commands
- Spindle speed override: 100%, +/-10%, +/-1% commands with values
50-200% of programmed speed
- Override values have configurable limits and increments in
config.h.
- Feature: Realtime toggle overrides for spindle stop, flood coolant,
and optionally mist coolant
- Spindle stop: Enables and disables spindle during a feed hold.
Automatically restores last spindles state.
- Flood and mist coolant: Immediately toggles coolant state until
next toggle or g-code coolant command.
- Feature: Jogging mode! Incremental and absolute modes supported.
- Grbl accepts jogging-specific commands like $J=X100F50. An axis
word and feed rate are required. G20/21 and G90/G91 commands are
accepted.
- Jog motions can be canceled at any time by a feed hold `!`
command. The buffer is automatically flushed. (No resetting required).
- Jog motions do not alter the g-code parser state so GUIs dont
have to track what they changed and correct it.
- Feature: Laser mode setting. Allows Grbl to execute continuous
motions with spindle speed and state changes.
- Feature: Significantly improved status reports. Overhauled to cram in
more meaningful data and still make it smaller on average.
- All available data is now sent by default, but does not appear if
it doesnt change or is not active.
- Machine position(MPos) or work position(WPos) is reported but not
both at the same time. Instead, the work coordinate offsets (WCO)are
sent intermittently whenever it changes or refreshes after 10-30 status
reports. Position vectors are easily computed by WPos = MPos - WCO.
- All data has changed in some way. Details of changes are in the
markdown documents and wiki.
- Feature: 16 new realtime commands to control overrides. All in
extended-ASCII character space.
- While they are not easily typeable and requires a GUI, they cant
be accidentally triggered by some latent character in the g-code
program and have tons of room for expansion.
- Feature: New substates for HOLD and SAFETY DOOR. A `:x` is appended
to the state, where `x` is an integer and indicates a substate.
- For example, each integer of a door state describes in what phase
the machine is in during parking. Substates are detailed in the
documentation.
- Feature: With the alarm codes, homing and probe alarms have been
expanded with more codes to provide more exact feedback on what caused
the alarm.
- Feature: New hard limit check upon power-up or reset. If detected, a
feedback message to check the limit switches sent immediately after the
welcome message.
- May be disabled in config.h.
- OEM feature: Enable/disable `$RST=` individual commands based on
desired behavior in config.h.
- OEM feature: Configurable EEPROM wipe to prevent certain data from
being deleted during firmware upgrade to a new settings version or
`RST=*` command.
- OEM feature: Enable/disable the `$I=` build info write string with
external EEPROM write example sketch.
- This prevents a user from altering the build info string in
EEPROM. This requires the vendor to write the string to EEPROM via
external means. An Arduino example sketch is provided to accomplish
this. This would be useful for contain product data that is
retrievable.
- Tweak: All feedback has been drastically trimmed to free up flash
space for the v1.0 release.
- The `$` help message is just one string, listing available
commands.
- The `$$` settings printout no longer includes descriptions. Only
the setting values. (Sorry its this or remove overrides!)
- Grbl `error:` and `ALARM:` responses now only contain codes. No
descriptions. All codes are explained in documentation.
- Grbls old feedback style may be restored via a config.h, but
keep in mind that it will likely not fit into the Arduinos flash space.
- Tweak: Grbl now forces a buffer sync or stop motion whenever a g-code
command needs to update and write a value to EEPROM or changes the work
coordinate offset.
- This addresses two old issues in all prior Grbl versions. First,
an EEPROM write requires interrupts to be disabled, including stepper
and serial comm. Steps can be lost and data can be corrupted. Second,
the work position may not be correlated to the actual machine position,
since machine position is derived from the actual current execution
state, while work position is based on the g-code parser offset state.
They are usually not in sync and the parser state is several motions
behind. This forced sync ensures work and machine positions are always
correct.
- This behavior can be disabled through a config.h option, but its
not recommended to do so.
- Tweak: To make status reports standardized, users can no longer
change what is reported via status report mask, except for only
toggling machine or work positions.
- All other data fields are included in the report and can only be
disabled through the config.h file. Its not recommended to alter this,
because GUIs will be expecting this data to be present and may not be
compatible.
- Tweak: Homing cycle and parking motion no longer report a negative
line number in a status report. These will now not report a line number
at all.
- Tweak: New `[Restoring spindle]` message when restoring from a
spindle stop override. Provides feedback what Grbl is doing while the
spindle is powering up and a 4.0 second delay is enforced.
- Tweak: Override values are reset to 100% upon M2/30. This behavior
can be disabled in config.h
- Tweak: The planner buffer size has been reduced from 18 to 16 to free
up RAM for tracking and controlling overrides.
- Tweak: TX buffer size has been increased from 64 to 90 bytes to
improve status reporting and overall performance.
- Tweak: Removed the MOTION CANCEL state. It was redundant and didnt
affect Grbls overall operation by doing so.
- Tweak: Grbls serial buffer increased by +1 internally, such that 128
bytes means 128, not 127 due to the ring buffer implementation. Long
overdue.
- Tweak: Altered sys.alarm variable to be set by alarm codes, rather
than bit flags. Simplified how it worked overall.
- Tweak: Planner buffer and serial RX buffer usage has been combined in
the status reports.
- Tweak: Pin state reporting has been refactored to report only the
pins “triggered” and nothing when not “triggered”.
- Tweak: Current machine rate or speed is now included in every report.
- Tweak: The work coordinate offset (WCO) and override states only need
to be refreshed intermittently or reported when they change. The
refresh rates may be altered for each in the config.h file with
different idle and busy rates to lessen Grbls load during a job.
- Tweak: For temporary compatibility to existing GUIs until they are
updated, an option to revert back to the old style status reports is
available in config.h, but not recommended for long term use.
- Tweak: Removed old limit pin state reporting option from config.h in
lieu of new status report that includes them.
- Tweak: Updated the defaults.h file to include laser mode, altered
status report mask, and fix an issue with a missing invert probe pin
default.
- Refactor: Changed how planner line data is generated and passed to
the planner and onto the step generator. By making it a struct
variable, this saved significant flash space.
- Refactor: Major re-factoring of the planner to incorporate override
values and allow for re-calculations fast enough to immediately take
effect during operation. No small feat.
- Refactor: Re-factored the step segment generator for re-computing new
override states.
- Refactor: Re-factored spindle_control.c to accommodate the spindle
speed overrides and laser mode.
- Refactor: Re-factored parts of the codebase for a new jogging mode.
Still under development though and slated to be part of the official
v1.0 release. Hang tight.
- Refactor: Created functions for computing a unit vector and value
limiting based on axis maximums to free up more flash.
- Refactor: The spindle PWM is now set directly inside of the stepper
ISR as it loads new step segments.
- Refactor: Moved machine travel checks out of soft limits function
into its own since jogging uses this too.
- Refactor: Removed coolant_stop() and combined with
coolant_set_state().
- Refactor: The serial RX ISR forks off extended ASCII values to
quickly assess the new override realtime commands.
- Refactor: Altered some names of the step control flags.
- Refactor: Improved efficiency of the serial RX get buffer count
function.
- Refactor: Saved significant flash by removing and combining print
functions. Namely the uint8 base10 and base2 functions.
- Refactor: Moved the probe state check in the main stepper ISR to
improve its efficiency.
- Refactor: Single character printPgmStrings() went converted to direct
serial_write() commands to save significant flash space.
- Documentation: Detailed Markdown documents on error codes, alarm
codes, messages, new real-time commands, new status reports, and how
jogging works. More to come later and will be posted on the Wiki as
well.
- Documentation: CSV files for quick importing of Grbl error and alarm
codes.
- Bug Fix: Applied v0.9 master fixes to CoreXY homing.
- Bug Fix: The print float function would cause Grbl to crash if a
value was 1e6 or greater. Increased the buffer by 3 bytes to help
prevent this in the future.
- Bug Fix: Build info and startup string EEPROM restoring was not
writing the checksum value.
- Bug Fix: Corrected an issue with safety door restoring the proper
spindle and coolant state. It worked before, but breaks with laser mode
that can continually change spindle state per planner block.
- Bug Fix: Move system position and probe position arrays out of the
system_t struct. Ran into some compiling errors that were hard to track
down as to why. Moving them out fixed it.

View File

@ -105,20 +105,20 @@ Format - `(v1.0)` `:` `(v0.9)` - `Description`
Format - `Message` - `Description` Format - `Message` - `Description`
- `[Reset to continue]` - Critical event message. Reset is required before Grbl accepts any other commands. This prevents ongoing command streaming and risking a motion before the alarm is acknowledged. Hard or soft limit errors will trigger this event. - `[MSG:Reset to continue]` - Critical event message. Reset is required before Grbl accepts any other commands. This prevents ongoing command streaming and risking a motion before the alarm is acknowledged. Hard or soft limit errors will trigger this event.
- `[$H|$X to unlock]`- Alarm message at initialization. All g-code commands and some $ are blocked until unlocked via homing or $X. - `[MSG:$H|$X to unlock]`- Alarm message at initialization. All g-code commands and some $ are blocked until unlocked via homing or $X.
- `[Caution: Unlocked]` - Alarm unlock $X acknowledgement. - `[MSG:Caution: Unlocked]` - Alarm unlock $X acknowledgement.
- `[Enabled]` - Indicates Grbls check-mode is enabled. - `[MSG:Enabled]` - Indicates Grbls check-mode is enabled.
- `[Disabled]` - Indicates Grbls check-mode is disabled. Grbl is automatically reset afterwards. - `[MSG:Disabled]` - Indicates Grbls check-mode is disabled. Grbl is automatically reset afterwards.
- `[Check Door]` - Safety door detected as open. This message appears either immediately upon a safety door ajar or if the safety is open when Grbl initializes after a power-up/reset. - `[MSG:Check Door]` - Safety door detected as open. This message appears either immediately upon a safety door ajar or if the safety is open when Grbl initializes after a power-up/reset.
- `[Check Limits]` - If Grbl detects a limit switch is triggered after power-up/reset and hard limits are enabled, this will appear as a courtesy message. - `[MSG:Check Limits]` - If Grbl detects a limit switch is triggered after power-up/reset and hard limits are enabled, this will appear as a courtesy message.
- `[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: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.
- `[Restoring defaults]` - Acknowledgement message when restoring EEPROM defaults via a `$RST=` command. - `[MSG:Restoring defaults]` - Acknowledgement message when restoring EEPROM defaults via a `$RST=` command.

544
doc/markdown/interface.md Normal file
View File

@ -0,0 +1,544 @@
# Grbl Interface Basics
The interface for Grbl is fairly simple and straightforward. With Grbl v1.0, steps have been taken to try to make it even easier for new users to get started, and for GUI developers to write their own custom interfaces to Grbl.
In short, Grbl communicates through the serial interface on the Arduino. You just need to connect your Arduino to your computer with a USB cable. Use any standard serial terminal program to connect to Grbl, such as: the Arduino IDE serial monitor, Coolterm, puTTY, etc. Or use one of the many great Grbl GUIs out there in the Internet wild.
Just about every user interaction with Grbl is performed by sending it a string of characters, followed by a carriage return. Grbl will then process the string, execute it accordingly, and then reply back with a response message to tell you how it went. These strings include sending Grbl: a G-code block to execute, commands to configure Grbl's system settings, to view how Grbl is doing, etc. At times, Grbl may not respond immediately. This happens only when Grbl is busy doing something else, or waiting for some room to clear in its look-ahead planner buffer so it can finish processing the previous line sent.
In other words, both commands sent to Grbl and messages received from Grbl have a format of a single line of characters, terminated by a return. To provide more feedback on what Grbl is doing, additional messages may be "pushed" from Grbl to the user in response to a query or to let the user know something important just happened. Finally, an exception to the command and response interface are Grbl's real-time commands. These commands are single, special characters that may be sent to Grbl at any time to immediately alter or report what its doing and do not have a response message. See the [realtime commands] document to see what they are and how they work.
#### Start Up Message
**`Grbl vX.Xx ['$' for help]`**
The start up message always prints upon startup and after a reset. Whenever you see this message, this also means that Grbl has completed re-initializing all its systems, so everything starts out the same every time you use Grbl.
* `vX.Xx` indicates the major version number, followed by a minor version letter. The major version number indicates the general release, while the letter simply indicates a feature update or addition from the preceding minor version letter.
* Bug fix revisions are tracked by the build info version number, printed when an `$I` command is sent. These revisions don't update the version number and are given by date revised in year, month, and day, like so `20160820`.
#### Grbl `$` Help Message
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]
```
- _**NOTE:** Grbl v1.0'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. _
* Check out our [Configuring Grbl](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9) wiki page to find out what all of these commands mean and how to use them.
---------
# Grbl Response Messages
Every G-code block sent to Grbl and Grbl `$` system command that is terminated with a return will be parsed and processed by Grbl. Grbl will then respond either if it recognized the command with an `ok` line or if there was a problem with an `error` line.
* **`ok`**: All is good! Everything in the last line was understood by Grbl and was successfully processed and executed.
- If an empty line with only a return is sent to Grbl, it considers it a valid line and will return an `ok` too, except it didn't do anything.
* **`error:X`**: Something went wrong! Grbl did not recognize the command and did not execute anything inside that message. The `X` is given as a numeric error code to tell you exactly what happened. The table below decribes every one of them.
| ID | Error Code Description |
|:-------------:|----|
| **`1`** | G-code words consist of a letter and a value. Letter was not found. |
| **`2`** | Numeric value format is not valid or missing an expected value. |
| **`3`** | Grbl '$' system command was not recognized or supported. |
| **`4`** | Negative value received for an expected positive value. |
| **`5`** | Homing cycle is not enabled via settings. |
| **`6`** | Minimum step pulse time must be greater than 3usec |
| **`7`** | EEPROM read failed. Reset and restored to default values. |
| **`8`** | Grbl '$' command cannot be used unless Grbl is IDLE. Ensures smooth operation during a job. |
| **`9`** | G-code locked out during alarm or jog state |
| **`10`** | Soft limits cannot be enabled without homing also enabled. |
| **`11`** | Max characters per line exceeded. Line was not processed and executed. |
| **`12`** | (Compile Option) Grbl '$' setting value exceeds the maximum step rate supported. |
| **`13`** | Safety door detected as opened and door state initiated. |
| **`14`** | (Grbl-Mega Only) Build info or startup line exceeded EEPROM line length limit. |
| **`15`** | Jog target exceeds machine travel. Command ignored. |
| **`16`** | Jog command with no '=' or contains prohibited g-code. |
| **`20`** | Unsupported or invalid g-code command found in block. |
| **`21`** | More than one g-code command from same modal group found in block.|
| **`22`** | Feed rate has not yet been set or is undefined. |
| **`23`** | G-code command in block requires an integer value. |
| **`24`** | Two G-code commands that both require the use of the `XYZ` axis words were detected in the block.|
| **`25`** | A G-code word was repeated in the block.|
| **`26`** | A G-code command implicitly or explicitly requires `XYZ` axis words in the block, but none were detected.|
| **`27`**| `N` line number value is not within the valid range of `1` - `9,999,999`. |
| **`28`** | A G-code command was sent, but is missing some required `P` or `L` value words in the line. |
| **`29`** | Grbl supports six work coordinate systems `G54-G59`. `G59.1`, `G59.2`, and `G59.3` are not supported.|
| **`30`**| The `G53` G-code command requires either a `G0` seek or `G1` feed motion mode to be active. A different motion was active.|
| **`31`** | There are unused axis words in the block and `G80` motion mode cancel is active.|
| **`32`** | A `G2` or `G3` arc was commanded but there are no `XYZ` axis words in the selected plane to trace the arc.|
| **`33`** | The motion command has an invalid target. `G2`, `G3`, and `G38.2` generates this error, if the arc is impossible to generate or if the probe target is the current position.|
| **`34`** | A `G2` or `G3` arc, traced with the radius definition, had a mathematical error when computing the arc geometry. Try either breaking up the arc into semi-circles or quadrants, or redefine them with the arc offset definition.|
| **`35`** | A `G2` or `G3` arc, traced with the offset definition, is missing the `IJK` offset word in the selected plane to trace the arc.|
| **`36`** | There are unused, leftover G-code words that aren't used by any command in the block.|
| **`37`** | The `G43.1` dynamic tool length offset command cannot apply an offset to an axis other than its configured axis. The Grbl default axis is the Z-axis.|
----------------------
# Grbl Push Messages
Along with the response message to indicate successfully executing a line command sent to Grbl, Grbl provides additional push messages for important feedback of its current state or if something went horribly wrong. These messages are "pushed" from Grbl and may appear at anytime. They are usually in response to a user query or some system event that Grbl needs to tell you about immediately. These push messages are organized into four general classes:
- **_ALARM messages_** - Means an emergency mode has been enacted and shut down normal use.
- **_'$' settings messages_** - Contains the type and data value for a Grbl setting.
- **_Feedback messages_** - Contains general feedback and can provide useful data.
- **_Real-time status reports_** - Contains current run data like state, position, and speed.
------
#### Alarm Message
Alarm is an emergency state. Something has gone terribly wrong when these occur. Typically, they are caused by limit error when the machine has moved or wants to move outside the machine travel and crash into the ends. They also report problems if Grbl is lost and can't guarantee positioning or a probe command has failed. Once in alarm-mode, Grbl will lock out all g-code functionality and accept only a small set of commands. It may even stop everything and force you to acknowledge the problem until you issue Grbl a reset. While in alarm-mode, the user can override the alarm manually with a specific command, which then re-enables g-code so you can move the machine again. This ensures the user knows about the problem and has taken steps to fix or account for it.
Similar to error messages, all alarm messages are sent as **`ALARM:X`**, where `X` is an alarm code to tell you exacly what caused the alarm. The table below describes the meaning of each alarm code.
| ID | Alarm Code Description |
|:-------------:|----|
| **`1`** | Hard limit triggered. Machine position is likely lost due to sudden and immediate halt. Re-homing is highly recommended. |
| **`2`** | G-code motion target exceeds machine travel. Machine position safely retained. Alarm may be unlocked. |
| **`3`** | Reset while in motion. Grbl cannot guarantee position. Lost steps are likely. Re-homing is highly recommended. |
| **`4`** | Probe fail. The probe is not in the expected initial state before starting probe cycle, where G38.2 and G38.3 is not triggered and G38.4 and G38.5 is triggered. |
| **`5`** | Probe fail. Probe did not contact the workpiece within the programmed travel for G38.2 and G38.4. |
| **`6`** | Homing fail. Reset during active homing cycle. |
| **`7`** | Homing fail. Safety door was opened during active homing cycle. |
| **`8`** | Homing fail. Cycle failed to clear limit switch when pulling off. Try increasing pull-off setting or check wiring. |
| **`9`** | Homing fail. Could not find limit switch within search distance. Defined as `1.5 * max_travel` on search and `5 * pulloff` on locate phases. |
-------
#### Grbl `$` Settings Message
When a push message starts with a `$`, this indicates Grbl is sending a setting and its configured value. There are only two types of settings messages: a single setting and value `$x=val` and a startup string setting `$Nx=line`. See [Configuring Grbl v1.x] document if you'd like to learn how to write these values for your machine.
- `$x=val` will only appear when the user queries to print all of Grbl's settings via the `$$` print settings command. It does so sequentially and completes with an `ok`.
- In prior versions of Grbl, the `$` settings included a short description of the setting immediately after the value. However, due to flash restrictions, most human-readable strings were removed to free up flash for the new override features in Grbl v1.0. In short, it was these strings or overrides, and overrides won. Keep in mind that once these values are set, they usually don't change, and GUIs will likely provide the assistance of translating these codes for users.
- _**NOTE for GUI developers:** As with the error and alarm codes, settings codes are available in an easy to parse CSV file in the `/doc/csv` folder. These are continually updated._
- The `$$` settings print out is shown below and the following describes each setting.
```
$0=10
$1=25
$2=0
$3=0
$4=0
$5=0
$6=0
$10=255
$11=0.010
$12=0.002
$13=0
$20=0
$21=0
$22=0
$23=0
$24=25.000
$25=500.000
$26=250
$27=1.000
$30=1000.
$31=0.
$32=0
$100=250.000
$101=250.000
$102=250.000
$110=500.000
$111=500.000
$112=500.000
$120=10.000
$121=10.000
$122=10.000
$130=200.000
$131=200.000
$132=200.000
ok
```
| `$x` Code | Setting Description, Units |
|:-------------:|----|
| **`0`** | Step pulse time, microseconds |
| **`1`** | Step idle delay, milliseconds |
| **`2`** | Step pulse invert, mask |
| **`3`** | Step direction invert, mask |
| **`4`** | Invert step enable pin, boolean |
| **`5`** | Invert limit pins, boolean |
| **`6`** | Invert probe pin, boolean |
| **`10`** | Status report options, mask |
| **`11`** | Junction deviation, millimeters |
| **`12`** | Arc tolerance, millimeters |
| **`13`** | Report in inches, boolean |
| **`20`** | Soft limits enable, boolean |
| **`21`** | Hard limits enable, boolean |
| **`22`** | Homing cycle enable, boolean |
| **`23`** | Homing direction invert, mask |
| **`24`** | Homing locate feed rate, mm/min |
| **`25`** | Homing search seek rate, mm/min |
| **`26`** | Homing switch debounce delay, milliseconds |
| **`27`** | Homing switch pull-off distance, millimeters |
| **`30`** | Maximum spindle speed, RPM |
| **`31`** | Minimum spindle speed, RPM |
| **`32`** | Laser-mode enable, boolean |
| **`100`** | X-axis steps per millimeter |
| **`101`** | Y-axis steps per millimeter |
| **`102`** | Z-axis steps per millimeter |
| **`110`** | X-axis maximum rate, mm/min |
| **`111`** | Y-axis maximum rate, mm/min |
| **`112`** | Z-axis maximum rate, mm/min |
| **`120`** | X-axis acceleration, mm/sec^2 |
| **`121`** | Y-axis acceleration, mm/sec^2 |
| **`122`** | Z-axis acceleration, mm/sec^2 |
| **`130`** | X-axis maximum travel, millimeters |
| **`131`** | Y-axis maximum travel, millimeters |
| **`132`** | Z-axis maximum travel, millimeters |
- The other `$Nx=line` message is the print-out of a user-defined startup line, where `x` denotes the startup line order and ranges from `0` to `1` by default. The `line` denotes the startup line to be executed by Grbl upon reset or power-up, except during an ALARM.
- When a user queries for the startup lines via a `$N` command, the following is sent by Grbl and completed by an `ok` response. The first line sets the initial startup work coordinate system to `G54`, while the second line is empty and does not execute.
```
$N0=G54
$N1=
ok
```
------
#### Feedback Messages
Feedback messages provide non-critical information on what Grbl is doing, what it needs, and/or provide some non-real-time data for the user when queried. Not too complicated. Feedback message are always enclosed in `[]` brackets, except for the startup line execution message which begins with an open chevron character `>`.
- **Non-Queried Feedback Messages:** These feedback messages that may appear at any time and is not part of a query are listed and described below. These always start with a `[MSG:` to denote their type.
- `[MSG:Reset to continue]` - Critical event message. Reset is required before Grbl accepts any other commands. This prevents ongoing command streaming and risking a motion before the alarm is acknowledged. Hard or soft limit errors will trigger this event.
- `[MSG:$H|$X to unlock]`- Alarm message at initialization. All g-code commands and some $ are blocked until unlocked via homing or $X.
- `[MSG:Caution: Unlocked]` - Alarm unlock $X acknowledgement.
- `[MSG:Enabled]` - Indicates Grbls check-mode is enabled.
- `[MSG:Disabled]` - Indicates Grbls check-mode is disabled. Grbl is automatically reset afterwards.
- `[MSG:Check Door]` - Safety door detected as open. This message appears either immediately upon a safety door ajar or if the safety is open when Grbl initializes after a power-up/reset.
- `[MSG:Check Limits]` - If Grbl detects a limit switch is triggered after power-up/reset and hard limits are enabled, this will appear as a courtesy message.
- `[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]` - Acknowledgement message when restoring EEPROM defaults via a `$RST=` command.
- **Queried Feedback Messages:**
- `[GC:]` G-code Parser State Message
- Initiated by the user via a `$G` command. Grbl replies as follows, where the `[GC:` denotes the message type and is followed by an `ok` to confirm the `$G` was executed.
- `[GC:G0 G54 G17 G21 G90 G94 M0 M5 M9 T0 F0. S0.]`
- The shown g-code are the current modal states of Grbl's g-code parser. This may not correlate to what is executing since there are usually several motions queued in the planner buffer.
- `[HLP:]` : Indicates the help message queried by a `$` command.
- The `$#` print parameter data query produces a large set of data which shown below and completed by an `ok` response message.
- Each line of the printout is starts with the data type, a `:`, and followed by the data values. If there is more than one, the order is XYZ axes, separated by commas.
```
[G54:0.000,0.000,0.000]
[G55:0.000,0.000,0.000]
[G56:0.000,0.000,0.000]
[G57:0.000,0.000,0.000]
[G58:0.000,0.000,0.000]
[G59:0.000,0.000,0.000]
[G28:0.000,0.000,0.000]
[G30:0.000,0.000,0.000]
[G92:0.000,0.000,0.000]
[TLO:0.000]
[PRB:0.000,0.000,0.000:0]
ok
```
- The `PRB:` probe parameter message includes an additional `:` and suffix value is a boolean. It denotes whether the last probe cycle was successful or not.
- `[VER:]` : Indicates build info and string from a `$I` user query.
- `[echo:]` : Indicates an automated line echo from a pre-parsed string prior to g-code parsing. Enabled by config.h option.
- **Startup Line Execution:**
- `>G54G20:ok` : The open chevron indicates a startup line has just executed. The startup line `G54G20` immediately follows the `>` character and is followed by an 'ok' response to indicate it executed successfully.
- A startup line will execute upon initialization only if a line is present and if Grbl is not in an alarm state.
- The `:ok` on the same line is intentional. It prevents this `ok` response from being counted as part of a stream, because it is not tied to a sent command, but an internally-generated one.
- There should always be an appended `:ok` because the startup line is checked for validity before it is stored in EEPROM. In the event that it's not, Grbl will print `>G54G20:error:X`, where `X` is the error code explaining why the startup line failed to execute.
- In the rare chance that there is an EEPROM read error, the startup line execution will print `>:error:7` with no startup line and a error code `7` for a read fail.
------
#### Real-time Status reports
- Contains real-time data of Grbls state, position, and other data required independently of the stream.
- Categorized as a real-time message, where it is a separate message that should not be counted as part of the streaming protocol. It may appear at any given time.
- A status report is initiated by sending Grbl a '?' character.
- Like all real-time commands, the '?' character is intercepted and never enters the serial buffer. It's never a part of the stream and can be sent at any time.
- Grbl will generate and transmit a report within ~5-20 milliseconds.
- Every ? command sent by a GUI is not guaranteed with a response. The following are the current scenarios when Grbl may not immediately or ignore a status report request. _NOTE: These may change in the future and will be documented here._
- If two or more '?' queries are sent before the first report is generated, the additional queries are ignored.
- A soft-reset commanded clears the last status report query.
- When Grbl throws a critical alarm from a limit violation. A soft-reset is required to resume operation.
- During a homing cycle.
- **Message Construction:**
- A message is a single line of ascii text, completed by a carriage return and line feed.
- `< >` Chevrons uniquely enclose reports to indicate message type.
- `|` Pipe delimiters separate data fields inside the report.
- The first data field is an exception to the following data field rules. See 'Machine State' description for details.
- All remaining data fields consist of a data type followed by a `:` colon delimiter and data values. `type:value(s)`
- Data values are given either as as one or more pre-defined character codes to indicate certain states/conditions or as numeric values, which are separated by a `,` comma delimiter when more than one is present. Numeric values are also in a pre-defined order and units of measure.
- The first (Machine State) and second (Current Position) data fields are always included in every report.
- Assume any following data field may or may not exist and can be in any order. The `$10` status report mask setting can alter what data is present and certain data fields can be reported intermittently (see descriptions for details.)
- The `$13` report inches settings alters the units of some data values. `$13=0` false indicates mm-mode, while `$13=1` true indicates inch-mode reporting. Keep note of this setting and which report values can be altered.
- **Data Field Descriptions:**
- **Machine State:**
- Valid states types: `Idle, Run, Hold, Jog, Alarm, Door, Check, Home`
- Sub-states may be included via `:` a colon delimiter and numeric code.
- Current sub-states are:
- `Hold:0` Hold complete. Ready to resume.
- `Hold:1` Hold in-progress. Reset will throw an alarm.
- `Door:0` Door closed. Ready to resume.
- `Door:1` Machine stopped. Door still ajar. Can't resume until closed.
- `Door:2` Door opened. Hold (or parking retract) in-progress. Reset will throw an alarm.
- `Door:3` Door closed and resuming. Restoring from park, if applicable. Reset will throw an alarm.
- This data field is always present as the first field.
- **Current Position:**
- Depending on `$10` status report mask settings, position may be sent as either:
- `MPos:0.000,-10.000,5.000` machine position or
- `WPos:-2.500,0.000,11.000` work position
- Three position values are given in the order of X, Y, and Z. A fourth position value may exist in later versions for the A-axis.
- `$13` report inches user setting effects these values and is given as either mm or inches.
- This data field is always present as the second field.
- **Work Coordinate Offset:**
- `WCO:0.000,1.551,5.664` is the current work coordinate offset of the g-code parser, which is the sum of the current work coordinate system, G92 offsets, and G43.1 tool length offset.
- Machine position and work position are related by this simple equation per axis: `WPos = MPos - WCO`
- Values are given in the order of the X,Y, and Z axes offsets. A fourth offset value may exist in later versions for the A-axis.
- `$13` report inches user setting effects these values and is given as either mm or inches.
- `WCO:` values don't change often during a job once set and only requires intermittent refreshing.
- This data field appears:
- In every 10 or 30 (configurable 1-255) status reports, depending on if Grbl is in a motion state or not.
- Immediately in the next report, if an offset value has changed.
- In the first report after a reset/power-cycle.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The refresh counter is in-between intermittent reports.
- **Buffer State:**
- `Bf:0,0`. The first value is planner blocks in use and the second is RX bytes in use.
- This data field will not appear if:
- It is disabled by the `$` status report mask setting.
- **Line Number:**
- `Ln:99999` indicates line 99999 is currently being executed. This differs from the `$G` line `N` value since the parser is usually queued few blocks behind execution.
- Compile-time option only because of memory requirements. However, if a GUI passes indicator line numbers onto Grbl, it's very useful to determine when Grbl is executing them.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The line number reporting not enabled in config.h. Different option to reporting data field.
- No line number or `N0` is passed with the g-code block.
- Grbl is homing, jogging, parking, or performing a system task/motion.
- There is no motion in the g-code block like a `G4P1` dwell. (May be fixed in later versions.)
- **Current Rate:**
- `F:1000.` indicates current actual feed rate (speed) of the executing motion. Depending on machine max rate settings and acceleration, this value may not be the programmed rate.
- Value units, either in mm/min or inches/min, is dependent on the `$` report inches user setting.
- As a operational note, reported rate is typically 30-50 msec behind actual position reported.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- **Input Pin State:**
- `Pn:XYZPDHRS` indicates which input pins Grbl has detected as 'triggered'.
- Pin state is evaluated every time a status report is generated. All input pin inversions are appropriately applied to determine 'triggered' states.
- Each letter of `XYZPDHRS` denotes a particular 'triggered' input pin.
- `X Y Z` XYZ limit pins, respectively
- `P` the probe pin.
- `D H R S` the door, hold, soft-reset, and cycle-start pins, respectively.
- Example: `Pn:PZ` indicates the probe and z-limit pins are 'triggered'.
- Note: `A` may be added in later versions for an A-axis limit pin.
- Assume input pin letters are presented in no particular order.
- One or more 'triggered' pin letter(s) will always be present with a `Pn:` data field.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- No input pins are detected as triggered.
- **Override Values:**
- `Ov:100,100,100` indicates current override values in percent of programmed values for feed, rapids, and spindle speed, respectively.
- Override values don't change often during a job once set and only requires intermittent refreshing. This data field appears:
- After 10 or 20 (configurable 1-255) status reports, depending on is in a motion state or not.
- If an override value has changed, this data field will appear immediately in the next report. However, if `WCO:` is present, this data field will be delayed one report.
- In the second report after a reset/power-cycle.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The override refresh counter is in-between intermittent reports.
- `WCO:` exists in current report during refresh. Automatically set to try again on next report.
- **Toggle Overrides:**
- `T:SFM` indicates a toggle override is in effect or has been commanded.
- Like the pin state field, each letter denotes a particular toggle override.
- `S` indicates the spindle stop toggle override is in effect. It will appear as long as the spindle stop override is active.
- `F` indicates the flood coolant toggle override was activated. It will only appear once after it has executed the coolant state change.
- `M` indicates the mist coolant toggle override was activated, if mist coolant is enabled via config.h. It will only appear once after it has executed the coolant state change.
- Assume toggle override letters are presented in no particular order.
- One or more active toggle override letter(s) will always be present with a `T:` data field.
- This data field appears:
- If a toggle override is active or has recently executed and only when the override values field is also present (see override value field rules).
- This data field will not appear if:
- If no toggle override is active or has been executed.
- It is disabled in the config.h file. No `$` mask setting available.
- If override refresh counter is in-between intermittent reports.
- `WCO:` exists in current report during refresh. Automatically set to try again on next report.
-------
# Message Summary
Grbl v1.0's interface protocol has been tweaked in the attempt to make GUI development cleaner, clearer, and hopefully easier. All messages are designed to be deterministic without needing to know the context of the message. Each can be inferred to a much greater degree than before just by the message type, which are all listed below.
- `ok` / `error:x` : Normal send command and execution response acknowledgement. Used for streaming.
- `< >` : Enclosed chevrons contains status report data.
- `Grbl vX.Xx ['$' for help]` : Welcome message indicates initialization.
- `ALARM:x` : Indicates an alarm has been thrown. Grbl is now in an alarm state.
- `$x=val` and `$Nx=line` indicate a settings printout from a `$` and `$N` user query, respectively.
- `[MSG:]` : Indicates a non-queried feedback message.
- `[GC:]` : Indicates a queried `$G` g-code state message.
- `[HLP:]` : Indicates the help message.
- `[G54:]`, `[G55:]`, `[G56:]`, `[G57:]`, `[G58:]`, `[G59:]`, `[G28:]`, `[G30:]`, `[G92:]`, `[TLO:]`, and `[PRB:]` messages indicate the parameter data printout from a `$#` user query.
- `[VER:]` : Indicates build info and string from a `$I` user query.
- `[echo:]` : Indicates an automated line echo from a pre-parsed string prior to g-code parsing. Enabled by config.h option.
- `>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.0 goes to master, please do immediately so we can all vet the new alteration before its installed.

View File

@ -0,0 +1,105 @@
***
# Writing an Interface for Grbl
_**FOR DEVELOPERS ONLY: This section outlines the recommended ways to setup a communications and streaming protocol with Grbl for a GUI.**_
The general interface for Grbl has been described above, but what's missing is how to run an entire G-code program on Grbl, when it doesn't seem to have an upload feature. Or, how to build a decent GUI with real-time feedback. This is where this section fits in. Early on, users fiercely requested for flash drive, external RAM, LCD support, joysticks, or network support so they can upload a g-code program and run it directly on Grbl. The general answer to that is, good ideas, but Grbl doesn't need them. Grbl already has nearly all of the tools and features to reliably communicate with a simple graphical user interface (GUI). Plus, we want to minimize as much as we can on what Grbl should be doing, because, in the end, Grbl needs to be concentrating on producing clean, reliable motion. That's it.
## Streaming a G-Code Program to Grbl
Here we will describe three different streaming methods for Grbl GUIs, but really there's only two that we recommend using. One of the main problems with streaming to Grbl is the USB port itself. Arduinos and most all micro controllers use a USB-to-serial converter chip that, at times, behaves strangely and not typically how you'd expect, like USB packet buffering and delays that can wreak havoc to a streaming protocol. Another problem is how to deal with some of the latency and oddities of the PCs themselves, because none of them are truly real-time and always create micro-delays when executing other tasks. Regardless, we've come up with ways to ensure the G-code stream is reliable and simple.
#### Streaming Protocol: Simple Send-Response _[Recommended for Grbl v0.9+]_
The send-response streaming protocol is the most fool-proof and simplest method to stream a G-code program to Grbl. The host PC interface simply sends a line of G-code to Grbl and waits for an `ok` or `error:` response before sending the next line of G-code. So, no matter if Grbl needs to wait for room in the look-ahead planner buffer to finish parsing and executing the last line of G-code or if the the host computer is busy doing something, this guarantees both to the host PC and Grbl, the programmed G-code has been sent and received properly. An example of this protocol is published in our `simple_stream.py` script in our repository.
However, it's also the slowest of three outlined streaming protocols. Grbl essentially has two buffers between the execution of steps and the host PC interface. One of them is the serial receive buffer. This briefly stores up to 127 characters of data received from the host PC until Grbl has time to fetch and parse the line of G-code. The other buffer is the look-ahead planner buffer. This buffer stores up to 17 line motions that are acceleration-planned and optimized for step execution. Since the send-response protocol receives a line of G-code while the host PC waits for a response, Grbl's serial receive buffer is usually empty and under-utilized. If Grbl is actively running and executing steps, Grbl will immediately begin to execute and empty the look-ahead planner buffer, while it sends the response to the host PC, waits for the next line from the host PC, upon receiving it, parse and plan it, and add it to the end of the look-ahead buffer.
Although this communication lag may take only a fraction of a second, there is a cumulative effect, because there is a lag with every G-code block sent to Grbl. In certain scenarios, like a G-code program containing lots of sequential, very short, line segments with high feed rates, the cumulative lag can be large enough to empty and starve the look-ahead planner buffer within this time. This could lead to start-stop motion when the streaming can't keep up with G-code program execution. Also, since Grbl can only plan and optimize what's in the look-ahead planner buffer, the performance through these types of motions will never be full-speed, because look-ahead buffer will always be partially full when using this streaming method. If your expected application doesn't contain a lot of these short line segments with high feed rates, this streaming protocol should be more than adequate for a vast majority of applications, is very robust, and is a quick way to get started. However, we do not recommend using this method for Grbl versions v0.8 or prior due to some performance issues with these versions.
#### Streaming Protocol: Via Flow Control (XON/XOFF)
To avoid the risk of starving the look-ahead planner buffer, a flow control streaming protocol can be used to try to keep Grbl's serial receive buffer full, so that Grbl has immediate access to the next g-code line to parse and plan without having to wait for the host PC to send it. Flow control, also known as XON/XOFF software flow control, uses two special characters to tell the host PC when it has or doesn't have room in the serial receive buffer to receive more data. When there is room, usually at 20% full, the special character is sent to the host PC indicating ready-to-receive. The host PC will begin to send data until it receives the other stop-receive special character, usually at 80% full. Grbl's XON/XOFF software flow control feature may be enabled through the config.h, but is not officially supported for the following reasons.
While sound in logic, software flow control has a number of problems. The timing between Grbl and the host PC is almost never perfectly in sync, in large part due to the USB protocol and the USB-serial converter chips on every Arduino. This poses a big problem when sending and receiving these special flow-control characters. When Grbl's serial receive buffer is low, the time between when it sends the ready-to-receive character and when the host PC sends more data all depends everything in between. If the host PC is busy or the Arduino USB-serial converter is not sending the character on time, this lag can cause Grbl to wait for more serial data to come in before parsing and executing the next line of G-code. Even worse though, if the serial receive buffer is nearing full and the stop-receive character is sent, the host PC may not receive the signal in time to stop the data transfer and over-flow Grbl's serial buffer. This is bad and will corrupt the data stream.
Because the software flow-control method is dependent on the performance of the USB-serial converter on the Arduino and the host PC, the low and high watermarks for the ready-to-receive and stop-receive characters must be tuned for each case. Thus, it's not really a robust solution. In our experience with XON/XOFF software flow control, it absolutely **DOES NOT** work with Arduinos with the Atmega8U/16U USB-serial converter chips (on all current Arduinos from the Uno to Mega2560). For some reason, there are USB packet delays that are out of Grbl's control and almost always led to data corruption. However, XON/XOFF worked, but only on older Arduinos or micro controllers that featured an FTDI RS232 USB-serial converter chip, such as the Duemilanove or controllers with an FTDI break-out board. The FTDI's firmware reliably sent the XON/XOFF special characters in time and on time. We're not sure why there is such a difference between them.
If you decide to use XON/XOFF software flow control for your GUI, keep in mind that, at the moment, it'll only really works with FTDI USB-serial converters. But, the great thing about this method is that you can connect with Grbl over a serial emulator program like Coolterm, enable XON/XOFF flow control, cut-and-paste an entire g-code program into it, and Grbl will execute it completely. (Nice but not really necessary.)
#### Streaming Protocol: Character-Counting _[**Recommended with Reservations**]_
To get the best of both worlds, the simplicity and reliability of the send-response method and assurance of maximum performance with software flow control, we came up with a simple character-counting protocol for streaming a G-code program to Grbl. It works like the send-response method, where the host PC sends a line of G-code for Grbl to execute and waits for a response, but, rather than needing special XON/XOFF characters for flow control, this protocol simply uses Grbl's responses as a way to reliably track how much room there is in Grbl's serial receive buffer. An example of this protocol is outlined in the `stream.py` streaming script in our repo.
The main difference between this protocol and the others is the host PC needs to maintain a standing count of how many characters it has sent to Grbl and then subtract the number of characters corresponding to the line executed with each Grbl response. Suppose there is a short G-code program that has 5 lines with 25, 40, 31, 58, and 20 characters (counting the line feed and carriage return characters too). We know Grbl has a 127 character serial receive buffer, and the host PC can send up to 127 characters without overflowing the buffer. If we let the host PC send as many complete lines as we can without over flowing Grbl's serial receive buffer, the first three lines of 25, 40, and 31 characters can be sent for a total of 96 characters. When Grbl responds, we know the first line has been processed and is no longer in the serial read buffer. As it stands, the serial read buffer now has the 40 and 31 character lines in it for a total of 71 characters. The host PC needs to then determine if it's safe to send the next line without overflowing the buffer. With the next line at 58 characters and the serial buffer at 71 for a total of 129 characters, the host PC will need to wait until more room has cleared from the serial buffer. When the next Grbl response comes in, the second line has been processed and only the third 31 character line remains in the serial buffer. At this point, it's safe to send the remaining last two 58 and 20 character lines of the g-code program for a total of 109.
While seemingly complicated, this character-counting streaming protocol is extremely effective in practice. It always ensures Grbl's serial read buffer is filled, while never overflowing it. It maximizes Grbl's performance by keeping the look-ahead planner buffer full by better utilizing the bi-directional data flow of the serial port, and it's fairly simple to implement as our `stream.py` script illustrates. We have stress-tested this character-counting protocol to extremes and it has not yet failed. Seemingly, only the speed of the serial connection is the limit.
_UPDATE: Up until recently, we've recommended that Grbl GUIs use this streaming protocol. It is indeed very efficient and effective, but there are a couple of additional things interface writers should aware of. These are issues being worked on for the v1.0 release._
- _Since the GUI is preloading Grbl's serial RX buffer with commands, Grbl will continually execute all of the queued g-code in the RX serial buffer. The first problem is if there is an error at the beginning of the RX buffer, Grbl will continue to execute the remaining buffered g-code and the GUI won't be able to control what happens. The interim solution is to check all of the g-code via the $C check mode, so all errors are vetted prior to streaming._
- _When Grbl stores data to EEPROM, the AVR requires all interrupts to be disabled during this write process, including the serial RX ISR. This means that if a g-code or Grbl `$` command writes to EEPROM, the data sent during the write may be lost. This is usually rare and typically occurs when streaming a G10 command inappropriately inside a program. For robustness, GUIs should track and detect these EEPROM write commands and handle them appropriately by waiting for the queue to finish executing before sending more data. Note that the simple send-response protocol doesn't not suffer from this issue._
## Interacting with Grbl's Systems
Along with streaming a G-code program, there a few more things to consider when writing a GUI for Grbl, such as how to use status reporting, real-time control commands, dealing with EEPROM, and general message handling.
#### Status Reporting
When a `?` character is sent to Grbl (no additional line feed or carriage return character required), it will immediately respond with something like `<Idle,MPos:0.000,0.000,0.000,WPos:0.000,0.000,0.000>` to report its state and current position. The `?` is always picked-off and removed from the serial receive buffer whenever Grbl detects one. So, these can be sent at any time. Also, to make it a little easier for GUIs to pick up on status reports, they are always encased by `<>` chevrons.
Developers can use this data to provide an on-screen position digital-read-out (DRO) for the user and/or to show the user a 3D position in a virtual workspace. We recommend querying Grbl for a `?` real-time status report at no more than 5Hz. 10Hz may be possible, but at some point, there are diminishing returns and you are taxing Grbl's CPU more by asking it to generate and send a lot of position data.
Grbl's status report is fairly simply in organization. It always starts with a word describing the machine state like `IDLE` (descriptions of these are available elsewhere in the Wiki). The following data values are usually in the order listed below and separated by commas, but may not be in the exact order or printed at all. Report output depends on the user's `$10` status report mask setting.
* `MPos:0.000,0.000,0.000` : Machine position listed as `X,Y,Z` coordinates. Units (mm or inch) depends on `$13` Grbl unit reporting setting.
* `WPos:0.000,0.000,0.000` : Work position listed as `X,Y,Z` coordinates. Units (mm or inch) depends on `$13` Grbl unit reporting setting.
* `Buf:0` : Number of motions queued in Grbl's planner buffer.
* `RX:0` : Number of characters queued in Grbl's serial RX receive buffer.
#### Real-Time Control Commands
The real-time control commands, `~` cycle start/resume, `!` feed hold, and `^X` soft-reset, all immediately signal Grbl to change its running state. Just like `?` status reports, these control characters are picked-off and removed from the serial buffer when they are detected and do not require an additional line-feed or carriage-return character to operate.
#### EEPROM Issues
EEPROM access on the Arduino AVR CPUs turns off all of the interrupts while the CPU reads and writes to EEPROM. This poses a problem for certain features in Grbl, particularly if a user is streaming and running a g-code program, since it can pause the main step generator interrupt from executing on time. Most of the EEPROM access is restricted by Grbl when it's in certain states, but there are some things that developers need to know.
* Settings can't be streamed to Grbl with either the XON/XOFF software flow control or the character-counting streaming protocols. Only the simple send-response protocol works. This is because during the EEPROM write, the AVR CPU also shuts-down the serial RX interrupt, which means data can get corrupted or lost. Note that the send-response protocol doesn't send any data until a response comes back.
* When changing work coordinates, printing `$#` parameters, or accessing the `G28`/`G30` predefined positions, Grbl has to fetch them from EEPROM. There is a small chance this access can pause the stepper or serial receive interrupt long enough to cause motion issues, but since it only fetches 12 bytes at a time at 2 cycles per fetch, the chances are very small that this will do anything to how Grbl runs. We just suggest keeping an eye on this and report to us any issues you might think are related to this.
For reference:
* Grbl's EEPROM write commands: `G10 L2`, `G10 L20`, `G28.1`, `G30.1`, `$x=`, `$I=`, `$Nx=`, `$RST=`
* Grbl's EEPROM read commands: `G54-G59`, `G28`, `G30`, `$$`, `$I`, `$N`, `$#`
#### Message Handling
Most of the feedback from Grbl fits into nice categories so GUIs can easily tell what is what. Here's how they are organized:
* `ok`: Standard all-is-good response to a single line sent to Grbl.
* `error:`: Standard error response to a single line sent to Grbl.
* `ALARM:`: A critical error message that occurred. All processes stopped until user acknowledgment.
* `[]`: All feedback messages are sent in brackets. These include parameter and g-code parser state print-outs.
* `<>`: Status reports are sent in chevrons.
There are few things that don't fit neatly into this setup at the moment. In the next version, we'll try to make this more universal, but for now, your GUIs will need to manually account for these:
* The startup message.
* `$` Help print-out.
* `$N` Start-up blocks execution after the startup message.
* The `$$` view Grbl settings print-out.
#### G-code Error Handling
As of Grbl v0.9, the g-code parser is fully standards-compilant with complete error-checking. When a G-code parser detects an error in a G-code block/line, the parser will dump everything in the block from memory and report an `error:` back to the user or GUI. This dump can pose problematic, because the bad G-code block may have contained some valuable positioning commands or feed rate settings.
It's highly recommended to do what all professional CNC controllers do when they detect an error in the G-code program, _**halt**_. Don't do anything further until the user has modified the G-code and fixed the error in their program. Otherwise, bad things could happen.
As a service to GUIs, Grbl has a "check G-code" mode, enabled by the `$C` system command. GUIs can stream a G-code program to Grbl, where it will parse it, error-check it, and report `ok`'s and `errors:`'s without powering on anything or moving. So GUIs can pre-check the programs before streaming them for real. To disable the "check G-code" mode, send another `$C` system command and Grbl will automatically soft-reset to flush and re-initialize the G-code parser and the rest of the system. This perhaps should be run in the background when a user first loads a program, before a user sets up his machine. This flushing and re-initialization clears `G92`'s by G-code standard, which some users still incorrectly use to set their part zero.
#### Jogging
Unfortunately, Grbl doesn't have a proper jogging interface, at least for now. This was to conserve precious flash space for the development of Grbl v0.9, but may be installed in the next release of Grbl. However, authors of Grbl GUIs have come up with ways to simulate jogging with Grbl by sending incremental motions, such as `G91 X0.1`, with each jogging click or key press. This works pretty well, but, if uncontrolled, a user can easily queue up more motions than they want without realizing it and move well-past their desired location.
The general methodology that has been shown to work is to simply restrict the number of jogging commands sent to Grbl. This can be done by disabling key repeating when held down. The planner buffer queue size can be tracked such that only a handful of motions can be queued and executed.
#### Synchronization
For situations when a GUI needs to run a special set of commands for tool changes, auto-leveling, etc, there often needs to be a way to know when Grbl has completed a task and the planner buffer is empty. The absolute simplest way to do this is to insert a `G4 P0.01` dwell command, where P is in seconds and must be greater than 0.0. This acts as a quick force-synchronization and ensures the planner buffer is completely empty before the GUI sends the next task to execute.

View File

@ -0,0 +1,409 @@
#### _Quick-Links:_
* [Getting Started](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9#getting-started)
* [Grbl Settings](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9#grbl-settings)
* [Grbl's Settings and What They Mean](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9#grbls-xval-settings-and-what-they-mean)
* [Grbl's Other `$` Commands](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9#grbls-other--commands)
* [Real-Time Commands](https://github.com/grbl/grbl/wiki/Configuring-Grbl-v0.9#real-time-commands----and-ctrl-x)
***
## Getting Started
First, connect to Grbl using the serial terminal of your choice.
Set the baud rate to **115200** as 8-N-1 (8-bits, no parity, and 1-stop bit.)
Once connected
you should get the Grbl-prompt, which looks like this:
```
Grbl 0.9i ['$' for help]
```
Type $ and press enter to have Grbl print a help message. You should not see any local echo of the $ and enter. Grbl should respond with:
```
$$ (view Grbl settings)
$# (view # parameters)
$G (view parser state)
$I (view build info)
$N (view startup blocks)
$x=value (save Grbl setting)
$Nx=line (save startup block)
$C (check gcode mode)
$X (kill alarm lock)
$H (run homing cycle)
~ (cycle start)
! (feed hold)
? (current status)
ctrl-x (reset Grbl)
```
The $-commands are Grbl system commands used to tweak the settings, view or change Grbl's states and running modes, and start a homing cycle. The last four **non**-'$' commands are realtime control commands that can be sent at anytime, no matter what Grbl is doing. These either immediately change Grbl's running behavior or immediately print a report of the important realtime data like current position (aka DRO).
***
##Grbl Settings
#### $$ - View Grbl settings
To view the settings, type `$$` and press enter after connecting to Grbl. Grbl should respond with a list of the current system settings, as shown in the example below. All of these settings are persistent and kept in EEPROM, so if you power down, these will be loaded back up the next time you power up your Arduino.
```
$0=10 (step pulse, usec)
$1=25 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=6 (dir port invert mask:00000110)
$4=0 (step enable invert, bool)
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=3 (status report mask:00000011)
$11=0.020 (junction deviation, mm)
$12=0.002 (arc tolerance, mm)
$13=0 (report inches, bool)
$20=0 (soft limits, bool)
$21=0 (hard limits, bool)
$22=0 (homing cycle, bool)
$23=1 (homing dir invert mask:00000001)
$24=50.000 (homing feed, mm/min)
$25=635.000 (homing seek, mm/min)
$26=250 (homing debounce, msec)
$27=1.000 (homing pull-off, mm)
$100=314.961 (x, step/mm)
$101=314.961 (y, step/mm)
$102=314.961 (z, step/mm)
$110=635.000 (x max rate, mm/min)
$111=635.000 (y max rate, mm/min)
$112=635.000 (z max rate, mm/min)
$120=50.000 (x accel, mm/sec^2)
$121=50.000 (y accel, mm/sec^2)
$122=50.000 (z accel, mm/sec^2)
$130=225.000 (x max travel, mm)
$131=125.000 (y max travel, mm)
$132=170.000 (z max travel, mm)
```
#### $x=val - Save Grbl setting
The `$x=val` command saves or alters a Grbl setting, which can be done manually by sending this command when connected to Grbl through a serial terminal program, but most Grbl GUIs will do this for you as a user-friendly feature.
To manually change e.g. the microseconds step pulse option to 10us you would type this, followed by an enter:
```
$0=10
```
If everything went well, Grbl will respond with an 'ok' and this setting is stored in EEPROM and will be retained forever or until you change them. You can check if Grbl has received and stored your setting correctly by typing `$$` to view the system settings again.
***
## Grbl's `$x=val` settings and what they mean
**NOTE: Settings numbering has changed since v0.8c for future-proofing purposes.**
#### $0 Step pulse, microseconds
Stepper drivers are rated for a certain minimum step pulse length. Check the data sheet or just try some numbers. You want the shortest pulses the stepper drivers can reliably recognize. If the pulses are too long, you might run into trouble when running the system at very high feed and pulse rates, because the step pulses can begin to overlap each other. We recommend something around 10 microseconds, which is the default value.
#### $1 - Step idle delay, msec
Every time your steppers complete a motion and come to a stop, Grbl will delay disabling the steppers by this value. **OR**, you can always keep your axes enabled (powered so as to hold position) by setting this value to the maximum 255 milliseconds. Again, just to repeat, you can keep all axes always enabled by setting `$1=255`.
The stepper idle lock time is the time length Grbl will keep the steppers locked before disabling. Depending on the system, you can set this to zero and disable it. On others, you may need 25-50 milliseconds to make sure your axes come to a complete stop before disabling. This is to help account for machine motors that do not like to be left on for long periods of time without doing something. Also, keep in mind that some stepper drivers don't remember which micro step they stopped on, so when you re-enable, you may witness some 'lost' steps due to this. In this case, just keep your steppers enabled via `$1=255`.
#### $2 Step port invert mask:binary
This setting inverts the step pulse signal. By default, a step signal starts at normal-low and goes high upon a step pulse event. After a step pulse time set by `$0`, the pin resets to low, until the next step pulse event. When inverted, the step pulse behavior switches from normal-high, to low during the pulse, and back to high. Most users will not need to use this setting, but this can be useful for certain CNC-stepper drivers that have peculiar requirements. For example, an artificial delay between the direction pin and step pulse can be created by inverting the step pin.
This invert mask setting is a value which stores the axes to invert as bit flags. You really don't need to completely understand how it works. You simply need to enter the settings value for the axes you want to invert. For example, if you want to invert the X and Z axes, you'd send `$2=5` to Grbl and the setting should now read `$2=5 (step port invert mask:00000101)`.
| Setting Value | Mask |Invert X | Invert Y | Invert Z |
|:-------------:|:----:|:-------:|:--------:|:--------:|
| 0 | 00000000 |N | N | N |
| 1 | 00000001 |Y | N | N |
| 2 | 00000010 |N | Y | N |
| 3 | 00000011 |Y | Y | N |
| 4 | 00000100 |N | N | Y |
| 5 | 00000101 |Y | N | Y |
| 6 | 00000110 |N | Y | Y |
| 7 | 00000111 |Y | Y | Y |
#### $3 Direction port invert mask:binary
This setting inverts the direction signal for each axis. By default, Grbl assumes that the axes move in a positive direction when the direction pin signal is low, and a negative direction when the pin is high. Often, axes don't move this way with some machines. This setting will invert the direction pin signal for those axes that move the opposite way.
This invert mask setting works exactly like the step port invert mask and stores which axes to invert as bit flags. To configure this setting, you simply need to send the value for the axes you want to invert. Use the table above. For example, if want to invert the Y axis direction only, you'd send `$3=2` to Grbl and the setting should now read `$3=2 (dir port invert mask:00000010)`
#### $4 - Step enable invert, bool
By default, the stepper enable pin is high to disable and low to enable. If your setup needs the opposite, just invert the stepper enable pin by typing `$4=1`. Disable with `$4=0`. (May need a power cycle to load the change.)
#### $5 - Limit pins invert, bool
By default, the limit pins are held normally-high with the Arduino's internal pull-up resistor. When a limit pin is low, Grbl interprets this as triggered. For the opposite behavior, just invert the limit pins by typing `$5=1`. Disable with `$5=0`. You may need a power cycle to load the change.
NOTE: If you invert your limit pins, you will need an external pull-down resistor wired in to all of the limit pins to prevent overloading the pins with current and frying them.
#### $6 - Probe pin invert, bool
By default, the probe pin is held normally-high with the Arduino's internal pull-up resistor. When the probe pin is low, Grbl interprets this as triggered. For the opposite behavior, just invert the probe pin by typing `$6=1`. Disable with `$6=0`. You may need a power cycle to load the change.
NOTE: If you invert your probe pin, you will need an external pull-down resistor wired in to the probe pin to prevent overloading it with current and frying it.
#### $10 - Status report mask:binary
This setting determines what Grbl real-time data it reports back to the user when a '?' status report is sent. By default, Grbl will send back its running state (can't be turned off), machine position, and work position (machine position with coordinate offsets and other offsets applied). Three additional reporting features are available that are useful for interfaces or users setting up their machines, which include the serial RX buffer, planner block buffer usage, and limit pin states (as high or low, shown in the order ZYX).
To set them, use the table below to determine what data you'd like Grbl to send back. Select the report types you'd like to see in the status reports and add their values together. This is the value you use to send to Grbl. For example, if you need machine and work positions, add the values 1 and 2 and send Grbl `$10=3` to set it. Or, if you need machine position only and limit pin state, add the values 1 and 16 and send Grbl `$10=17`.
In general, keep this real-time status data to a minimum, since it takes resources to print and send this data back at a high rate. For example, limit pins reporting is generally only needed when users are setting up their machine. Afterwards, it's recommended to disable it, as it isn't very useful once you've got everything figured out.
| Report Type | Value |
|:-------------:|:----:|
| Machine Position | 1 |
| Work Position | 2 |
| Planner Buffer | 4 |
| RX Buffer | 8 |
| Limit Pins | 16 |
#### $11 - Junction deviation, mm
Junction deviation is used by the acceleration manager to determine how fast it can move through line segment junctions of a G-code program path. For example, if the G-code path has a sharp 10 degree turn coming up and the machine is moving at full speed, this setting helps determine how much the machine needs to slow down to safely go through the corner without losing steps.
How we calculate it is a bit complicated, but, in general, higher values gives faster motion through corners, while increasing the risk of losing steps and positioning. Lower values makes the acceleration manager more careful and will lead to careful and slower cornering. So if you run into problems where your machine tries to take a corner too fast, *decrease* this value to make it slow down when entering corners. If you want your machine to move faster through junctions, *increase* this value to speed it up. For curious people, hit this [link](http://t.co/KQ5BvueY) to read about Grbl's cornering algorithm, which accounts for both velocity and junction angle with a very simple, efficient, and robust method.
#### $12 Arc tolerance, mm
Grbl renders G2/G3 circles, arcs, and helices by subdividing them into teeny tiny lines, such that the arc tracing accuracy is never below this value. You will probably never need to adjust this setting, since `0.002mm` is well below the accuracy of most all CNC machines. But if you find that your circles are too crude or arc tracing is performing slowly, adjust this setting. Lower values give higher precision but may lead to performance issues by overloading Grbl with too many tiny lines. Alternately, higher values traces to a lower precision, but can speed up arc performance since Grbl has fewer lines to deal with.
For the curious, arc tolerance is defined as the maximum perpendicular distance from a line segment with its end points lying on the arc, aka a chord. With some basic geometry, we solve for the length of the line segments to trace the arc that satisfies this setting. Modeling arcs in this way is great, because the arc line segments automatically adjust and scale with length to ensure optimum arc tracing performance, while never losing accuracy.
#### $13 - Report inches, bool
Grbl has a real-time positioning reporting feature to provide a user feedback on where the machine is exactly at that time, as well as, parameters for coordinate offsets and probing. By default, it is set to report in mm, but by sending a `$13=1` command, you send this boolean flag to true and these reporting features will now report in inches. `$13=0` to set back to mm.
#### $20 - Soft limits, bool
Soft limits is a safety feature to help prevent your machine from traveling too far and beyond the limits of travel, crashing or breaking something expensive. It works by knowing the maximum travel limits for each axis and where Grbl is in machine coordinates. Whenever a new G-code motion is sent to Grbl, it checks whether or not you accidentally have exceeded your machine space. If you do, Grbl will issue an immediate feed hold wherever it is, shutdown the spindle and coolant, and then set the system alarm indicating the problem. Machine position will be retained afterwards, since it's not due to an immediate forced stop like hard limits.
NOTE: Soft limits requires homing to be enabled and accurate axis maximum travel settings, because Grbl needs to know where it is. `$20=1` to enable, and `$20=0` to disable.
#### $21 - Hard limits, bool
Hard limit work basically the same as soft limits, but use physical switches instead. Basically you wire up some switches (mechanical, magnetic, or optical) near the end of travel of each axes, or where ever you feel that there might be trouble if your program moves too far to where it shouldn't. When the switch triggers, it will immediately halt all motion, shutdown the coolant and spindle (if connected), and go into alarm mode, which forces you to check your machine and reset everything.
To use hard limits with Grbl, the limit pins are held high with an internal pull-up resistor, so all you have to do is wire in a normally-open switch with the pin and ground and enable hard limits with `$21=1`. (Disable with `$21=0`.) We strongly advise taking electric interference prevention measures. If you want a limit for both ends of travel of one axes, just wire in two switches in parallel with the pin and ground, so if either one of them trips, it triggers the hard limit.
Keep in mind, that a hard limit event is considered to be critical event, where steppers immediately stop and will have likely have lost steps. Grbl doesn't have any feedback on position, so it can't guarantee it has any idea where it is. So, if a hard limit is triggered, Grbl will go into an infinite loop ALARM mode, giving you a chance to check your machine and forcing you to reset Grbl. Remember it's a purely a safety feature.
#### $22 - Homing cycle, bool
Ahh, homing. For those just initiated into CNC, the homing cycle is used to accurately and precisely locate a known and consistent position on a machine every time you start up your Grbl between sessions. In other words, you know exactly where you are at any given time, every time. Say you start machining something or are about to start the next step in a job and the power goes out, you re-start Grbl and Grbl has no idea where it is. You're left with the task of figuring out where you are. If you have homing, you always have the machine zero reference point to locate from, so all you have to do is run the homing cycle and resume where you left off.
To set up the homing cycle for Grbl, you need to have limit switches in a fixed position that won't get bumped or moved, or else your reference point gets messed up. Usually they are setup in the farthest point in +x, +y, +z of each axes. Wire your limit switches in with the limit pins and ground, just like with the hard limits, and enable homing. If you're curious, you can use your limit switches for both hard limits AND homing. They play nice with each other.
By default, Grbl's homing cycle moves the Z-axis positive first to clear the workspace and then moves both the X and Y-axes at the same time in the positive direction. To set up how your homing cycle behaves, there are more Grbl settings down the page describing what they do (and compile-time options as well.)
Also, one more thing to note, when homing is enabled. Grbl will lock out all G-code commands until you perform a homing cycle. Meaning no axes motions, unless the lock is disabled ($X) but more on that later. Most, if not all CNC controllers, do something similar, as it is mostly a safety feature to prevent users from making a positioning mistake, which is very easy to do and be saddened when a mistake ruins a part. If you find this annoying or find any weird bugs, please let us know and we'll try to work on it so everyone is happy. :)
NOTE: Check out config.h for more homing options for advanced users. You can disable the homing lockout at startup, configure which axes move first during a homing cycle and in what order, and more.
#### $23 - Homing dir invert mask, int:binary
By default, Grbl assumes your homing limit switches are in the positive direction, first moving the z-axis positive, then the x-y axes positive before trying to precisely locate machine zero by going back and forth slowly around the switch. If your machine has a limit switch in the negative direction, the homing direction mask can invert the axes' direction. It works just like the step port invert and direction port invert masks, where all you have to do is send the value in the table to indicate what axes you want to invert and search for in the opposite direction.
#### $24 - Homing feed, mm/min
The homing cycle first searches for the limit switches at a higher seek rate, and after it finds them, it moves at a slower feed rate to home into the precise location of machine zero. Homing feed rate is that slower feed rate. Set this to whatever rate value that provides repeatable and precise machine zero locating.
#### $25 - Homing seek, mm/min
Homing seek rate is the homing cycle search rate, or the rate at which it first tries to find the limit switches. Adjust to whatever rate gets to the limit switches in a short enough time without crashing into your limit switches if they come in too fast.
#### $26 - Homing debounce, ms
Whenever a switch triggers, some of them can have electrical/mechanical noise that actually 'bounce' the signal high and low for a few milliseconds before settling in. To solve this, you need to debounce the signal, either by hardware with some kind of signal conditioner or by software with a short delay to let the signal finish bouncing. Grbl performs a short delay, only homing when locating machine zero. Set this delay value to whatever your switch needs to get repeatable homing. In most cases, 5-25 milliseconds is fine.
#### $27 - Homing pull-off, mm
To play nice with the hard limits feature, where homing can share the same limit switches, the homing cycle will move off all of the limit switches by this pull-off travel after it completes. In other words, it helps to prevent accidental triggering of the hard limit after a homing cycle.
#### $100, $101 and $102 [X,Y,Z] steps/mm
Grbl needs to know how far each step will take the tool in reality. To calculate steps/mm for an axis of your machine you need to know:
* The mm traveled per revolution of your stepper motor. This is dependent on your belt drive gears or lead screw pitch.
* The full steps per revolution of your steppers (typically 200)
* The microsteps per step of your controller (typically 1, 2, 4, 8, or 16). _Tip: Using high microstep values (e.g., 16) can reduce your stepper motor torque, so use the lowest that gives you the desired axis resolution and comfortable running properties._
The steps/mm can then be calculated like this: ```steps_per_mm = (steps_per_revolution*microsteps)/mm_per_rev```
Compute this value for every axis and write these settings to Grbl.
#### $110, $111 and $112 [X,Y,Z] Max rate, mm/min
This sets the maximum rate each axis can move. Whenever Grbl plans a move, it checks whether or not the move causes any one of these individual axes to exceed their max rate. If so, it'll slow down the motion to ensure none of the axes exceed their max rate limits. This means that each axis has its own independent speed, which is extremely useful for limiting the typically slower Z-axis.
The simplest way to determine these values is to test each axis one at a time by slowly increasing max rate settings and moving it. For example, to test the X-axis, send Grbl something like `G0 X50` with enough travel distance so that the axis accelerates to its max speed. You'll know you've hit the max rate threshold when your steppers stall. It'll make a bit of noise, but shouldn't hurt your motors. Enter a setting a 10-20% below this value, so you can account for wear, friction, and the mass of your workpiece/tool. Then, repeat for your other axes.
NOTE: This max rate setting also sets the G0 seek rates.
#### $120, $121, $122 [X,Y,Z] Acceleration, mm/sec^2
This sets the axes acceleration parameters in mm/second/second. Simplistically, a lower value makes Grbl ease slower into motion, while a higher value yields tighter moves and reaches the desired feedrates much quicker. Much like the max rate setting, each axis has its own acceleration value and are independent of each other. This means that a multi-axis motion will only accelerate as quickly as the lowest contributing axis can.
Again, like the max rate setting, the simplest way to determine the values for this setting is to individually test each axis with slowly increasing values until the motor stalls. Then finalize your acceleration setting with a value 10-20% below this absolute max value. This should account for wear, friction, and mass inertia. We highly recommend that you dry test some G-code programs with your new settings before committing to them. Sometimes the loading on your machine is different when moving in all axes together.
#### $130, $131, $132 [X,Y,Z] Max travel, mm
This sets the maximum travel from end to end for each axis in mm. This is only useful if you have soft limits (and homing) enabled, as this is only used by Grbl's soft limit feature to check if you have exceeded your machine limits with a motion command.
***
## Grbl's Other '$' Commands
The other `$` commands provide additional controls for the user, such as printing feedback on the current G-code parser modal state or running the homing cycle. This section explains what these commands are and how to use them.
#### `$#` - View gcode parameters
G-code parameters store the coordinate offset values for G54-G59 work coordinates, G28/G30 pre-defined positions, G92 coordinate offset, tool length offsets, and probing (not officially, but we added here anyway). Most of these parameters are directly written to EEPROM anytime they are changed and are persistent. Meaning that they will remain the same, regardless of power-down, until they are explicitly changed. The non-persistent parameters, which will are not retained when reset or power-cycled, are G92, G43.1 tool length offsets, and the G38.2 probing data.
G54-G59 work coordinates can be changed via the `G10 L2 Px` or `G10 L20 Px` command defined by the NIST gcode standard and the EMC2 (linuxcnc.org) standard. G28/G30 pre-defined positions can be changed via the `G28.1` and the `G30.1` commands, respectively.
When `$#` is called, Grbl will respond with the stored offsets from machine coordinates for each system as follows. `TLO` denotes tool length offset, and `PRB` denotes the coordinates of the last probing cycle.
```
[G54:4.000,0.000,0.000]
[G55:4.000,6.000,7.000]
[G56:0.000,0.000,0.000]
[G57:0.000,0.000,0.000]
[G58:0.000,0.000,0.000]
[G59:0.000,0.000,0.000]
[G28:1.000,2.000,0.000]
[G30:4.000,6.000,0.000]
[G92:0.000,0.000,0.000]
[TLO:0.000,0.000,0.000]
[PRB:0.000,0.000,0.000]
```
#### `$G` - View gcode parser state
This command prints all of the active gcode modes in Grbl's G-code parser. When sending this command to Grbl, it will reply with something like:
```
[G0 G54 G17 G21 G90 G94 M0 M5 M9 T0 S0.0 F500.0]
```
These active modes determine how the next G-code block or command will be interpreted by Grbl's G-code parser. For those new to G-code and CNC machining, modes sets the parser into a particular state so you don't have to constantly tell the parser how to parse it. These modes are organized into sets called "modal groups" that cannot be logically active at the same time. For example, the units modal group sets whether your G-code program is interpreted in inches or in millimeters.
A short list of the modal groups, supported by Grbl, is shown below, but more complete and detailed descriptions can be found at LinuxCNC's [website](http://www.linuxcnc.org/docs/2.4/html/gcode_overview.html#sec:Modal-Groups). The G-code commands in **bold** indicate the default modes upon powering-up Grbl or resetting it.
| Modal Group Meaning | Member Words |
|:----:|:----:|
| Motion Mode | **G0**, G1, G2, G3, G38.2, G38.3, G38.4, G38.5, G80 |
|Coordinate System Select | **G54**, G55, G56, G57, G58, G59|
|Plane Select | **G17**, G18, G19|
|Distance Mode | **G90**, G91|
|Arc IJK Distance Mode | **G91.1** |
|Feed Rate Mode | G93, **G94**|
|Units Mode | G20, **G21**|
|Cutter Radius Compensation | **G40** |
|Tool Length Offset |G43.1, **G49**|
|Program Mode | **M0**, M1, M2, M30|
|Spindle State |M3, M4, **M5**|
|Coolant State | M7, M8, **M9** |
In addition to the G-code parser modes, Grbl will report the active `T` tool number, `S` spindle speed, and `F` feed rate, which all default to 0 upon a reset. For those that are curious, these don't quite fit into nice modal groups, but are just as important for determining the parser state.
#### `$I` - View build info
This prints feedback to the user the Grbl version and source code build date. Optionally, `$I` can also store a short string to help identify which CNC machine you are communicating with, if you have more than machine using Grbl. To set this string, send Grbl `$I=xxx`, where `xxx` is your customization string that is less than 80 characters. The next time you query Grbl with a `$I` view build info, Grbl will print this string after the version and build date.
#### $N - View startup blocks
`$Nx` are the startup blocks that Grbl runs every time you power on Grbl or reset Grbl. In other words, a startup block is a line of G-code that you can have Grbl auto-magically run to set your G-code modal defaults, or anything else you need Grbl to do everytime you start up your machine. Grbl can store two blocks of G-code as a system default.
So, when connected to Grbl, type `$N` and then enter. Grbl should respond with something short like:
```
$N0=
$N1=
ok
```
Not much to go on, but this just means that there is no G-code block stored in line `$N0` for Grbl to run upon startup. `$N1` is the next line to be run.
#### $Nx=line - Save startup block
**IMPORTANT: Be very careful when storing any motion (G0/1,G2/3,G28/30) commands in the startup blocks. These motion commands will run everytime you reset or power up Grbl, so if you have an emergency situation and have to e-stop and reset, a startup block move can and will likely make things worse quickly. Also, do not place any commands that save data to EEPROM, such as G10/G28.1/G30.1. This will cause Grbl to constantly re-write this data upon every startup and reset, which will eventually wear out your Arduino's EEPROM.**
**Typical usage for a startup block is simply to set your preferred modal states, such as G20 inches mode, always default to a different work coordinate system, or, to provide a way for a user to run some user-written unique feature that they need for their crazy project.**
To set a startup block, type `$N0=` followed by a valid G-code block and an enter. Grbl will run the block to check if it's valid and then reply with an `ok` or an `error:` to tell you if it's successful or something went wrong. If there is an error, Grbl will not save it.
For example, say that you want to use your first startup block `$N0` to set your G-code parser modes like G54 work coordinate, G20 inches mode, G17 XY-plane. You would type `$N0=G20 G54 G17` with an enter and you should see an 'ok' response. You can then check if it got stored by typing `$N` and you should now see a response like `$N0=G20G54G17`.
Once you have a startup block stored in Grbl's EEPROM, everytime you startup or reset you will see your startup block printed back to you and a response from Grbl to indicate if it ran okay. So for the previous example, you'll see:
```
Grbl 0.9i ['$' for help]
G20G54G17ok
```
If you have multiple G-code startup blocks, they will print back to you in order upon every startup. And if you'd like to clear one of the startup blocks, (e.g., block 0) type `$N0=` without anything following the equal sign.
Also, if you have homing enabled, the startup blocks will execute immediately after the homing cycle, not at startup.
#### `$C` - Check gcode mode
This toggles the Grbl's gcode parser to take all incoming blocks and process them completely, as it would in normal operation, but it does not move any of the axes, ignores dwells, and powers off the spindle and coolant. This is intended as a way to provide the user a way to check how their new G-code program fares with Grbl's parser and monitor for any errors (and checks for soft limit violations, if enabled).
When toggled off, Grbl will perform an automatic soft-reset (^X). This is for two purposes. It simplifies the code management a bit. But, it also prevents users from starting a job when their G-code modes are not what they think they are. A system reset always gives the user a fresh, consistent start.
#### `$X` - Kill alarm lock
Grbl's alarm mode is a state when something has gone critically wrong, such as a hard limit or an abort during a cycle, or if Grbl doesn't know its position. By default, if you have homing enabled and power-up the Arduino, Grbl enters the alarm state, because it does not know its position. The alarm mode will lock all G-code commands until the '$H' homing cycle has been performed. Or if a user needs to override the alarm lock to move their axes off their limit switches, for example, '$X' kill alarm lock will override the locks and allow G-code functions to work again.
But, tread carefully!! This should only be used in emergency situations. The position has likely been lost, and Grbl may not be where you think it is. So, it's advised to use G91 incremental mode to make short moves. Then, perform a homing cycle or reset immediately afterwards.
#### `$H` - Run homing cycle
This command is the only way to perform the homing cycle in Grbl. Some other motion controllers designate a special G-code command to run a homing cycle, but this is incorrect according to the G-code standards. Homing is a completely separate command handled by the controller.
TIP: After running a homing cycle, rather jogging manually all the time to a position in the middle of your workspace volume. You can set a G28 or G30 pre-defined position to be your post-homing position, closer to where you'll be machining. To set these, you'll first need to jog your machine to where you would want it to move to after homing. Type G28.1 (or G30.1) to have Grbl store that position. So then after '$H' homing, you could just enter 'G28' (or 'G30') and it'll move there auto-magically. In general, I would just move the XY axis to the center and leave the Z-axis up. This ensures that there isn't a chance the tool in the spindle will interfere and that it doesn't catch on anything.
#### `$RST=$`, `$RST=#`, and `$RST=*`- Restore Grbl settings and data to defaults
These commands are not listed in the main Grbl `$` help message, but are available to allow users to restore parts of or all of Grbl's EEPROM data. Note: Grbl will automatically reset after executing one of these commands to ensure the system is initialized correctly.
- `$RST=$` : Erases and restores the `$$` Grbl settings back to defaults, which is defined by the default settings file used when compiling Grbl. Often OEMs will build their Grbl firmwares with their machine-specific recommended settings. This provides users and OEMs a quick way to get back to square-one, if something went awry or if a user wants to start over.
- `$RST=#` : Erases and zeros all G54-G59 work coordinate offsets and G28/30 positions stored in EEPROM. These are generally the values seen in the `$#` parameters printout. This provides an easy way to clear these without having to do it manually for each set with a `G20 L2/20` or `G28.1/30.1` command.
- `$RST=*` : This clears and restores all of the EEPROM data used by Grbl. This includes `$$` settings, `$#` parameters, `$N` startup lines, and `$I` build info string. Note that this doesn't wipe the entire EEPROM, only the data areas Grbl uses. To do a complete wipe, please use the Arduino IDE's EEPROM clear example project.
***
## Real-Time Commands: `~, !, ?, and Ctrl-X`
The last four of Grbl's commands are real-time commands. This means that they can be sent at anytime, anywhere, and Grbl will immediately respond, no matter what it's doing. For those that are curious, these are special characters that are 'picked-off' from the incoming serial stream and will tell Grbl to execute them, usually within a few milliseconds.
#### `~` - Cycle start
This is the cycle start or resume command that can be issued at any time, as it is a real-time command. When Grbl has motions queued in its buffer and is ready to go, the `~` cycle start command will start executing the buffer and Grbl will begin moving the axes. However, by default, auto-cycle start is enabled, so new users will not need this command unless a feed hold is performed. When a feed hold is executed, cycle start will resume the program. Cycle start will only be effective when there are motions in the buffer ready to go and will not work with any other process like homing.
#### `!` - Feed hold
The feed hold command will bring the active cycle to a stop via a controlled deceleration, so as not to lose position. It is also real-time and may be activated at any time. Once finished or paused, Grbl will wait until a cycle start command is issued to resume the program. Feed hold can only pause a cycle and will not affect homing or any other process.
If you need to stop a cycle mid-program and can't afford losing position, perform a feed hold to have Grbl bring everything to a controlled stop. Once finished, you can then issue a reset. Always try to execute a feed hold whenever the machine is running before hitting reset, except of course if there is some emergency situation.
#### `?` - Current status
The `?` command immediately returns Grbl's active state and the real-time current position, both in machine coordinates and work coordinates. Optionally, you can also have Grbl respond back with the RX serial buffer and planner buffer usage via the status report mask setting. The `?` command may be sent at any time and works asynchronously with all other processes that Grbl is doing. The `$13` Grbl setting determines whether it reports millimeters or inches. When `?` is pressed, Grbl will immediately reply with something like the following:
```
<Idle,MPos:5.529,0.560,7.000,WPos:1.529,-5.440,-0.000>
```
The active states Grbl can be in are: **Idle, Run, Hold, Door, Home, Alarm, Check**
- **Idle**: All systems are go, no motions queued, and it's ready for anything.
- **Run**: Indicates a cycle is running.
- **Hold**: A feed hold is in process of executing, or slowing down to a stop. After the hold is complete, Grbl will remain in Hold and wait for a cycle start to resume the program.
- **Door**: (New in v0.9i) This compile-option causes Grbl to feed hold, shut-down the spindle and coolant, and wait until the door switch has been closed and the user has issued a cycle start. Useful for OEM that need safety doors.
- **Home**: In the middle of a homing cycle. NOTE: Positions are not updated live during the homing cycle, but they'll be set to the home position once done.
- **Alarm**: This indicates something has gone wrong or Grbl doesn't know its position. This state locks out all G-code commands, but allows you to interact with Grbl's settings if you need to. '$X' kill alarm lock releases this state and puts Grbl in the Idle state, which will let you move things again. As said before, be cautious of what you are doing after an alarm.
- **Check**: Grbl is in check G-code mode. It will process and respond to all G-code commands, but not motion or turn on anything. Once toggled off with another '$C' command, Grbl will reset itself.
#### `Ctrl-x` - Reset Grbl
This is Grbl's _soft_ reset command. It's real-time and can be sent at any time. As the name implies, it resets Grbl, but in a controlled way, *retains* your machine position, and all is done without powering down your Arduino. The only times a soft-reset could lose position is when problems arise and the steppers were killed while they were moving. If so, it will report if Grbl's tracking of the machine position has been lost. This is because an uncontrolled deceleration can lead to lost steps, and Grbl has no feedback to how much it lost (this is the problem with steppers in general). Otherwise, Grbl will just re-initialize, run the startup lines, and continue on its merry way.
Please note that it's recommended to do a soft-reset before starting a job. This guarantees that there aren't any G-code modes active that from playing around or setting up your machine before running the job. So, your machine will always starts fresh and consistently, and your machine does what you expect it to.
## Other Resources:
* **[DANK](http://dank.bengler.no/-/page/show/5474_configuringgrbl)** _Last updated 2/2011._ Only applies to grbl v0.6.

View File

@ -113,6 +113,7 @@ Grbl v1.0 installed more than a dozen new realtime commands to control feed, rap
- `0x9E` : Toggle Spindle Stop - `0x9E` : Toggle Spindle Stop
- Toggles spindle enable or disable state immediately, but only while in the HOLD. - Toggles spindle enable or disable state immediately, but only while in the HOLD.
- The command is otherwise ignored, especially while in motion. This prevents accidental disabling during a job that can either destroy the part/machine or personal injury. Industrial machines handle the spindle stop override similarly. - The command is otherwise ignored, especially while in motion. This prevents accidental disabling during a job that can either destroy the part/machine or personal injury. Industrial machines handle the spindle stop override similarly.
- When motion restarts via cycle start, the last spindle state will be restored and wait 4.0 seconds (configurable) before resuming the tool path. This ensures the user doesn't forget to turn it back on. - When motion restarts via cycle start, the last spindle state will be restored and wait 4.0 seconds (configurable) before resuming the tool path. This ensures the user doesn't forget to turn it back on.
@ -121,6 +122,7 @@ Grbl v1.0 installed more than a dozen new realtime commands to control feed, rap
- `0xA0` : Toggle Flood Coolant - `0xA0` : Toggle Flood Coolant
- Toggles flood coolant state and output pin until the next toggle or g-code command alters it. - Toggles flood coolant state and output pin until the next toggle or g-code command alters it.
- May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored. - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.
- This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M8` or `M9` g-code command. - This override directly changes the coolant modal state in the g-code parser. Grbl will continue to operate normally like it received and executed an `M8` or `M9` g-code command.
@ -128,6 +130,7 @@ Grbl v1.0 installed more than a dozen new realtime commands to control feed, rap
- `0xA1` : Toggle Mist Coolant - `0xA1` : Toggle Mist Coolant
- Enabled by `ENABLE_M7` compile-time option. Default is disabled. - Enabled by `ENABLE_M7` compile-time option. Default is disabled.
- Toggles mist coolant state and output pin until the next toggle or g-code command alters it. - Toggles mist coolant state and output pin until the next toggle or g-code command alters it.
- May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored. - May be commanded at any time while in IDLE, RUN, or HOLD states. It is otherwise ignored.

View File

@ -1,4 +1,4 @@
### _Grbl v1.0 Realtime Status Reports_ (Rev. 2) ### _Grbl v1.0 Realtime Status Reports_ (Rev. 3)
-------- --------
@ -55,225 +55,6 @@
- Grbl is performing a system motion like homing, jogging, or parking. - Grbl is performing a system motion like homing, jogging, or parking.
- Grbl is executing g-code block that does not contain a motion, like `G20G54` or `G4P1` dwell. (NOTE: Looking to fixing this later.) - Grbl is executing g-code block that does not contain a motion, like `G20G54` or `G4P1` dwell. (NOTE: Looking to fixing this later.)
- See the interface markdown document for details on the new status report.
------- -------
#### Basic Characteristics
- Contains real-time data of Grbls state, position, and other data required independently of the stream.
- Categorized as a real-time message, where it is a separate message that should not be counted as part of the streaming protocol. It may appear at any given time.
- A status report is initiated by sending Grbl a '?' character.
- Like all real-time commands, the '?' character is intercepted and never enters the serial buffer. It's never a part of the stream and can be sent at any time.
- Grbl will generate and transmit a report within ~5-20 milliseconds.
- Every ? command sent by a GUI is not guaranteed with a response. The following are the current scenarios when Grbl may not immediately or ignore a status report request. _NOTE: These may change in the future and will be documented here._
- If two or more '?' queries are sent before the first report is generated, the additional queries are ignored.
- A soft-reset commanded clears the last status report query.
- When Grbl throws a critical alarm from a limit violation. A soft-reset is required to resume operation.
- During a homing cycle.
#### Message Construction:
- A message is a single line of ascii text, completed by a carriage return and line feed.
- `< >` Chevrons uniquely enclose reports to indicate message type.
- `|` Pipe delimiters separate data fields inside the report.
- The first data field is an exception to the following data field rules. See 'Machine State' description for details.
- All remaining data fields consist of a data type followed by a `:` colon delimiter and data values. `type:value(s)`
- Data values are given either as as one or more pre-defined character codes to indicate certain states/conditions or as numeric values, which are separated by a `,` comma delimiter when more than one is present. Numeric values are also in a pre-defined order and units of measure.
- The first (Machine State) and second (Current Position) data fields are always included in every report.
- Assume any following data field may or may not exist and can be in any order. The `$10` status report mask setting can alter what data is present and certain data fields can be reported intermittently (see descriptions for details.)
- The `$13` report inches settings alters the units of some data values. `$13=0` false indicates mm-mode, while `$13=1` true indicates inch-mode reporting. Keep note of this setting and which report values can be altered.
- _Data Field Descriptions:_
- **Machine State:**
- Valid states types: `Idle, Run, Hold, Jog, Alarm, Door, Check, Home`
- Sub-states may be included via `:` a colon delimiter and numeric code.
- Current sub-states are:
- `Hold:0` Hold complete. Ready to resume.
- `Hold:1` Hold in-progress. Reset will throw an alarm.
- `Door:0` Door closed. Ready to resume.
- `Door:1` Machine stopped. Door still ajar. Can't resume until closed.
- `Door:2` Door opened. Hold (or parking retract) in-progress. Reset will throw an alarm.
- `Door:3` Door closed and resuming. Restoring from park, if applicable. Reset will throw an alarm.
- This data field is always present as the first field.
- **Current Position:**
- Depending on `$10` status report mask settings, position may be sent as either:
- `MPos:0.000,-10.000,5.000` machine position or
- `WPos:-2.500,0.000,11.000` work position
- Three position values are given in the order of X, Y, and Z. A fourth position value may exist in later versions for the A-axis.
- `$13` report inches user setting effects these values and is given as either mm or inches.
- This data field is always present as the second field.
- **Work Coordinate Offset:**
- `WCO:0.000,1.551,5.664` is the current work coordinate offset of the g-code parser, which is the sum of the current work coordinate system, G92 offsets, and G43.1 tool length offset.
- Machine position and work position are related by this simple equation per axis: `WPos = MPos - WCO`
- Values are given in the order of the X,Y, and Z axes offsets. A fourth offset value may exist in later versions for the A-axis.
- `$13` report inches user setting effects these values and is given as either mm or inches.
- `WCO:` values don't change often during a job once set and only requires intermittent refreshing.
- This data field appears:
- In every 10 or 30 (configurable 1-255) status reports, depending on if Grbl is in a motion state or not.
- Immediately in the next report, if an offset value has changed.
- In the first report after a reset/power-cycle.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The refresh counter is in-between intermittent reports.
- **Buffer State:**
- `Bf:0,0`. The first value is planner blocks in use and the second is RX bytes in use.
- This data field will not appear if:
- It is disabled by the `$` status report mask setting.
- **Line Number:**
- `Ln:99999` indicates line 99999 is currently being executed. This differs from the `$G` line `N` value since the parser is usually queued few blocks behind execution.
- Compile-time option only because of memory requirements. However, if a GUI passes indicator line numbers onto Grbl, it's very useful to determine when Grbl is executing them.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The line number reporting not enabled in config.h. Different option to reporting data field.
- No line number or `N0` is passed with the g-code block.
- Grbl is homing, jogging, parking, or performing a system task/motion.
- There is no motion in the g-code block like a `G4P1` dwell. (May be fixed in later versions.)
- **Current Rate:**
- `F:1000.` indicates current actual feed rate (speed) of the executing motion. Depending on machine max rate settings and acceleration, this value may not be the programmed rate.
- Value units, either in mm/min or inches/min, is dependent on the `$` report inches user setting.
- As a operational note, reported rate is typically 30-50 msec behind actual position reported.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- **Input Pin State:**
- `Pn:XYZPDHRS` indicates which input pins Grbl has detected as 'triggered'.
- Pin state is evaluated every time a status report is generated. All input pin inversions are appropriately applied to determine 'triggered' states.
- Each letter of `XYZPDHRS` denotes a particular 'triggered' input pin.
- `X Y Z` XYZ limit pins, respectively
- `P` the probe pin.
- `D H R S` the door, hold, soft-reset, and cycle-start pins, respectively.
- Example: `Pn:PZ` indicates the probe and z-limit pins are 'triggered'.
- Note: `A` may be added in later versions for an A-axis limit pin.
- Assume input pin letters are presented in no particular order.
- One or more 'triggered' pin letter(s) will always be present with a `Pn:` data field.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- No input pins are detected as triggered.
- **Override Values:**
- `Ov:100,100,100` indicates current override values in percent of programmed values for feed, rapids, and spindle speed, respectively.
- Override values don't change often during a job once set and only requires intermittent refreshing. This data field appears:
- After 10 or 20 (configurable 1-255) status reports, depending on is in a motion state or not.
- If an override value has changed, this data field will appear immediately in the next report. However, if `WCO:` is present, this data field will be delayed one report.
- In the second report after a reset/power-cycle.
- This data field will not appear if:
- It is disabled in the config.h file. No `$` mask setting available.
- The override refresh counter is in-between intermittent reports.
- `WCO:` exists in current report during refresh. Automatically set to try again on next report.
- **Toggle Overrides:**
- `T:SFM` indicates a toggle override is in effect or has been commanded.
- Like the pin state field, each letter denotes a particular toggle override.
- `S` indicates the spindle stop toggle override is in effect. It will appear as long as the spindle stop override is active.
- `F` indicates the flood coolant toggle override was activated. It will only appear once after it has executed the coolant state change.
- `M` indicates the mist coolant toggle override was activated, if mist coolant is enabled via config.h. It will only appear once after it has executed the coolant state change.
- Assume toggle override letters are presented in no particular order.
- One or more active toggle override letter(s) will always be present with a `T:` data field.
- This data field appears:
- If a toggle override is active or has recently executed and only when the override values field is also present (see override value field rules).
- This data field will not appear if:
- If no toggle override is active or has been executed.
- It is disabled in the config.h file. No `$` mask setting available.
- If override refresh counter is in-between intermittent reports.
- `WCO:` exists in current report during refresh. Automatically set to try again on next report.

View File

@ -22,8 +22,8 @@
#define grbl_h #define grbl_h
// Grbl versioning system // Grbl versioning system
#define GRBL_VERSION "1.0e" #define GRBL_VERSION "1.1a"
#define GRBL_VERSION_BUILD "20160921" #define GRBL_VERSION_BUILD "20160922"
// Define standard libraries used by Grbl. // Define standard libraries used by Grbl.
#include <avr/io.h> #include <avr/io.h>

View File

@ -190,7 +190,7 @@ void printFloat_RateValue(float n) {
} }
} }
void printFloat_SettingValue(float n) { printFloat(n,N_DECIMAL_SETTINGVALUE); } // void printFloat_SettingValue(float n) { printFloat(n,N_DECIMAL_SETTINGVALUE); }
void printFloat_RPMValue(float n) { printFloat(n,N_DECIMAL_RPMVALUE); } void printFloat_RPMValue(float n) { printFloat(n,N_DECIMAL_RPMVALUE); }

View File

@ -46,7 +46,7 @@ void printFloat(float n, uint8_t decimal_places);
// - RPMValue: Handles spindle RPM values in settings and reports. // - RPMValue: Handles spindle RPM values in settings and reports.
void printFloat_CoordValue(float n); void printFloat_CoordValue(float n);
void printFloat_RateValue(float n); void printFloat_RateValue(float n);
void printFloat_SettingValue(float n); // void printFloat_SettingValue(float n);
void printFloat_RPMValue(float n); void printFloat_RPMValue(float n);
// Debug tool to print free memory in bytes at the called point. Not used otherwise. // Debug tool to print free memory in bytes at the called point. Not used otherwise.

View File

@ -137,27 +137,28 @@ void report_alarm_message(int8_t alarm_code)
// TODO: Install silence feedback messages option in settings // TODO: Install silence feedback messages option in settings
void report_feedback_message(uint8_t message_code) void report_feedback_message(uint8_t message_code)
{ {
printPgmString(PSTR("[MSG:"));
switch(message_code) { switch(message_code) {
case MESSAGE_CRITICAL_EVENT: case MESSAGE_CRITICAL_EVENT:
printPgmString(PSTR("[Reset to continue")); break; printPgmString(PSTR("Reset to continue")); break;
case MESSAGE_ALARM_LOCK: case MESSAGE_ALARM_LOCK:
printPgmString(PSTR("['$H'|'$X' to unlock")); break; printPgmString(PSTR("'$H'|'$X' to unlock")); break;
case MESSAGE_ALARM_UNLOCK: case MESSAGE_ALARM_UNLOCK:
printPgmString(PSTR("[Caution: Unlocked")); break; printPgmString(PSTR("Caution: Unlocked")); break;
case MESSAGE_ENABLED: case MESSAGE_ENABLED:
printPgmString(PSTR("[Enabled")); break; printPgmString(PSTR("Enabled")); break;
case MESSAGE_DISABLED: case MESSAGE_DISABLED:
printPgmString(PSTR("[Disabled")); break; printPgmString(PSTR("Disabled")); break;
case MESSAGE_SAFETY_DOOR_AJAR: case MESSAGE_SAFETY_DOOR_AJAR:
printPgmString(PSTR("[Check Door")); break; printPgmString(PSTR("Check Door")); break;
case MESSAGE_CHECK_LIMITS: case MESSAGE_CHECK_LIMITS:
printPgmString(PSTR("[Check Limits")); break; printPgmString(PSTR("Check Limits")); break;
case MESSAGE_PROGRAM_END: case MESSAGE_PROGRAM_END:
printPgmString(PSTR("[Pgm End")); break; printPgmString(PSTR("Pgm End")); break;
case MESSAGE_RESTORE_DEFAULTS: case MESSAGE_RESTORE_DEFAULTS:
printPgmString(PSTR("[Restoring defaults")); break; printPgmString(PSTR("Restoring defaults")); break;
case MESSAGE_SPINDLE_RESTORE: case MESSAGE_SPINDLE_RESTORE:
printPgmString(PSTR("[Restoring spindle")); break; printPgmString(PSTR("Restoring spindle")); break;
} }
printPgmString(PSTR("]\r\n")); printPgmString(PSTR("]\r\n"));
} }
@ -172,7 +173,7 @@ void report_init_message()
// Grbl help message // Grbl help message
void report_grbl_help() { void report_grbl_help() {
#ifdef REPORT_GUI_MODE #ifdef REPORT_GUI_MODE
printPgmString(PSTR("[$$ $# $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 $C $X $H ~ ! ? ctrl-x]\r\n"));
#else #else
printPgmString(PSTR("$$ (view Grbl settings)\r\n" printPgmString(PSTR("$$ (view Grbl settings)\r\n"
"$# (view # parameters)\r\n" "$# (view # parameters)\r\n"
@ -193,38 +194,102 @@ void report_grbl_help() {
} }
static void report_int_setting(uint8_t n, int val)
{
serial_write('$');
print_uint8_base10(n);
serial_write('=');
print_uint8_base10(val);
printPgmString(PSTR("\r\n"));
}
static void report_float_setting(uint8_t n, float val, uint8_t decimal_places)
{
serial_write('$');
print_uint8_base10(n);
serial_write('=');
printFloat(val, decimal_places);
printPgmString(PSTR("\r\n"));
}
// Grbl global settings print out. // Grbl global settings print out.
// 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.
#ifdef REPORT_GUI_MODE #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); report_int_setting(0,settings.pulse_microseconds);
printPgmString(PSTR("\r\n$2=")); print_uint8_base10(settings.step_invert_mask); report_int_setting(1,settings.stepper_idle_lock_time);
printPgmString(PSTR("\r\n$3=")); print_uint8_base10(settings.dir_invert_mask); report_int_setting(2,settings.step_invert_mask);
printPgmString(PSTR("\r\n$4=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE)); report_int_setting(3,settings.dir_invert_mask);
printPgmString(PSTR("\r\n$5=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)); report_int_setting(4,bit_istrue(settings.flags,BITFLAG_INVERT_ST_ENABLE));
printPgmString(PSTR("\r\n$6=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN)); report_int_setting(5,bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS));
printPgmString(PSTR("\r\n$10=")); print_uint8_base10(settings.status_report_mask); report_int_setting(6,bit_istrue(settings.flags,BITFLAG_INVERT_PROBE_PIN));
printPgmString(PSTR("\r\n$11=")); printFloat_SettingValue(settings.junction_deviation); report_int_setting(10,settings.status_report_mask);
printPgmString(PSTR("\r\n$12=")); printFloat_SettingValue(settings.arc_tolerance); report_float_setting(11,settings.junction_deviation,N_DECIMAL_SETTINGVALUE);
printPgmString(PSTR("\r\n$13=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)); report_float_setting(12,settings.arc_tolerance,N_DECIMAL_SETTINGVALUE);
printPgmString(PSTR("\r\n$20=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE)); report_int_setting(13,bit_istrue(settings.flags,BITFLAG_REPORT_INCHES));
printPgmString(PSTR("\r\n$21=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE)); report_int_setting(20,bit_istrue(settings.flags,BITFLAG_SOFT_LIMIT_ENABLE));
printPgmString(PSTR("\r\n$22=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE)); report_int_setting(21,bit_istrue(settings.flags,BITFLAG_HARD_LIMIT_ENABLE));
printPgmString(PSTR("\r\n$23=")); print_uint8_base10(settings.homing_dir_mask); report_int_setting(22,bit_istrue(settings.flags,BITFLAG_HOMING_ENABLE));
printPgmString(PSTR("\r\n$24=")); printFloat_SettingValue(settings.homing_feed_rate); report_int_setting(23,settings.homing_dir_mask);
printPgmString(PSTR("\r\n$25=")); printFloat_SettingValue(settings.homing_seek_rate); report_float_setting(24,settings.homing_feed_rate,N_DECIMAL_SETTINGVALUE);
printPgmString(PSTR("\r\n$26=")); print_uint8_base10(settings.homing_debounce_delay); report_float_setting(25,settings.homing_seek_rate,N_DECIMAL_SETTINGVALUE);
printPgmString(PSTR("\r\n$27=")); printFloat_SettingValue(settings.homing_pulloff); report_int_setting(26,settings.homing_debounce_delay);
printPgmString(PSTR("\r\n$30=")); printFloat_RPMValue(settings.rpm_max); report_float_setting(27,settings.homing_pulloff,N_DECIMAL_SETTINGVALUE);
printPgmString(PSTR("\r\n$31=")); printFloat_RPMValue(settings.rpm_min); report_float_setting(30,settings.rpm_max,N_DECIMAL_RPMVALUE);
report_float_setting(31,settings.rpm_min,N_DECIMAL_RPMVALUE);
#ifdef VARIABLE_SPINDLE #ifdef VARIABLE_SPINDLE
printPgmString(PSTR("\r\n$32=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_LASER_MODE)); report_int_setting(32,bit_istrue(settings.flags,BITFLAG_LASER_MODE));
#else #else
printPgmString(PSTR("\r\n$32=0\r\n")); report_int_setting(32,0);
#endif #endif
// Print axis settings
uint8_t idx, set_idx;
uint8_t val = AXIS_SETTINGS_START_VAL;
for (set_idx=0; set_idx<AXIS_N_SETTINGS; set_idx++) {
for (idx=0; idx<N_AXIS; idx++) {
switch (set_idx) {
case 0: report_float_setting(val+idx,settings.steps_per_mm[idx],N_DECIMAL_SETTINGVALUE); break;
case 1: report_float_setting(val+idx,settings.max_rate[idx],N_DECIMAL_SETTINGVALUE); break;
case 2: report_float_setting(val+idx,settings.acceleration[idx]/(60*60),N_DECIMAL_SETTINGVALUE); break;
case 3: report_float_setting(val+idx,-settings.max_travel[idx],N_DECIMAL_SETTINGVALUE); break;
}
}
val += AXIS_SETTINGS_INCREMENT;
}
// 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$30=")); printFloat_RPMValue(settings.rpm_max);
// printPgmString(PSTR("\r\n$31=")); printFloat_RPMValue(settings.rpm_min);
// #ifdef VARIABLE_SPINDLE
// printPgmString(PSTR("\r\n$32=")); print_uint8_base10(bit_istrue(settings.flags,BITFLAG_LASER_MODE));
// printPgmString(PSTR("\r\n"));
// #else
// printPgmString(PSTR("\r\n$32=0\r\n"));
// #endif
#else #else
printPgmString(PSTR("$0=")); print_uint8_base10(settings.pulse_microseconds); 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 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 idle delay, msec)\r\n$2=")); print_uint8_base10(settings.step_invert_mask);
@ -252,8 +317,6 @@ void report_grbl_settings() {
#else #else
printPgmString(PSTR(" (rpm min)\r\n$32=0 (laser mode, bool)\r\n")); printPgmString(PSTR(" (rpm min)\r\n$32=0 (laser mode, bool)\r\n"));
#endif #endif
#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;
@ -268,9 +331,6 @@ 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;
} }
#ifdef REPORT_GUI_MODE
printPgmString(PSTR("\r\n"));
#else
serial_write(' '); serial_write(' ');
serial_write('('); serial_write('(');
switch (idx) { switch (idx) {
@ -285,10 +345,11 @@ void report_grbl_settings() {
case 3: printPgmString(PSTR(" max travel, mm")); break; case 3: printPgmString(PSTR(" max travel, mm")); break;
} }
printPgmString(PSTR(")\r\n")); printPgmString(PSTR(")\r\n"));
#endif
} }
val += AXIS_SETTINGS_INCREMENT; val += AXIS_SETTINGS_INCREMENT;
} }
#endif
} }
@ -352,24 +413,26 @@ void report_ngc_parameters()
// Print current gcode parser mode state // Print current gcode parser mode state
void report_gcode_modes() void report_gcode_modes()
{ {
printPgmString(PSTR("[GC:G"));
switch (gc_state.modal.motion) { switch (gc_state.modal.motion) {
case MOTION_MODE_SEEK : printPgmString(PSTR("[G0")); break; case MOTION_MODE_SEEK : serial_write('0'); break;
case MOTION_MODE_LINEAR : printPgmString(PSTR("[G1")); break; case MOTION_MODE_LINEAR : serial_write('1'); break;
case MOTION_MODE_CW_ARC : printPgmString(PSTR("[G2")); break; case MOTION_MODE_CW_ARC : serial_write('2'); break;
case MOTION_MODE_CCW_ARC : printPgmString(PSTR("[G3")); break; case MOTION_MODE_CCW_ARC : serial_write('3'); break;
case MOTION_MODE_NONE : printPgmString(PSTR("[G80")); break; case MOTION_MODE_NONE : printPgmString(PSTR("80")); break;
default: default:
printPgmString(PSTR("[G38.")); printPgmString(PSTR("38."));
print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2)); print_uint8_base10(gc_state.modal.motion - (MOTION_MODE_PROBE_TOWARD-2));
} }
printPgmString(PSTR(" G")); printPgmString(PSTR(" G"));
print_uint8_base10(gc_state.modal.coord_select+54); print_uint8_base10(gc_state.modal.coord_select+54);
printPgmString(PSTR(" G1"));
switch (gc_state.modal.plane_select) { switch (gc_state.modal.plane_select) {
case PLANE_SELECT_XY : printPgmString(PSTR(" G17")); break; case PLANE_SELECT_XY : serial_write('7'); break;
case PLANE_SELECT_ZX : printPgmString(PSTR(" G18")); break; case PLANE_SELECT_ZX : serial_write('8'); break;
case PLANE_SELECT_YZ : printPgmString(PSTR(" G19")); break; case PLANE_SELECT_YZ : serial_write('9'); break;
} }
if (gc_state.modal.units == UNITS_MODE_MM) { printPgmString(PSTR(" G21")); } if (gc_state.modal.units == UNITS_MODE_MM) { printPgmString(PSTR(" G21")); }
@ -381,26 +444,29 @@ void report_gcode_modes()
if (gc_state.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { printPgmString(PSTR(" G93")); } if (gc_state.modal.feed_rate == FEED_RATE_MODE_INVERSE_TIME) { printPgmString(PSTR(" G93")); }
else { printPgmString(PSTR(" G94")); } else { printPgmString(PSTR(" G94")); }
printPgmString(PSTR(" M"));
switch (gc_state.modal.program_flow) { switch (gc_state.modal.program_flow) {
case PROGRAM_FLOW_RUNNING : printPgmString(PSTR(" M0")); break; case PROGRAM_FLOW_RUNNING : serial_write('0'); break;
case PROGRAM_FLOW_PAUSED : printPgmString(PSTR(" M1")); break; case PROGRAM_FLOW_PAUSED : serial_write('1'); break;
case PROGRAM_FLOW_COMPLETED : printPgmString(PSTR(" M2")); break; case PROGRAM_FLOW_COMPLETED : serial_write('2'); break;
} }
printPgmString(PSTR(" M"));
switch (gc_state.modal.spindle) { switch (gc_state.modal.spindle) {
case SPINDLE_ENABLE_CW : printPgmString(PSTR(" M3")); break; case SPINDLE_ENABLE_CW : serial_write('3'); break;
case SPINDLE_ENABLE_CCW : printPgmString(PSTR(" M4")); break; case SPINDLE_ENABLE_CCW : serial_write('4'); break;
case SPINDLE_DISABLE : printPgmString(PSTR(" M5")); break; case SPINDLE_DISABLE : serial_write('5'); break;
} }
printPgmString(PSTR(" M"));
#ifdef ENABLE_M7 #ifdef ENABLE_M7
if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time. if (gc_state.modal.coolant) { // Note: Multiple coolant states may be active at the same time.
if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { printPgmString(PSTR(" M7")); } if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_MIST) { serial_write('7'); }
if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { printPgmString(PSTR(" M8")); } if (gc_state.modal.coolant & PL_COND_FLAG_COOLANT_FLOOD) { serial_write('8'); }
} else { printPgmString(PSTR(" M9")); } } else { serial_write('9'); }
#else #else
if (gc_state.modal.coolant) { printPgmString(PSTR(" M8")); } if (gc_state.modal.coolant) { serial_write('8'); }
else { printPgmString(PSTR(" M9")); } else { serial_write('9'); }
#endif #endif
printPgmString(PSTR(" T")); printPgmString(PSTR(" T"));
@ -427,11 +493,18 @@ void report_startup_line(uint8_t n, char *line)
printPgmString(PSTR("\r\n")); printPgmString(PSTR("\r\n"));
} }
void report_execute_startup_message(char *line, uint8_t status_code)
{
serial_write('>');
printString(line); // Echo startup line to indicate execution.
serial_write(':');
report_status_message(status_code);
}
// Prints build info line // Prints build info line
void report_build_info(char *line) void report_build_info(char *line)
{ {
printPgmString(PSTR("[" GRBL_VERSION "." GRBL_VERSION_BUILD ":")); printPgmString(PSTR("[VER:" GRBL_VERSION "." GRBL_VERSION_BUILD ":"));
printString(line); printString(line);
printPgmString(PSTR("]\r\n")); printPgmString(PSTR("]\r\n"));
} }

View File

@ -114,8 +114,9 @@ void report_ngc_parameters();
// Prints current g-code parser mode state // Prints current g-code parser mode state
void report_gcode_modes(); void report_gcode_modes();
// Prints startup line // Prints startup line when requested and executed.
void report_startup_line(uint8_t n, char *line); void report_startup_line(uint8_t n, char *line);
void report_execute_startup_message(char *line, uint8_t status_code);
// Prints build info and user info // Prints build info and user info
void report_build_info(char *line); void report_build_info(char *line);

View File

@ -64,7 +64,7 @@ void spindle_init()
// Stop and start spindle routines. Called by all spindle routines and stepper ISR. // Stop and start spindle routines. Called by all spindle routines and stepper ISR.
inline void spindle_stop() void spindle_stop()
{ {
// On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin. // On the Uno, spindle enable and PWM are shared. Other CPUs have seperate enable pin.
#ifdef VARIABLE_SPINDLE #ifdef VARIABLE_SPINDLE
@ -87,7 +87,7 @@ inline void spindle_stop()
#ifdef VARIABLE_SPINDLE #ifdef VARIABLE_SPINDLE
inline void spindle_set_speed(uint8_t pwm_value) void spindle_set_speed(uint8_t pwm_value)
{ {
if (pwm_value == SPINDLE_PWM_OFF_VALUE) { if (pwm_value == SPINDLE_PWM_OFF_VALUE) {
spindle_stop(); spindle_stop();

View File

@ -34,8 +34,8 @@ void spindle_run(uint8_t direction, float rpm);
void spindle_set_state(uint8_t state, uint8_t pwm_value); void spindle_set_state(uint8_t state, uint8_t pwm_value);
// Stop and start spindle routines. Called by all spindle routines and stepper ISR. // Stop and start spindle routines. Called by all spindle routines and stepper ISR.
inline void spindle_stop(); void spindle_stop();
inline void spindle_set_speed(uint8_t pwm_value); // Variable spindle only. void spindle_set_speed(uint8_t pwm_value); // Variable spindle only.
uint8_t spindle_compute_pwm_value(float rpm); // 328p PWM register is 8-bit. Variable spindle only. uint8_t spindle_compute_pwm_value(float rpm); // 328p PWM register is 8-bit. Variable spindle only.

View File

@ -97,11 +97,12 @@ void system_execute_startup(char *line)
uint8_t n; uint8_t n;
for (n=0; n < N_STARTUP_LINE; n++) { for (n=0; n < N_STARTUP_LINE; n++) {
if (!(settings_read_startup_line(n, line))) { if (!(settings_read_startup_line(n, line))) {
report_status_message(STATUS_SETTING_READ_FAIL); line[0] = 0;
report_execute_startup_message(line,STATUS_SETTING_READ_FAIL);
} else { } else {
if (line[0] != 0) { if (line[0] != 0) {
printString(line); // Echo startup line to indicate execution. uint8_t status_code = gc_execute_line(line);
report_status_message(gc_execute_line(line)); report_execute_startup_message(line,status_code);
} }
} }
} }