Skip to content
M Codes
=======
M Code Quick Reference Table
----------------------------
================================ =======================================
Code Description
================================ =======================================
`M0 M1 <#mcode:m0-m1>`__ Program Pause
`M2 M30 <#mcode:m2-m30>`__ Program End
`M60 <#mcode:m60>`__ Pallet Change Pause
`M3 M4 M5 <#mcode:m3-m4-m5>`__ Spindle Control
`M6 <#mcode:m6>`__ Tool Change
`M7 M8 M9 <#mcode:m7-m8-m9>`__ Coolant Control
`M19 <#mcode:m19>`__ Orient Spindle
`M48 M49 <#mcode:m48-m49>`__ Feed & Spindle Overrides Enable/Disable
`M50 <#mcode:m50>`__ Feed Override Control
`M51 <#mcode:m51>`__ Spindle Override Control
`M52 <#mcode:m52>`__ Adaptive Feed Control
`M53 <#mcode:m53>`__ Feed Stop Control
`M61 <#mcode:m61>`__ Set Current Tool Number
`m62-m65 <#mcode:m62-m65>`__ Output Control
`M66 <#mcode:m66>`__ Input Control
`M67 <#mcode:m67>`__ Analog Output Control
`M68 <#mcode:m68>`__ Analog Output Control
`M70 <#mcode:m70>`__ Save Modal State
`M71 <#mcode:m71>`__ Invalidate Stored Modal State
`M72 <#mcode:m72>`__ Restore Modal State
`M73 <#mcode:m73>`__ Save Autorestore Modal State
`M98 M99 <#mcode:m98-m99>`__ Call and Return From Subprogram
`M100-M199 <#mcode:m100-m199>`__ User Defined M-Codes
================================ =======================================
M0, M1 Program Pause
--------------------
* ``M0`` - pause a running program temporarily. LinuxCNC remains in the Auto Mode so MDI and other
manual actions are not enabled. Pressing the resume button will restart the program at the
following line.
* ``M1`` - pause a running program temporarily if the optional stop switch is on. LinuxCNC remains in
the Auto Mode so MDI and other manual actions are not enabled. Pressing the resume button will
restart the program at the following line.
M2, M30 Program End
-------------------
* ``M2`` - end the program. Pressing r will start the program at the beginning of the file.
* ``M30`` - exchange pallet shuttles and end the program. Pressing cycle start will start the program
at the beginning of the file.
Both of these commands have the following effects:
#. Change from Auto mode to MDI mode.
#. Origin offsets are set to the default (like ``G54``).
#. Selected plane is set to XY plane (like ``G17``).
#. Distance mode is set to absolute mode (like ``G90``).
#. Feed rate mode is set to units per minute (like ``G94``).
#. Feed and speed overrides are set to ON (like ``M48``).
#. Cutter compensation is turned off (like ``G40``).
#. The spindle is stopped (like ``M5``).
#. The current motion mode is set to feed (like ``G1``).
#. Coolant is turned off (like ``M9``).
M60 Pallet Change Pause
-----------------------
* ``M60`` - exchange pallet shuttles and then pause a running program temporarily (regardless of the
setting of the optional stop switch). Pressing the cycle start button will restart the program at
the following line.
M3, M4, M5 Spindle Control
--------------------------
* ``M3`` - start the selected spindle clockwise at the ``S`` speed.
* ``M4`` - start the selected spindle counterclockwise at the ``S`` speed.
* ``M5`` - stop the selected spindle.
Use $ to operate on specific spindles. If $ is omitted then thr commands operate on all spindles.
For example
.. code:: text
---
S100 $0
S200 $1
S300 $2
M3
----
Will start all three spindles simultaneously at different speeds
[source,{ngc]]
----
M4 $1
----
Will then reverse spindle 1 but leave the other spindles rotating forwards.
If the $ is omitted then behaviour is exactly as normal for a single spindle machine
It is OK to use ``M3`` or ``M4`` if the `S <#sec:set-spindle-speed>`__ spindle speed is set to zero. If
this is done (or if the speed override switch is enabled and set to zero), the spindle will not
start turning. If, later, the spindle speed is set above zero (or the override switch is turned
up), the spindle will start turning. It is OK to use ``M3`` or ``M4`` when the spindle is already
turning or to use ``M5`` when the spindle is already stopped.
M6 Tool Change
--------------
Manual Tool Change
~~~~~~~~~~~~~~~~~~
If the HAL component hal_manualtoolchange is loaded, M6 will stop the spindle and prompt the user to
change the tool based on the last ``T-`` number programmed. For more information on
hal_manualtoolchange see the `Manual Tool Change <#sec:manual-tool-change>`__ section.
Tool Changer
~~~~~~~~~~~~
To change a tool in the spindle from the tool currently in the spindle to the tool most recently
selected (using a T word - see Section `Select Tool <#sec:select-tool>`__), program ``M6``. When the
tool change is complete:
* The spindle will be stopped.
* The tool that was selected (by a T word on the same line or on any line after the previous tool
change) will be in the spindle.
* If the selected tool was not in the spindle before the tool change, the tool that was in the
spindle (if there was one) will be placed back into the tool changer magazine.
* If configured in the .ini file some axis positions may move when a M6 is issued. See the `EMCIO
section <#sec:emcio-section>`__ for more information on tool change options.
* No other changes will be made. For example, coolant will continue to flow during the tool change
unless it has been turned off by an ``M9``.
The tool change may include axis motion. It is OK (but not useful) to program a change to the tool
already in the spindle. It is OK if there is no tool in the selected slot; in that case, the spindle
will be empty after the tool change. If slot zero was last selected, there will definitely be no
tool in the spindle after a tool change. The tool changer will have to be setup to perform the tool
change in hal and possibly classic ladder.
M7, M8, M9 Coolant Control
--------------------------
* ``M7`` - turn mist coolant on. M7 controls iocontrol.0.coolant-mist pin.
* ``M8`` - turn flood coolant on. M8 controls iocontrol.0.coolant-flood pin.
* ``M9`` - turn both M7 and M8 off.
Connect one or both of the coolant control pins in HAL before M7 or M8 will control an output. M7
and M8 can be used to turn on any output via G code.
It is OK to use any of these commands, regardless of the current coolant state.
M19 Orient Spindle
------------------
* ``M19 R- Q- [P-] [$-]``
* ``R`` Position to rotate to from 0, valid range is 0-360 degrees
* ``Q`` Number of seconds to wait until orient completes. If spindle.N.is-oriented does not become
true within Q timeout an error occurs.
* ``P`` Direction to rotate to position.
* ``0`` rotate for smallest angular movement (default)
* ``1`` always rotate clockwise (same as M3 direction)
* ``2`` always rotate counterclockwise (same as M4 direction)
* ``$`` The spindle to orient (actually only determines which HAL pins carry the spindle position
commands)
M19 is cleared by any of M3,M4,M5.
Spindle orientation requires a quadrature encoder with an index to sense the spindle shaft position
and direction of rotation.
INI Settings in the [RS274NGC] section.
ORIENT_OFFSET = 0-360 (fixed offset in degrees added to M19 R word)
HAL Pins
* ``spindle.N.orient-angle`` (out float) Desired spindle orientation for M19. Value of the M19 R word
parameter plus the value of the [RS274NGC]ORIENT_OFFSET ini parameter.
* ``spindle.N.orient-mode`` (out s32) Desired spindle rotation mode. Reflects M19 P parameter word,
Default = 0
* ``spindle.N.orient`` (out bit) Indicates start of spindle orient cycle. Set by M19. Cleared by any
of M3,M4,M5. If spindle-orient-fault is not zero during spindle-orient true, the M19 command fails
with an error message.
* ``spindle.N.is-oriented`` (in bit) Acknowledge pin for spindle-orient. Completes orient cycle. If
spindle-orient was true when spindle-is-oriented was asserted, the spindle-orient pin is cleared
and the spindle-locked pin is asserted. Also, the spindle-brake pin is asserted.
* ``spindle.N.orient-fault`` (in s32) Fault code input for orient cycle. Any value other than zero
will cause the orient cycle to abort.
* ``spindle.N.locked`` (out bit) Spindle orient complete pin. Cleared by any of M3,M4,M5.
M48, M49 Speed and Feed Override Control
----------------------------------------
* ``M48`` - enable the spindle speed and feed rate override controls.
* ``M49`` - disable both controls.
These commands also take an optional $ parameter to determine which spindle they operate on.
It is OK to enable or disable the controls when they are already enabled or disabled. See the `Feed
Rate <#sub:feed-rate>`__ Section for more details.
M50 Feed Override Control
-------------------------
* ``M50 <P1>`` - enable the feed rate override control. The P1 is optional.
* ``M50 P0`` - disable the feed rate control.
While disabled the feed override will have no influence, and the motion will be executed at
programmed feed rate. (unless there is an adaptive feed rate override active).
M51 Spindle Speed Override Control
----------------------------------
* ``M51 <P1> <$→``- enable the spindle speed override control for the selected spindle. The P1 is
optional.
* ``M51 P0 <$→`` - disable the spindle speed override control program. While disabled the spindle
speed override will have no influence, and the spindle speed will have the exact program specified
value of the S-word (described in `Spindle Speed <#sec:set-spindle-speed>`__ Section).
M52 Adaptive Feed Control
-------------------------
* ``M52 <P1>`` - use an adaptive feed. The P1 is optional.
* ``M52 P0`` - stop using adaptive feed.
When adaptive feed is enabled, some external input value is used together with the user interface
feed override value and the commanded feed rate to set the actual feed rate. In LinuxCNC, the HAL
pin ``motion.adaptive-feed`` is used for this purpose. Values on ``motion.adaptive-feed`` should range
from 0 (feed hold) to 1 (full speed).
M53 Feed Stop Control
---------------------
* ``M53 <P1>`` - enable the feed stop switch. The P1 is optional. Enabling the feed stop switch will
allow motion to be interrupted by means of the feed stop control. In LinuxCNC, the HAL pin
``motion.feed-hold`` is used for this purpose. A ``true`` value will cause the motion to stop when
``M53`` is active.
* ``M53 P0`` - disable the feed stop switch. The state of ``motion.feed-hold`` will have no effect on
feed when M53 is not active.
M61 Set Current Tool
--------------------
* ``M61 Q-`` - change the current tool number while in MDI or Manual mode. One use is when you power
up LinuxCNC with a tool currently in the spindle you can set that tool number without doing a tool
change.
It is an error if:
* Q- is not 0 or greater
M62 - M65 Digital Output Control
--------------------------------
* ``M62 P-`` - turn on digital output synchronized with motion. The P- word specifies the digital
output number.
* ``M63 P-`` - turn off digital output synchronized with motion. The P- word specifies the digital
output number.
* ``M64 P-`` - turn on digital output immediately. The P- word specifies the digital output number.
* ``M65 P-`` - turn off digital output immediately. The P- word specifies the digital output number.
The P-word ranges from 0 to a default value of 3. If needed the the number of I/O can be increased
by using the num_dio parameter when loading the motion controller. See the `Motion Section
<#sec:motion>`__ for more information.
The M62 & M63 commands will be queued. Subsequent commands referring to the same output number will
overwrite the older settings. More than one output change can be specified by issuing more than one
M62/M63 command.
The actual change of the specified outputs will happen at the beginning of the next motion
command. If there is no subsequent motion command, the queued output changes won’t happen. It’s best
to always program a motion G code (G0, G1, etc) right after the M62/63.
M64 & M65 happen immediately as they are received by the motion controller. They are not
synchronized with movement, and they will break blending.
M66 Wait on Input
-----------------
::
M66 P- | E- <L->
* ``P-`` - specifies the digital input number from 0 to 3.
* ``E-`` - specifies the analog input number from 0 to 3.
* ``L-`` - specifies the wait mode type.
* ``Mode 0: IMMEDIATE`` - no waiting, returns immediately. The current value of the input is stored
in parameter #5399
* ``Mode 1: RISE`` - waits for the selected input to perform a rise event.
* ``Mode 2: FALL`` - waits for the selected input to perform a fall event.
* ``Mode 3: HIGH`` - waits for the selected input to go to the HIGH state.
* ``Mode 4: LOW`` - waits for the selected input to go to the LOW state.
* ``Q-`` - specifies the timeout in seconds for waiting. If the timeout is exceeded, the wait is
interrupt, and the variable #5399 will be holding the value -1. The Q value is ignored if the
L-word is zero (IMMEDIATE). A Q value of zero is an error if the L-word is non-zero.
* Mode 0 is the only one permitted for an analog input.
M66 Example Lines
::
M66 P0 L3 Q5 (wait up to 5 seconds for digital input 0 to turn on)
M66 wait on an input stops further execution of the program, until the selected event (or the
programmed timeout) occurs.
It is an error to program M66 with both a P-word and an E-word (thus selecting both an analog and a
digital input). In LinuxCNC these inputs are not monitored in real time and thus should not be used
for timing-critical applications.
The number of I/O can be increased by using the num_dio or num_aio parameter when loading the motion
controller. See the `Motion Section <#sec:motion>`__ for more information.
Example HAL Connection
::
net signal-name motion.digital-in-00 <= parport.0.pin10-in
M67 Analog Output,Synchronized
------------------------------
::
M67 E- Q-
* ``M67`` - set an analog output synchronized with motion.
* ``E-`` - output number ranging from 0 to 3.
* ``Q-`` - is the value to set (set to 0 to turn off).
The actual change of the specified outputs will happen at the beginning of the next motion
command. If there is no subsequent motion command, the queued output changes won’t happen. It’s best
to always program a motion G code (G0, G1, etc) right after the M67. M67 functions the same as
M62-63.
The number of I/O can be increased by using the num_dio or num_aio parameter when loading the motion
controller. See the `Motion Section <#sec:motion>`__ for more information.
M68 Analog Output, Immediate
----------------------------
::
M68 E- Q-
* ``M68`` - set an analog output immediately.
* ``E-`` - output number ranging from 0 to 3.
* ``Q-`` - is the value to set (set to 0 to turn off).
M68 output happen immediately as they are received by the motion controller. They are not
synchronized with movement, and they will break blending. M68 functions the same as M64-65.
The number of I/O can be increased by using the num_dio or num_aio parameter when loading the motion
controller. See the `Motion Section <#sec:motion>`__ for more information.
M70 Save Modal State
--------------------
To explicitly save the modal state at the current call level, program ``M70``. Once modal state has
been saved with ``M70``, it can be restored to exactly that state by executing an ``M72``.
A pair of ``M70`` and ``M72`` instructions will typically be used to protect a program against
inadvertant modal changes within subroutines.
The state saved consists of:
* current G20/G21 settings (imperial/metric)
* selected plane (G17/G18/G19 G17.1,G18.1,G19.1)
* status of cutter compensation (G40,G41,G42,G41.1,G42,1)
* distance mode - relative/absolute (G90/G91)
* feed mode (G93/G94,G95)
* current coordinate system (G54-G59.3)
* tool length compensation status (G43,G43.1,G49)
* retract mode (G98,G99)
* spindle mode (G96-css or G97-RPM)
* arc distance mode (G90.1, G91.1)
* lathe radius/diameter mode (G7,G8)
* path control mode (G61, G61.1, G64)
* current feed and speed (``F`` and ``S`` values)
* spindle status (M3,M4,M5) - on/off and direction
* mist (M7) and flood (M8) status
* speed override (M51) and feed override (M50) settings
* adaptive feed setting (M52)
* feed hold setting (M53)
Note that in particular, the motion mode (G1 etc) is NOT restored.
``current call level`` means either:
* executing in the main program. There is a single storage location for state at the main program
level; if several ``M70`` instructions are executed in turn, only the most recently saved state is
restored when an ``M72`` is executed.
* executing within a G-code subroutine. The state saved with ``M70`` within a subroutine behaves
exactly like a local named parameter - it can be referred to only within this subroutine
invocation with an ``M72`` and when the subroutine exits, the parameter goes away.
A recursive invocation of a subroutine introduces a new call level.
M71 Invalidate Stored Modal State
---------------------------------
Modal state saved with an ``M70`` or by an ``M73`` at the current call level is invalidated (cannot be
restored from anymore).
A subsequent ``M72`` at the same call level will fail.
If executed in a subroutine which protects modal state by an ``M73``, a subsequent return or endsub
will **not** restore modal state.
The usefulness of this feature is dubious. It should not be relied upon as it might go away.
M72 Restore Modal State
-----------------------
`Modal state saved with an ``M70`` <#mcode:m70-saved-state>`__ code can be restored by executing an
``M72``.
The handling of G20/G21 is specially treated as feeds are interpreted differently depending on
G20/G21: if length units (mm/in) are about to be changed by the restore operation, ``M72 ``will
restore the distance mode first, and then all other state including feed to make sure the feed value
is interpreted in the correct unit setting.
It is an error to execute an ``M72`` with no previous ``M70`` save operation at that level.
The following example demonstrates saving and explicitely restoring modal state around a subroutine
call using ``M70`` and ``M72``. Note that the ``imperialsub`` subroutine is not "aware" of the M7x
features and can be used unmodified:
.. code:: text
O<showstate> sub
(DEBUG, imperial=#<_imperial> absolute=#<_absolute> feed=#<_feed> rpm=#<_rpm>)
O<showstate> endsub
O<imperialsub> sub
g20 (imperial)
g91 (relative mode)
F5 (low feed)
S300 (low rpm)
(debug, in subroutine, state now:)
o<showstate> call
O<imperialsub> endsub
; main program
g21 (metric)
g90 (absolute)
f200 (fast speed)
S2500 (high rpm)
(debug, in main, state now:)
o<showstate> call
M70 (save caller state in at global level)
O<imperialsub> call
M72 (explicitely restore state)
(debug, back in main, state now:)
o<showstate> call
m2
M73 Save and Autorestore Modal State
------------------------------------
To save modal state within a subroutine, and restore state on subroutine ``endsub`` or any ``return``
path, program ``M73``.
Aborting a running program in a subroutine which has an ``M73`` operation will **not** restore state .
Also, the normal end (``M2``) of a main program which contains an ``M73`` will **not** restore state.
The suggested use is at the beginning of a O-word subroutine as in the following example. Using
``M73`` this way enables designing subroutines which need to modify modal state but will protect the
calling program against inadvertant modal changes. Note the use of `predefined named parameters
<#gcode:predefined-named-parameters>`__ in the ``showstate`` subroutine.
.. code:: text
O<showstate> sub
(DEBUG, imperial=#<_imperial> absolute=#<_absolute> feed=#<_feed> rpm=#<_rpm>)
O<showstate> endsub
O<imperialsub> sub
M73 (save caller state in current call context, restore on return or endsub)
g20 (imperial)
g91 (relative mode)
F5 (low feed)
S300 (low rpm)
(debug, in subroutine, state now:)
o<showstate> call
; note - no M72 is needed here - the following endsub or an
; explicit ``return`` will restore caller state
O<imperialsub> endsub
; main program
g21 (metric)
g90 (absolute)
f200 (fast speed)
S2500 (high rpm)
(debug, in main, state now:)
o<showstate> call
o<imperialsub> call
(debug, back in main, state now:)
o<showstate> call
m2
M98 and M99
-----------
The interpreter supports Fanuc-style main- and sub-programs with the ``M98`` and ``M99`` M-codes. See
`Fanuc-Style Programs <#ocode:fanuc-style-programs>`__.
Selectively Restoring Modal State
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Executing an ``M72`` or returning from a subroutine which contains an ``M73`` will restore `all modal
state saved <#mcode:m70-saved-state>`__.
If only some aspects of modal state should be preserved, an alternative is the usage of `predefined
named parameters <#gcode:predefined-named-parameters>`__, local parameters and conditional
statements. The idea is to remember the modes to be restored at the beginning of the subroutine, and
restore these before exiting. Here is an example, based on snippet of
``nc_files/tool-length-probe.ngc``:
.. code:: text
O<measure> sub (measure reference tool)
;
#<absolute> = #<_absolute> (remember in local variable if G90 was set)
;
g30 (above switch)
g38.2 z0 f15 (measure)
g91 g0z.2 (off the switch)
#1000=#5063 (save reference tool length)
(print,reference length is #1000)
;
O<restore_abs> if [#<absolute>]
g90 (restore G90 only if it was set on entry:)
O<restore_abs> endif
;
O<measure> endsub
M100 - M199 User Defined Commands
---------------------------------
::
M1-- <P- Q->
* ``M1--`` - an integer in the range of 100 - 199.
* ``P-`` - a number passed to the file as the first parameter.
* ``Q-`` - a number passed to the file as the second parameter.
The external program named ``M100`` through ``M199`` (no extension and a capitol M) is executed with the
optional P and Q values as its two arguments. Execution of the G code file pauses until the external
program exits. Any valid executable file can be used. The file must be located in the search path
specificed in the ini file configuration. See the `Display Section <#sec:display-section>`__ for
more information on search paths.
The error ``Unknown M code used`` denotes one of the following
* The specified User Defined Command does not exist
* The file is not an executable file
* The file name has an extension
* The file name does not follow this format M1nn where nn = 00 through 99
* The file name used a lower case M
For example to open and close a collet closer that is controlled by a parallel port pin using a bash
script file using M101 and M102. Create two files named M101 and M102. Set them as executable files
(typically right click/properties/permissions) before running LinuxCNC. Make sure the parallel port
pin is not connected to anything in a HAL file.
M101 Example File
::
#!/bin/bash
# file to turn on parport pin 14 to open the collet closer
halcmd setp parport.0.pin-14-out True
exit 0
M102 Example File
::
#!/bin/bash
# file to turn off parport pin 14 to open the collet closer
halcmd setp parport.0.pin-14-out False
exit 0
To pass a variable to a M1nn file you use the P and Q option like this:
::
M100 P123.456 Q321.654
M100 Example file
::
#!/bin/bash
voltage=$1
feedrate=$2
halcmd setp thc.voltage $voltage
halcmd setp thc.feedrate $feedrate
exit 0
To display a graphic message and stop until the message window is closed
use a graphic display program like Eye of Gnome to display the graphic
file. When you close it the program will resume.
M110 Example file
::
#!/bin/bash
eog /home/john/linuxcnc/nc_files/message.png
exit 0
To display a graphic message and continue processing the G code file suffix an ampersand to the
command.
M110 Example display and keep going
::
#!/bin/bash
eog /home/john/linuxcnc/nc_files/message.png &
exit 0
CNC Machine Overview
====================
This section gives a brief description of how a CNC machine is viewed from the input and output ends
of the Interpreter.
Mechanical Components
---------------------
A CNC machine has many mechanical components that may be controlled or may affect the way in which
control is exercised. This section describes the subset of those components that interact with the
Interpreter. Mechanical components that do not interact directly with the Interpreter, such as the
jog buttons, are not described here, even if they affect control.
Axes
~~~~
Any CNC machine has one or more Axes. Different types of CNC machines have different
combinations. For instance, a '4-axis milling machine' may have XYZA or XYZB axes. A lathe typically
has XZ axes. A foam-cutting machine may have XYUV axes. In LinuxCNC, the case of a XYYZ 'gantry'
machine with two motors for one axis is better handled by kinematics rather than by a second linear
axis. ^([`1 <#_footnote_1>`__])
Primary Linear Axes
The X, Y, and Z axes produce linear motion in three mutually orthogonal directions.
Secondary Linear Axes
The U, V, and W axes produce linear motion in three mutually orthogonal directions. Typically, X and
U are parallel, Y and V are parallel, and Z and W are parallel.
Rotational Axes
The A, B and C axes produce angular motion (rotation). Typically, A rotates around a line parallel
to X, B rotates around a line parallel to Y, and C rotates around a line parallel to Z.
Spindle
~~~~~~~
A CNC machine typically has a spindle which holds one cutting tool, probe, or the material in the
case of a lathe. The spindle may or may not be controlled by the CNC software. LinuxCNC offers
suport for up to 8 spindles, which can be individually controlled and can run simultaneously at
different speeds and in different directions.
Coolant
~~~~~~~
If a CNC machine has components to provide mist coolant and/or flood coolant they can be controlled
by G codes.
Feed and Speed Override
~~~~~~~~~~~~~~~~~~~~~~~
A CNC machine can have separate feed and speed override controls, which let the operator specify
that the actual feed rate or spindle speed used in machining at some percentage of the programmed
rate.
Block Delete Switch
~~~~~~~~~~~~~~~~~~~
A CNC machine can have a block delete switch. See the `Block Delete <#sub:block-delete-switch>`__
Section.
Optional Program Stop Switch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A CNC machine can have an optional program stop switch. See the `Optional Program Stop
<#sub:optional-program-stop>`__ Section.
Control and Data Components
---------------------------
Linear Axes
~~~~~~~~~~~
The X, Y, and Z axes form a standard right-handed coordinate system of orthogonal linear
axes. Positions of the three linear motion mechanisms are expressed using coordinates on these axes.
The U, V and W axes also form a standard right-handed coordinate system. X and U are parallel, Y
and V are parallel, and Z and W are parallel (when A, B, and C are rotated to zero).
Rotational Axes
~~~~~~~~~~~~~~~
The rotational axes are measured in degrees as wrapped linear axes in which the direction of
positive rotation is counterclockwise when viewed from the positive end of the corresponding X, Y,
or Z-axis. By 'wrapped linear axis', we mean one on which the angular position increases without
limit (goes towards plus infinity) as the axis turns counterclockwise and deceases without limit
(goes towards minus infinity) as the axis turns clockwise. Wrapped linear axes are used regardless
of whether or not there is a mechanical limit on rotation.
Clockwise or counterclockwise is from the point of view of the workpiece. If the workpiece is
fastened to a turntable which turns on a rotational axis, a counterclockwise turn from the point of
view of the workpiece is accomplished by turning the turntable in a direction that (for most common
machine configurations) looks clockwise from the point of view of someone standing next to the
machine. ^([`2 <#_footnote_2>`__])
Controlled Point
~~~~~~~~~~~~~~~~
The controlled point is the point whose position and rate of motion are controlled. When the tool
length offset is zero (the default value), this is a point on the spindle axis (often called the
gauge point) that is some fixed distance beyond the end of the spindle, usually near the end of a
tool holder that fits into the spindle. The location of the controlled point can be moved out along
the spindle axis by specifying some positive amount for the tool length offset. This amount is
normally the length of the cutting tool in use, so that the controlled point is at the end of the
cutting tool. On a lathe, tool length offsets can be specified for X and Z axes, and the controlled
point is either at the tool tip or slightly outside it (where the perpendicular, axis-aligned lines
touched by the 'front' and 'side' of the tool intersect).
Coordinated Linear Motion
~~~~~~~~~~~~~~~~~~~~~~~~~
To drive a tool along a specified path, a machining center must often coordinate the motion of
several axes. We use the term 'coordinated linear motion' to describe the situation in which,
nominally, each axis moves at constant speed and all axes move from their starting positions to
their end positions at the same time. If only the X, Y, and Z axes (or any one or two of them) move,
this produces motion in a straight line, hence the word 'linear' in the term. In actual motions, it
is often not possible to maintain constant speed because acceleration or deceleration is required at
the beginning and/or end of the motion. It is feasible, however, to control the axes so that, at all
times, each axis has completed the same fraction of its required motion as the other axes. This
moves the tool along same path, and we also call this kind of motion coordinated linear motion.
Coordinated linear motion can be performed either at the prevailing feed rate, or at traverse rate,
or it may be synchronized to the spindle rotation. If physical limits on axis speed make the desired
rate unobtainable, all axes are slowed to maintain the desired path.
Feed Rate
~~~~~~~~~
The rate at which the controlled point moves is nominally a steady rate which may be set by the
user. In the Interpreter, the feed rate is interpreted as follows (unless 'inverse time feed' or
'feed per revolution' modes are being used, in which case see Section `G93-G94-G95-Mode,G93 G94 G95
<#gcode:g93-g94-g95>`__).
#. If any of XYZ are moving, F is in units per minute in the XYZ cartesian system, and all other
axes (ABCUVW) move so as to start and stop in coordinated fashion.
#. Otherwise, if any of UVW are moving, F is in units per minute in the UVW cartesian system, and
all other axes (ABC) move so as to start and stop in coordinated fashion.
#. Otherwise, the move is pure rotary motion and the F word is in rotary units in the ABC
'pseudo-cartesian' system.
.. _coolant-1:
Coolant
~~~~~~~
Flood coolant and mist coolant may each be turned on independently. The RS274/NGC language turns
them off together see Section `M7 M8 M9 <#mcode:m7-m8-m9>`__.
Dwell
~~~~~
A machining center may be commanded to dwell (i.e., keep all axes unmoving) for a specific amount of
time. The most common use of dwell is to break and clear chips, so the spindle is usually turning
during a dwell. Regardless of the Path Control Mode (see Section `Path Control
<#sec:path-control-mode>`__) the machine will stop exactly at the end of the previous programmed
move, as though it was in exact path mode.
Units
~~~~~
Units used for distances along the X, Y, and Z axes may be measured in millimeters or inches. Units
for all other quantities involved in machine control cannot be changed. Different quantities use
different specific units. Spindle speed is measured in revolutions per minute. The positions of
rotational axes are measured in degrees. Feed rates are expressed in current length units per
minute, or degrees per minute, or length units per spindle revolution, as described in Section `G93
G94 G95 <#gcode:g93-g94-g95>`__.
Current Position
~~~~~~~~~~~~~~~~
The controlled point is always at some location called the 'current position', and the controller
always knows where that is. The numbers representing the current position must be adjusted in the
absence of any axis motion if any of several events take place:
#. Length units are changed.
#. Tool length offset is changed.
#. Coordinate system offsets are changed.
Selected Plane
~~~~~~~~~~~~~~
There is always a 'selected plane', which must be the XY-plane, the
YZ-plane, or the XZ-plane of the machining center. The Z-axis is, of
course, perpendicular to the XY-plane, the X-axis to the YZ-plane, and
the Y-axis to the XZ-plane.
Tool Carousel
~~~~~~~~~~~~~
Zero or one tool is assigned to each slot in the tool carousel.
Tool Change
~~~~~~~~~~~
A machining center may be commanded to change tools.
Pallet Shuttle
~~~~~~~~~~~~~~
The two pallets may be exchanged by command.
Path Control Mode
~~~~~~~~~~~~~~~~~
The machining center may be put into any one of three path control modes: (1) exact stop mode, (2)
exact path mode, or (3) continuous mode with optional tolerance. In exact stop mode, the machine
stops briefly at the end of each programmed move. In exact path mode, the machine follows the
programmed path as exactly as possible, slowing or stopping if necessary at sharp corners of the
path. In continuous mode, sharp corners of the path may be rounded slightly so that the feed rate
may be kept up (but by no more than the tolerance, if specified). See Sections `G61/G61.1
<#gcode:g61-g61.1>`__ and `G64 <#gcode:g64>`__.
Interpreter Interaction with Switches
-------------------------------------
The Interpreter interacts with several switches. This section describes
the interactions in more detail. In no case does the Interpreter know
what the setting of any of these switches is.
Feed and Speed Override Switches
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Interpreter will interpret RS274/NGC commands which enable 'M48' or disable 'M49' the feed and
speed override switches. For certain moves, such as the traverse out of the end of a thread during a
threading cycle, the switches are disabled automatically.
LinuxCNC reacts to the speed and feed override settings when these switches are enabled.
See the `M48 M49 Override <#mcode:m48-m49>`__ section for more information.
.. _block-delete-switch-1:
Block Delete Switch
~~~~~~~~~~~~~~~~~~~
If the block delete switch is on, lines of G code which start with a slash (the block delete
character) are not interpreted. If the switch is off, such lines are interpreted. Normally the block
delete switch should be set before starting the NGC program.
.. _optional-program-stop-switch-1:
Optional Program Stop Switch
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If this switch is on and an M1 code is encountered, program execution is paused.
Tool Table
----------
A tool table is required to use the Interpreter. The file tells which tools are in which tool
changer slots and what the size and type of each tool is. The name of the tool table is defined in
the ini file:
::
[EMCIO]
# tool table file
TOOL_TABLE = tooltable.tbl
The default filename probably looks something like the above, but you may prefer to give your
machine its own tool table, using the same name as your ini file, but with a tbl extension:
::
TOOL_TABLE = acme_300.tbl
or
::
TOOL_TABLE = EMC-AXIS-SIM.tbl
For more information on the specifics of the tool table format, see the `Tool Table Format
<#sec:tool-table>`__ Section.
Parameters
----------
In the RS274/NGC language view, a machining center maintains an array of numerical parameters
defined by a system definition (RS274NGC_MAX_PARAMETERS). Many of them have specific uses especially
in defining coordinate systems. The number of numerical parameters can increase as development adds
support for new parameters. The parameter array persists over time, even if the machining center is
powered down. LinuxCNC uses a parameter file to ensure persistence and gives the Interpreter the
responsibility for maintaining the file. The Interpreter reads the file when it starts up, and
writes the file when it exits.
All parameters are available for use in G code programs.
The format of a parameter file is shown in the following table. The file consists of any number of
header lines, followed by one blank line, followed by any number of lines of data. The Interpreter
skips over the header lines. It is important that there be exactly one blank line (with no spaces or
tabs, even) before the data. The header line shown in the following table describes the data
columns, so it is suggested (but not required) that that line always be included in the header.
The Interpreter reads only the first two columns of the table. The third column, 'Comment', is not
read by the Interpreter.
Each line of the file contains the index number of a parameter in the first column and the value to
which that parameter should be set in the second column. The value is represented as a
double-precision floating point number inside the Interpreter, but a decimal point is not required
in the file. All of the parameters shown in the following table are required parameters and must be
included in any parameter file, except that any parameter representing a rotational axis value for
an unused axis may be omitted. An error will be signaled if any required parameter is missing. A
parameter file may include any other parameter, as long as its number is in the range 1 to 5400. The
parameter numbers must be arranged in ascending order. An error will be signaled if not. Any
parameter included in the file read by the Interpreter will be included in the file it writes as it
exits. The original file is saved as a backup file when the new file is written. Comments are not
preserved when the file is written.
================ =============== ==========
Parameter Number Parameter Value Comment
================ =============== ==========
5161 0.0 G28 Home X
5162 0.0 G28 Home Y
================ =============== ==========
See the `Parameters <#gcode:parameters>`__ section for more information.
--------------
`1 <#_footnoteref_1>`__. If the motion of mechanical components is not independent, as with hexapod
machines, the RS274/NGC language and the canonical machining functions will still be usable, as long
as the lower levels of control know how to control the actual mechanisms to produce the same
relative motion of tool and workpiece as would be produced by independent axes. This is called
'kinematics'.
`2 <#_footnoteref_2>`__. If the parallelism requirement is violated, the system builder will have to
say how to distinguish clockwise from counterclockwise.
O Codes
=======
O-codes provide for flow control in NC programs. Each block has an associated number, which is the
number used after O. Care must be taken to properly match the O-numbers. O codes use the letter ``O``
not the number zero as the first character in the number like O100 or o100.
Numbering
---------
Numbered O codes must have a unique number for each subroutine,
Numbering Example
::
(the start of o100)
o100 sub
(notice that the if-endif block uses a different number)
(the start of o110)
o110 if [#2 GT 5]
(some code here)
(the end of o110)
o110 endif
(some more code here)
(the end of o100)
o100 endsub
Comments
--------
Comments on the same line as the O word should not be used as the behavior can change in the future.
The behavior is undefined if:
* The same number is used for more than one block
* Other words are used on a line with an O- word
* Comments are used on a line with an O-word
[TABLE]
Subroutines
-----------
Subroutines starts at ``Onnn sub`` and ends at ``Onnn endsub``. The lines between ``Onnn sub`` and ``Onnn
endsub`` are not executed until the subroutine is called with ``Onnn call``. Each subroutine must use a
unique number.
Subroutine Example
::
o100 sub
G53 G0 X0 Y0 Z0 (rapid move to machine home)
o100 endsub
(the subroutine is called)
o100 call
M2
See `G53 <#gcode:g53>`__ & `G0 <#gcode:g0>`__ & `M2 <#mcode:m2-m30>`__ sections for more
information.
O- Return
Inside a subroutine, ``O- return`` can be executed. This immediately returns to the calling code, just
as though ``O- endsub`` was encountered.
O- Return Example
::
o100 sub
(test if parameter #2 is greater than 5)
o110 if [#2 GT 5]
(return to top of subroutine if test is true)
o100 return
o110 endif
(this only gets executed if parameter #2 is not greater than 5)
(DEBUG, parameter 1 is [#1])
o100 endsub
See the `Binary Operators <#gcode:binary-operators>`__ & `Parameters <#gcode:parameters>`__ sections
for more information.
O- Call
``O- Call`` takes up to 30 optional arguments, which are passed to the subroutine as ``#1``, ``#2`` , …​,
#N. Parameters from #N+1 to #30 have the same value as in the calling context. On return from the
subroutine, the values of parameters #1 through #30 (regardless of the number of arguments) will be
restored to the values they had before the call. Parameters #1 - #30 are local to the subroutine.
Because ``1 2 3`` is parsed as the number 123, the parameters must be enclosed in square brackets. The
following calls a subroutine with 3 arguments:
O- Call Example
::
o100 sub
(test if parameter #2 is greater than 5)
o110 if [#2 GT 5]
(return to top of subroutine if test is true)
o100 return
o110 endif
(this only gets executed if parameter #2 is not greater than 5)
(DEBUG, parameter 1 is [#1])
o100 endsub
o100 call [1] [2]
Subroutine bodies may not be nested. They may only be called after they are defined. They may be
called from other functions, and may call themselves recursively if it makes sense to do so. The
maximum subroutine nesting level is 10.
Subroutines do not have ``return values``, but they may change the value of parameters above #30 and
those changes will be visible to the calling code. Subroutines may also change the value of global
named parameters.
Fanuc-Style Numbered Programs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Numbered programs (both main and subprograms), the ``M98`` call and ``M99`` return M-codes, and their
respective semantic differences are an alternative to the rs274ngc subroutines described above,
provided for compatibility with Fanuc and other machine controllers.
Numbered programs are enabled by default, and may be disabled by placing ``DISABLE_FANUC_STYLE_SUB =
1`` in the ``[RS274NGC]`` section of the ``.ini`` file.
Numbered Subprogram Simple Example
.. code:: highlight
o1 (Example 1) ; Main program 1, "Example 1"
M98 P100 ; Call subprogram 100
M30 ; End main program
o100 ; Beginning of subprogram 100
G53 G0 X0 Y0 Z0 ; Rapid move to machine home
M99 ; Return from subprogram 100
``o1 (Title)``
The optional main program beginning block gives the main program the number ``1``. Some controllers
treat an optional following parenthesized comment as a program title, ``Example 1`` in this example,
but this has no special meaning in the rs274ngc interpreter.
``M98 P- <L->``
Call a numbered subprogram. The block ``M98 P100`` is analogous to the traditional ``o100 call``
syntax, but may only be used to call a following numbered subprogram defined with ``o100``\ …​\
``M99``. An optional ``L``-word specifies a loop count.
``M30``
The main program must be terminated with ``M02`` or ``M30`` (or ``M99``; see below).
``O-`` subprogram definition start
Marks the start of a numbered subprogram definition. The block ``O100`` is similar to ``o100 sub``,
except that it must be placed later in the file than the ``M98 P100`` calling block.
``M99`` return from numbered subroutine
The block ``M99`` is analogous to the traditional ``o100 endsub`` syntax, but may only terminate a
numbered program (``o100`` in this example), and may not terminate a subroutine beginning with the
``o100 sub`` syntax.
The ``M98`` subprogram call differs from rs274ngc ``O call`` in the following ways:
* The numbered subprogram must follow the ``M98`` call in the program file. The interpreter will
throw an error if the subprogram precedes the call block.
* Parameters ``#1``, ``#2``, …​, ``#30`` are global and accessible in numbered subprograms, similar
to higher-numbered parameters in traditional style calls. Modifications to these parameters within
a subprogram are global modifications, and will be persist after subprogram return.
* ``M98`` subprogram calls have no return value.
* ``M98`` subprogram call blocks may contain an optional L-word specifying a loop repeat
count. Without the L-word, the subprogram will execute once only (equivalent to ``M98 L1``). An
``M98 L0`` block will not execute the subprogram.
In rare cases, the ``M99`` M-code may be used to terminate the main program, where it indicates an
``endless program``. When the interpreter reaches an ``M99`` in the main program, it will skip back to
the beginning of the file and resume execution at the first line. An example use of an endless
program is in a machine warm-up cycle; a block delete program end ``/M30`` block might be used to
stop the cycle at a tidy point when the operator is ready.
Numbered Subprogram Full Example
.. code:: highlight
O1 ; Main program 1
#1 = 0
(PRINT,X MAIN BEGIN: 1=#1)
M98 P100 L5 ; Call subprogram 100
(PRINT,X MAIN END: 1=#1)
M30 ; End main program
O100 ; Subprogram 100
#1 = [#1 + 1]
M98 P200 L5 ; Call subprogram 200
(PRINT,>> O100: #1)
M99 ; Return from Subprogram 100
O200 ; Subprogram 200
#1 = [#1 + 0.01]
(PRINT,>>>> O200: #1)
M99 ; Return from Subprogram 200
In this example, parameter ``#1`` is initialized to ``0``. Subprogram ``O100`` is called five times
in a loop. Nested within each call to ``O100``, subprogram ``O200`` is called five times in a loop,
for 25 times total.
Note that parameter ``#1`` is global. At the end of the main program, after updates within ``O100``
and ``O200``, its value will equal ``5.25``.
Looping
-------
The ``while loop`` has two structures: ``while/endwhile``, and ``do/while``. In each case, the loop is
exited when the ``while`` condition evaluates to false. The difference is when the test condition is
done. The ``do/while`` loop runs the code in the loop then checks the test condition. The
``while/endwhile`` loop does the test first.
While Endwhile Example
::
(draw a sawtooth shape)
G0 X1 Y0 (move to start position)
#1 = 0 (assign parameter #1 the value of 0)
F25 (set a feed rate)
o101 while [#1 LT 10]
G1 X0
G1 Y[#1/10] X1
#1 = [#1+1] (increment the test counter)
o101 endwhile
M2 (end program)
Do While Example
::
#1 = 0 (assign parameter #1 the value of 0)
o100 do
(debug, parameter 1 = #1)
o110 if [#1 EQ 2]
#1 = 3 (assign the value of 3 to parameter #1)
(msg, #1 has been assigned the value of 3)
o100 continue (skip to start of loop)
o110 endif
(some code here)
#1 = [#1 + 1] (increment the test counter)
o100 while [#1 LT 3]
(msg, Loop Done!)
M2
Inside a while loop, ``O- break`` immediately exits the loop, and ``O- continue`` immediately skips to
the next evaluation of the ``while`` condition. If it is still true, the loop begins again at the
top. If it is false, it exits the loop.
Conditional
-----------
The ``if`` conditional consists of a group of statements with the same ``o`` number that start with ``if``
and end with ``endif``. Optional ``elseif`` and ``else`` conditions may be between the starting ``if`` and
the ending ``endif``.
If the ``if`` conditional evaluates to true then the group of statements following the ``if`` up to the
next conditional line are executed.
If the ``if`` conditional evaluates to false then the ``elseif`` conditions are evaluated in order until
one evaluates to true. If the ``elseif`` condition is true then the statements following the ``elseif``
up to the next conditional line are executed. If none of the ``if`` or ``elseif`` conditions evaluate to
true then the statements following the ``else`` are executed. When a condition is evaluated to true no
more conditions are evaluated in the group.
If Endif Example
::
(if parameter #31 is equal to 3 set S2000)
o101 if [#31 EQ 3]
S2000
o101 endif
If ElseIf Else EndIf Example
::
(if parameter #2 is greater than 5 set F100)
o102 if [#2 GT 5]
F100
o102 elseif [#2 LT 2]
(else if parameter #2 is less than 2 set F200)
F200
(else if parameter #2 is 2 through 5 set F150)
o102 else
F150
o102 endif
Several conditons may be tested for by ``elseif`` statements until the ``else`` path is finally executed
if all preceding conditons are false:
If Elseif Else Endif Example
::
(if parameter #2 is greater than 5 set F100)
O102 if [#2 GT 5]
F100
(else if parameter #2 less than 2 set F200)
O102 elseif [#2 LT 2]
F20
(parameter #2 is between 2 and 5)
O102 else
F200
O102 endif
Repeat
------
The ``repeat`` will execute the statements inside of the repeat/endrepeat the specified number of
times. The example shows how you might mill a diagonal series of shapes starting at the present
position.
Repeat Example
::
(Mill 5 diagonal shapes)
G91 (Incremental mode)
o103 repeat [5]
... (insert milling code here)
G0 X1 Y1 (diagonal move to next position)
o103 endrepeat
G90 (Absolute mode)
Indirection
-----------
The O-number may be given by a parameter and/or calculation.
Indirection Example
::
o[#101+2] call
Computing values in O-words
For more information on computing values see the following sections
* `Parameters <#gcode:parameters>`__
* `Expressions <#gcode:expressions>`__
* `Binary Operators <#gcode:binary-operators>`__
* `Functions <#gcode:functions>`__
Calling Files
-------------
To call a separate file with a subroutine name the file the same as your call and include a sub and
endsub in the file. The file must be in the directory pointed to by ``PROGRAM_PREFIX`` or
``SUBROUTINE_PATH`` in the ini file. The file name can include **lowercase** letters, numbers, dash,
and underscore only. A named subroutine file can contain only a single subroutine definition.
Named File Example
::
o<myfile> call
Numbered File Example
::
o123 call
In the called file you must include the oxxx sub and endsub and the file
must be a valid file.
Called File Example
::
(filename myfile.ngc)
o<myfile> sub
(code here)
o<myfile> endsub
M2
[TABLE]
Subroutine return values
------------------------
Subroutines may optionally return a value by an optional expression at an ``endsub`` or ``return``
statement.
Return value example
::
o123 return [#2 *5]
...
o123 endsub [3 * 4]
A subroutine return value is stored in the ``<_value>`` `predefined named parameter
<#gcode:predefined-named-parameters>`__ , and the ``<_value_returned>`` predefined parameter is set
to 1, to indicate a value was returned. Both parameters are global, and are cleared just before the
next subroutine call.
Errors
------
The following statements cause an error message and abort the
interpreter:
* a ``return`` or ``endsub`` not within a sub defintion
* a label on ``repeat`` which is defined elsewhere
* a label on ``while`` which is defińed elsewhere and not referring to a ``do``
* a label on ``if`` defined elsewhere
* a undefined label on ``else`` or ``elseif``
* a label on ``else``, ``elseif`` or ``endif`` not pointing to a matching ``if``
* a label on ``break`` or ``continue`` which does not point to a matching ``while`` or ``do``
* a label on ``endrepeat`` or ``endwhile`` no referring to a corresponding ``while`` or ``repeat``
To make these errors non-fatal warnings on stderr, set bit 0x20 in the ``[RS274NGC]FEATURE=`` mask
ini option.
Other Codes
===========
F: Set Feed Rate
----------------
'Fx' - set the feed rate to 'x'. 'x' is usually in machine units (inches or millimeters) per minute.
The application of the feed rate is as described in the `Feed Rate <#sub:feed-rate>`__ Section,
unless 'inverse time feed rate mode' or 'feed per revolution mode' are in effect, in which case the
feed rate is as described in the `G93 G94 G95 <#gcode:g93-g94-g95>`__ Section.
S: Set Spindle Speed
--------------------
'Sx' - set the speed of the spindle to 'x' revolutions per minute (RPM).
The spindle will turn at that speed when a 'M3' or 'M4' is in effect. It is OK to program an S word
whether the spindle is turning or not. If the speed override switch is enabled and not set at 100%,
the speed will be different from what is programmed. It is OK to program S0, the spindle will not
turn if that is done.
It is an error if:
* the S number is negative.
T: Select Tool
--------------
'Tx' - prepare to change to tool 'x'.
The tool is not changed until an 'M6' is programmed (see Section `M6 <#mcode:m6>`__). The T word may
appear on the same line as the 'M6' or on a previous line. It is OK if T words appear on two or more
lines with no tool change. Only the the most recent T word will take effect at the next tool change.
It is an error if:
* a negative T number is used,
* T number is used that does not appear in the tool table file (with the exception that T0 on
nonrandom toolchangers **is** accepted, as noted above).
On some machines, the carousel will move when a T word is programmed, at the same time machining is
occurring. On such machines, programming the T word several lines before a tool change will save
time. A common programming practice for such machines is to put the T word for the next tool to be
used on the line after a tool change. This maximizes the time available for the carousel to move.
Rapid moves after a 'T<n>' will not show on the AXIS preview until after a feed move. This is for
machines that travel long distances to change the tool like a lathe. This can be very confusing at
first. To turn this feature off for the current tool program a G1 without any move after the 'T<n>'.
G Code Overview
===============
Overview
--------
The LinuxCNC G Code language is based on the RS274/NGC language. The G Code language is based on
lines of code. Each line (also called a 'block') may include commands to do several different
things. Lines of code may be collected in a file to make a program.
A typical line of code consists of an optional line number at the beginning followed by one or more
'words'. A word consists of a letter followed by a number (or something that evaluates to a
number). A word may either give a command or provide an argument to a command. For example, 'G1 X3'
is a valid line of code with two words. 'G1' is a command meaning 'move in a straight line at the
programmed feed rate to the programmed end point', and 'X3' provides an argument value (the value of
X should be 3 at the end of the move). Most LinuxCNC G Code commands start with either G or M (for
General and Miscellaneous). The words for these commands are called 'G codes' and 'M codes.'
The LinuxCNC language has no indicator for the start of a program. The Interpreter, however, deals
with files. A single program may be in a single file, or a program may be spread across several
files. A file may demarcated with percents in the following way. The first non-blank line of a file
may contain nothing but a percent sign, '%', possibly surrounded by white space, and later in the
file (normally at the end of the file) there may be a similar line. Demarcating a file with percents
is optional if the file has an 'M2' or 'M30' in it, but is required if not. An error will be
signaled if a file has a percent line at the beginning but not at the end. The useful contents of a
file demarcated by percents stop after the second percent line. Anything after that is ignored.
The LinuxCNC G Code language has two commands ('M2' or 'M30'), either of which ends a program. A
program may end before the end of a file. Lines of a file that occur after the end of a program are
not to be executed. The interpreter does not even read them.
Format of a line
----------------
A permissible line of input code consists of the following, in order, with the restriction that
there is a maximum (currently 256) to the number of characters allowed on a line.
#. an optional block delete character, which is a slash '/'.
#. an optional line number.
#. any number of words, parameter settings, and comments.
#. an end of line marker (carriage return or line feed or both).
Any input not explicitly allowed is illegal and will cause the Interpreter to signal an error.
Spaces and tabs are allowed anywhere on a line of code and do not change the meaning of the line,
except inside comments. This makes some strange-looking input legal. The line 'G0X +0. 12 34Y 7' is
equivalent to 'G0 x+0.1234 Y7', for example.
Blank lines are allowed in the input. They are to be ignored.
Input is case insensitive, except in comments, i.e., any letter outside a comment may be in upper or
lower case without changing the meaning of a line.
Block Delete
~~~~~~~~~~~~
The optional block delete character the slash '/' when placed first on a line can be used by some
user interfaces to skip lines of code when needed. In Axis the key combination Alt-m-/ toggles block
delete on and off. When block delete is on any lines starting with the slash '/' are skipped.
Line Number
~~~~~~~~~~~
A line number is the letter N followed by an unsigned integer, optionally followed by a period and
another unsigned integer. For example, 'N1234' and 'N56.78' are valid line numbers. They may be
repeated or used out of order, although normal practice is to avoid such usage. Line numbers may
also be skipped, and that is normal practice. A line number is not required to be used, but must be
in the proper place if used.
Word
~~~~
A word is a letter other than N followed by a real value.
Words may begin with any of the letters shown in the following Table. The table includes N for
completeness, even though, as defined above, line numbers are not words. Several letters (I, J, K,
L, P, R) may have different meanings in different contexts. Letters which refer to axis names are
not valid on a machine which does not have the corresponding axis.
Table 1. Words and their meanings
Letter
Meaning
A
A axis of machine
B
B axis of machine
C
C axis of machine
D
Tool radius compensation number
F
Feed rate
G
General function (See table `Modal Groups <#cap:modal-groups>`__)
H
Tool length offset index
I
X offset for arcs and G87 canned cycles
J
Y offset for arcs and G87 canned cycles
K
Z offset for arcs and G87 canned cycles.
Spindle-Motion Ratio for G33 synchronized movements.
L
generic parameter word for G10, M66 and others
M
Miscellaneous function (See table `Modal Groups <#cap:modal-groups>`__)
N
Line number
P
Dwell time in canned cycles and with G4.
Key used with G10.
Q
Feed increment in G73, G83 canned cycles
R
Arc radius or canned cycle plane
S
Spindle speed
T
Tool selection
U
U axis of machine
V
V axis of machine
W
W axis of machine
X
X axis of machine
Y
Y axis of machine
Z
Z axis of machine
Number
~~~~~~
The following rules are used for (explicit) numbers. In these rules a digit is a single character
between 0 and 9.
* A number consists of (1) an optional plus or minus sign, followed by (2) zero to many digits,
followed, possibly, by (3) one decimal point, followed by (4) zero to many digits - provided that
there is at least one digit somewhere in the number.
* There are two kinds of numbers: integers and decimals. An integer does not have a decimal point in
it; a decimal does.
* Numbers may have any number of digits, subject to the limitation on line length. Only about
seventeen significant figures will be retained, however (enough for all known applications).
* A non-zero number with no sign as the first character is assumed to be positive.
Notice that initial (before the decimal point and the first non-zero digit) and trailing (after the
decimal point and the last non-zero digit) zeros are allowed but not required. A number written with
initial or trailing zeros will have the same value when it is read as if the extra zeros were not
there.
Numbers used for specific purposes in RS274/NGC are often restricted to some finite set of values or
some to some range of values. In many uses, decimal numbers must be close to integers; this includes
the values of indices (for parameters and carousel slot numbers, for example), M codes, and G codes
multiplied by ten. A decimal number which is intended to represent an integer is considered close
enough if it is within 0.0001 of an integer value.
Parameters
----------
The RS274/NGC language supports 'parameters' - what in other programming languages would be called
'variables'. There are several types of parameter of different purpose and appearance, each
described in the following sections. The only value type supported by parameters is floating-point;
there are no string, boolean or integer types in G-code like in other programming
languages. However, logic expressions can be formulated with `boolean operators
<#gcode:binary-operators>`__ ( 'AND', 'OR', 'XOR', and the comparison operators
'EQ','NE','GT','GE','LT','LE'), and the 'MOD', 'ROUND', 'FUP' and 'FIX' `operators
<#gcode:functions>`__ support integer arithmetic.
Parameters differ in syntax, scope, behavior when not yet initialized, mode, persistence and
intended use.
| Syntax
| There are three kinds of syntactic appearance:
* 'numbered' - #4711
* 'named local' - #<localvalue>
* 'named global' - #<_globalvalue>
| Scope
| The scope of a parameter is either global, or local within a
subroutine. Subroutine parameters and local named variables have local
scope. Global named parameters and numbered parameters starting from
number 31 are global in scope. RS274/NGC uses 'lexical scoping' - in a
subroutine only the local variables defined therein, and any global
variables are visible. The local variables of a calling procedure are
not visible in a called procedure.
Behavior of uninitialized parameters
* Uninitialized global parameters, and unused subroutine parameters
return the value zero when used in an expression.
* Uninitialized named parameters signal an error when used in an
expression.
| Mode
| Most parameters are read/write and may be assigned to within an
assignment statement. However, for many predefined parameters this
does not make sense, so they are are read-only - they may appear in
expressions, but not on the left-hand side of an assignment statement.
| Persistence
| When LinuxCNC is shut down, volatile parameters lose their values. All
parameters except numbered parameters in the current persistent range
^([`1 <#_footnote_1>`__]) are volatile. Persistent parameters are
saved in the .var file and restored to their previous values when
LinuxCNC is started again. Volatile numbered parameters are reset to
zero.
| Intended Use
| \* user parameters
| numbered parameters in the range 31..5000, and named global and local
parameters except predefined parameters. These are available for
general-purpose storage of floating-point values, like intermediate
results, flags etc, throughout program execution. They are read/write
(can be assigned a value).
* `subroutine parameters <#sub:subroutine-parameters>`__ - these are used to hold the actual
parameters passed to a subroutine.
* `numbered parameters <#sub:numbered-parameters>`__ - most of these are used to access offsets of
coordinate systems.
* `system parameters <#sub:system-parameters>`__ - used to determine the current running
version. They are read-only.
Numbered Parameters
~~~~~~~~~~~~~~~~~~~
A numbered parameter is the pound character '#' followed by an integer between 1 and (currently)
5602 ^([`2 <#_footnote_2>`__]). The parameter is referred to by this integer, and its value is
whatever number is stored in the parameter.
A value is stored in a parameter with the = operator; for example:
::
#3 = 15 (set parameter 3 to 15)
A parameter setting does not take effect until after all parameter values on the same line have been
found. For example, if parameter 3 has been previously set to 15 and the line '#3=6 G1 X#3' is
interpreted, a straight move to a point where X equals 15 will occur and the value of parameter 3
will be 6.
The '#' character takes precedence over other operations, so that, for example, '\#1+2' means the
number found by adding 2 to the value of parameter 1, not the value found in parameter 3. Of course,
'\#[1+2]' does mean the value found in parameter 3. The '#' character may be repeated; for example
'##2' means the value of the parameter whose index is the (integer) value of parameter 2.
* '31-5000' - G code user parameters. These parameters are global in the G code file, and available
for general use. Volatile.
* '5061-5069' - Coordinates of a `G38 <#gcode:g38>`__ probe result (X, Y, Z, A, B, C, U, V &
W). Coordinates are in the coordinate system in which the G38 took place. Volatile.
* '5070' - `G38 <#gcode:g38>`__ probe result: 1 if success, 0 if probe failed to close. Used with
G38.3 and G38.5. Volatile.
* '5161-5169' - "G28" Home for X, Y, Z, A, B, C, U, V & W. Persistent.
* '5181-5189' - "G30" Home for X, Y, Z, A, B, C, U, V & W. Persistent.
* '5210' - 1 if "G52" or "G92" offset is currently applied, 0 otherwise. Volatile by default;
persistent if 'DISABLE_G92_PERSISTENCE = 1' in the '[RS274NGC]' section of the '.ini' file.
* '5211-5219' - Shared "G52" and "G92" offset for X, Y, Z, A, B, C, U, V & W. Volatile by default;
persistent if 'DISABLE_G92_PERSISTENCE = 1' in the '[RS274NGC]' section of the '.ini' file.
* '5220' - Coordinate System number 1 - 9 for G54 - G59.3. Persistent.
* '5221-5230' - Coordinate System 1, G54 for X, Y, Z, A, B, C, U, V, W & R. R denotes the XY
rotation angle around the Z axis. Persistent.
* '5241-5250' - Coordinate System 2, G55 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5261-5270' - Coordinate System 3, G56 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5281-5290' - Coordinate System 4, G57 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5301-5310' - Coordinate System 5, G58 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5321-5330' - Coordinate System 6, G59 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5341-5350' - Coordinate System 7, G59.1 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5361-5370' - Coordinate System 8, G59.2 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5381-5390' - Coordinate System 9, G59.3 for X, Y, Z, A, B, C, U, V, W & R. Persistent.
* '5399' - Result of M66 - Check or wait for input. Volatile.
* '5400' - Tool Number. Volatile.
* '5401-5409' - Tool Offsets for X, Y, Z, A, B, C, U, V & W. Volatile.
* '5410' - Tool Diameter. Volatile.
* '5411' - Tool Front Angle. Volatile.
* '5412' - Tool Back Angle. Volatile.
* '5413' - Tool Orientation. Volatile.
* '5420-5428' - Current relative position in the active coordinate system including all offsets and
in the current program units for X, Y, Z, A, B, C, U, V & W, volatile.
* '5599' - Flag for controlling the output of (DEBUG,) statements. 1=output, 0=no output;
default=1. Volatile.
* '5600' - Toolchanger fault indicator. Used with the iocontrol-v2 component. 1: toolchanger
faulted, 0: normal. Volatile.
* '5601' - Toolchanger fault code. Used with the iocontrol-v2 component. Reflects the value of the
'toolchanger-reason' HAL pin if a fault occurred. Volatile.
Numbered Parameters Persistence
The values of parameters in the persistent range are retained over time, even if the machining
center is powered down. LinuxCNC uses a parameter file to ensure persistence. It is managed by the
Interpreter. The Interpreter reads the file when it starts up, and writes the file when it exits.
The format of a parameter file is shown in Table `Parameter File Format
<#gcode:format-parameter-file>`__.
The Interpreter expects the file to have two columns. It skips any lines which do not contain
exactly two numeric values. The first column is expected to contain an integer value (the
parameter’s number). The second column contains a floating point number (this parameter’s last
value). The value is represented as a double-precision floating point number inside the Interpreter,
but a decimal point is not required in the file.
Parameters in the user-defined range (31-5000) may be added to this file. Such parameters will be
read by the Interpreter and written to the file as it exits.
Missing Parameters in the persistent range will be initialized to zero and written with their
current values on the next save operation.
The parameter numbers must be arranged in ascending order. An 'Parameter file out of order' error
will be signaled if they are not in ascending order.
The original file is saved as a backup file when the new file is written.
================ ===============
Parameter Number Parameter Value
================ ===============
5161 0.0
5162 0.0
================ ===============
Subroutine Parameters
~~~~~~~~~~~~~~~~~~~~~
* '1-30' Subroutine local parameters of call arguments. These parameters are local to the
subroutine. Volatile. See also the chapter on `O-Codes <#cha:o-codes>`__.
Named Parameters
~~~~~~~~~~~~~~~~
Named parameters work like numbered parameters but are easier to read. All parameter names are
converted to lower case and have spaces and tabs removed, so '<param>' and '<P a R am >' refer to
the same parameter. Named parameters must be enclosed with '< >' marks.
'#<named parameter>' is a local named parameter. By default, a named parameter is local to the scope
in which it is assigned. You can’t access a local parameter outside of its subroutine. This means
that two subroutines can use the same parameter names without fear of one subroutine overwriting the
values in another.
'#<_global named parameter>' is a global named parameter. They are accessible from within called
subroutines and may set values within subroutines that are accessible to the caller. As far as scope
is concerned, they act just like regular numeric parameters. They are not stored in files.
Examples:
Declaration of named global variable
::
#<_endmill_dia> = 0.049
Reference to previously declared global variable
::
#<_endmill_rad> = [#<_endmill_dia>/2.0]
Mixed literal and named parameters
::
o100 call [0.0] [0.0] [#<_inside_cutout>-#<_endmill_dia>] [#<_Zcut>] [#<_feedrate>]
Named parameters spring into existence when they are assigned a value for the first time. Local
named parameters vanish when their scope is left: when a subroutine returns, all its local
parameters are deleted and cannot be referred to anymore.
It is an error to use a non-existent named parameter within an expression, or at the right-hand side
of an assignment. Printing the value of a non-existent named parameter with a DEBUG statement - like
'(DEBUG, <no_such_parameter>)' will display the string '#'.
Global parameters, as well as local parameters assigned to at the global level, retain their value
once assigned even when the program ends, and have these values when the program is run again.
The `'EXISTS' function <#gcode:functions>`__ tests whether a given named parameter exists.
Predefined Named Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following global read only named parameters are available to access internal state of the
interpreter and machine state. They can be used in arbitrary expressions, for instance to control
flow of the program with if-then-else statements. Note that new `predefined named parameters
<#remap:adding-predefined-named-parameters>`__ can be added easily without changes to the source
code.
* '#<_vmajor>' - Major package version. If current version was 2.5.2 would return 2.5. d
* '#<_vminor>' - Minor package version. If current version was 2.6.2 it would return 0.2. d
* '#<_line>' - Sequence number. If running a G-Code file, this returns the current line number.
* '#<_motion_mode>' - Return the interpreter’s current motion mode:
=========== ============
Motion mode return value
=========== ============
G1 10
G2 20
G3 30
G33 330
G38.2 382
G38.3 383
G38.4 384
G38.5 385
G5.2 52
G73 730
G76 760
G80 800
G81 810
G82 820
G83 830
G84 840
G85 850
G86 860
G87 870
G88 880
G89 890
=========== ============
* '#<_plane>' - returns the value designating the current plane:
===== ============
Plane return value
G17 170
G18 180
G19 190
G17.1 171
G18.1 181
G19.1 191
===== ============
* '#<_ccomp>' - Status of cutter compensation. Return values:
===== ============
Mode return value
G40 400
G41 410
G41.1 411
G41 410
G42 420
G42.1 421
===== ============
* '#<_metric>' - Return 1 if G21 is on, else 0.
* '#<_imperial>' - Return 1 if G20 is on, else 0.
* '#<_absolute>' - Return 1 if G90 is on, else 0.
* '#<_incremental>' - Return 1 if G91 is on, else 0.
* '#<_inverse_time>' - Return 1 if inverse feed mode (G93) is on, else 0.
* '#<_units_per_minute>' - Return 1 if Units/minute feed mode (G94) is on, else 0.
* '#<_units_per_rev>' - Return 1 if Units/revolution mode (G95) is on, else 0.
* '#<_coord_system>' - Return a float of the current coordinate system name(G54..G59.3). For example
if your in G55 coordinate system the return value is 550.000000 and if your in G59.1 the return
value is 591.000000.
===== ============
Mode return value
===== ============
G54 554
G55 550
G56 560
G57 570
G58 580
G59 590
G59.1 591
G59.2 592
G59.3 593
===== ============
* '#<_tool_offset>' - Return 1 if tool offset (G43) is on, else 0.
* '#<_retract_r_plane>' - Return 1 if G98 is set, else 0.
* '#<_retract_old_z>' - Return 1 if G99 is on, else 0.
System Parameters
~~~~~~~~~~~~~~~~~
* '#<_spindle_rpm_mode>' - Return 1 if spindle rpm mode (G97) is on, else 0.
* '#<_spindle_css_mode>' - Return 1 if constant surface speed mode (G96) is on, else 0.
* '#<_ijk_absolute_mode>' - Return 1 if Absolute Arc distance mode (G90.1) is on, else 0.
* '#<_lathe_diameter_mode>' - Return 1 if this is a lathe configuration and diameter (G7) mode is
on, else 0.
* '#<_lathe_radius_mode>' - Return 1 if this is a lathe configuration and radius (G8) mode is on,
else 0.
* '#<_spindle_on>' - Return 1 if spindle currently running (M3 or M4) else 0.
* '#<_spindle_cw>' - Return 1 if spindle direction is clockwise (M3) else 0.
* '#<_mist>' - Return 1 if mist (M7) is on.
* '#<_flood>' - Return 1 if flood (M8) is on.
* '#<_speed_override>' - Return 1 if feed override (M48 or M50 P1) is on, else 0.
* '#<_feed_override>' - Return 1 if feed override (M48 or M51 P1) is on, else 0.
* '#<_adaptive_feed>' - Return 1 if adaptive feed (M52 or M52 P1) is on, else 0.
* '#<_feed_hold>' - Return 1 if feed hold switch is enabled (M53 P1), else 0.
* '#<_feed>' - Return the current value of F, not the actual feed rate.
* '#<_rpm>' - Return the current value of S, not the actual spindle speed.
* '#<_x>' - Return current relative X coordinate including all offsets. Same as #5420.
* '#<_y>' - Return current relative Y coordinate including all offsets. Same as #5421.
* '#<_z>' - Return current relative Z coordinate including all offsets. Same as #5422.
* '#<_a>' - Return current relative A coordinate including all offsets. Same as #5423.
* '#<_b>' - Return current relative B coordinate including all offsets. Same as #5424.
* '#<_c>' - Return current relative C coordinate including all offsets. Same as #5425.
* '#<_u>' - Return current relative U coordinate including all offsets. Same as #5426.
* '#<_v>' - Return current relative V coordinate including all offsets. Same as #5427.
* '#<_w>' - Return current relative W coordinate including all offsets. Same as #5428.
* '#<_current_tool>' - Return number of the current tool in spindle. Same as #5400.
* '#<_current_pocket>' - Return pocket number of the current tool.
* '#<_selected_tool>' - Return number of the selected tool post a T code. Default -1.
* '#<_selected_pocket>' - Return number of the selected pocket post a T code. Default -1 (no pocket
selected).
* '#<_value>' - Return value from the last O-word 'return' or 'endsub'. Default value 0 if no
expression after 'return' or 'endsub'. Initialized to 0 on program start.
* '#<_value_returned>' - 1.0 if the last O-word 'return' or 'endsub' returned a value, 0
otherwise. Cleared by the next O-word call.
* '#<_task>' - 1.0 if the executing interpreter instance is part of milltask, 0.0
otherwise. Sometimes it is necessary to treat this case specially to retain proper preview, for
instance when testing the success of a probe (G38.n) by inspecting #5070, which will always fail
in the preview interpreter (e.g. Axis).
* '#<_call_level>' - current nesting level of O-word procedures. For debugging.
* '#<_remap_level>' - current level of the remap stack. Each remap in a block adds one to the remap
level. For debugging.
Expressions
-----------
An expression is a set of characters starting with a left bracket '[' and ending with a balancing
right bracket ']' . In between the brackets are numbers, parameter values, mathematical operations,
and other expressions. An expression is evaluated to produce a number. The expressions on a line are
evaluated when the line is read, before anything on the line is executed. An example of an
expression is '[1 + acos[0] - [#3 \*\* [4.0/2]]]'.
Binary Operators
----------------
Binary operators only appear inside expressions. There are four basic mathematical operations:
addition ('+'), subtraction ('-'), multiplication ('*'), and division ('/'). There are three logical
operations: non-exclusive or ('OR'), exclusive or ('XOR'), and logical and ('AND'). The eighth
operation is the modulus operation ('MOD'). The ninth operation is the 'power' operation ('**') of
raising the number on the left of the operation to the power on the right. The relational operators
are equality ('EQ'), inequality ('NE'), strictly greater than ('GT'), greater than or equal to
('GE'), strictly less than ('LT'), and less than or equal to ('LE').
The binary operations are divided into several groups according to their precedence. If operations
in different precedence groups are strung together (for example in the expression '[2.0 / 3 \* 1.5 -
5.5 / 11.0]'), operations in a higher group are to be performed before operations in a lower
group. If an expression contains more than one operation from the same group (such as the first '/'
and '*' in the example), the operation on the left is performed first. Thus, the example is
equivalent to: '[ [ [2.0 / 3] \* 1.5] - [5.5 / 11.0] ]' , which is equivalent to to '[1.0 - 0.5]' ,
which is '0.5'.
The logical operations and modulus are to be performed on any real numbers, not just on
integers. The number zero is equivalent to logical false, and any non-zero number is equivalent to
logical true.
================= ==========
Operators Precedence
================= ==========
\*\* 'highest'
\* / MOD
+ *
EQ NE GT GE LT LE
AND OR XOR 'lowest'
================= ==========
Equality and floating-point values
----------------------------------
The RS274/NGC language only supports floating-point values of finite precision. Therefore, testing
for equality or inequality of two floating-point values is inherently problematic. The interpreter
solves this problem by considering values equal if their absolute difference is less than 0.0001
(this value is defined as 'TOLERANCE_EQUAL' in src/emc/rs274ngc/interp_internal.hh).
Functions
---------
The available functions are shown in following table. Arguments to unary operations which take angle
measures ('COS', 'SIN', and 'TAN' ) are in degrees. Values returned by unary operations which return
angle measures ('ACOS', 'ASIN', and 'ATAN') are also in degrees.
=============== =============================
Function Name Function result
=============== =============================
ATAN[arg]/[arg] Four quadrant inverse tangent
ABS[arg] Absolute value
ACOS[arg] Inverse cosine
ASIN[arg] Inverse sine
COS[arg] Cosine
EXP[arg] e raised to the given power
FIX[arg] Round down to integer
FUP[arg] Round up to integer
ROUND[arg] Round to nearest integer
LN[arg] Base-e logarithm
SIN[arg] Sine
SQRT[arg] Square Root
TAN[arg] Tangent
EXISTS[arg] Check named Parameter
=============== =============================
The 'FIX' function rounds towards the left (less positive or more negative) on a number line, so
that 'FIX[2.8] =2' and 'FIX[-2.8] = -3'.
The 'FUP' operation rounds towards the right (more positive or less negative) on a number line;
'FUP[2.8] = 3' and 'FUP[-2.8] = -2'.
The 'EXISTS' function checks for the existence of a single named parameter. It takes only one named
parameter and returns 1 if it exists and 0 if it does not exist. It is an error if you use a
numbered parameter or an expression. Here is an example for the usage of the EXISTS function:
::
o<test> sub
o10 if [EXISTS[#<_global>]]
(debug, _global exists and has the value #<_global>)
o10 else
(debug, _global does not exist)
o10 endif
o<test> endsub
o<test> call
#<_global> = 4711
o<test> call
m2
Repeated Items
--------------
A line may have any number of G words, but two G words from the same modal group may not appear on
the same line See the `Modal Groups <#gcode:modal-groups>`__ Section for more information.
A line may have zero to four M words. Two M words from the same modal group may not appear on the
same line.
For all other legal letters, a line may have only one word beginning with that letter.
If a parameter setting of the same parameter is repeated on a line, '#3=15 #3=6', for example, only
the last setting will take effect. It is silly, but not illegal, to set the same parameter twice on
the same line.
If more than one comment appears on a line, only the last one will be used; each of the other
comments will be read and its format will be checked, but it will be ignored thereafter. It is
expected that putting more than one comment on a line will be very rare.
Item order
----------
The three types of item whose order may vary on a line (as given at the beginning of this section)
are word, parameter setting, and comment. Imagine that these three types of item are divided into
three groups by type.
The first group (the words) may be reordered in any way without changing the meaning of the line.
If the second group (the parameter settings) is reordered, there will be no change in the meaning of
the line unless the same parameter is set more than once. In this case, only the last setting of the
parameter will take effect. For example, after the line '#3=15 #3=6' has been interpreted, the value
of parameter 3 will be 6. If the order is reversed to '#3=6 #3=15' and the line is interpreted, the
value of parameter 3 will be 15.
If the third group (the comments) contains more than one comment and is reordered, only the last
comment will be used.
If each group is kept in order or reordered without changing the meaning of the line, then the three
groups may be interleaved in any way without changing the meaning of the line. For example, the line
'g40 g1 #3=15 (foo) #4=-7.0' has five items and means exactly the same thing in any of the 120
possible orders (such as '#4=-7.0 g1 #3=15 g40 (foo)') for the five items.
Commands and Machine Modes
--------------------------
Many commands cause the controller to change from one mode to another, and the mode stays active
until some other command changes it implicitly or explicitly. Such commands are called 'modal'. For
example, if coolant is turned on, it stays on until it is explicitly turned off. The G codes for
motion are also modal. If a G1 (straight move) command is given on one line, for example, it will be
executed again on the next line if one or more axis words is available on the line, unless an
explicit command is given on that next line using the axis words or canceling motion.
'Non-modal' codes have effect only on the lines on which they occur. For example, G4 (dwell) is
non-modal.
Polar Coordinates
-----------------
Polar Coordinates can be used to specify the XY coordinate of a move. The @n is the distance and ^n
is the angle. The advantage of this is for things like bolt hole circles which can be done very
simply by moving to a point in the center of the circle, setting the offset and then moving out to
the first hole then run the drill cycle. Polar Coordinates always are from the current XY zero
position. To shift the Polar Coordinates from machine zero use an offset or select a coordinate
system.
In Absolute Mode the distance and angle is from the XY zero position and the angle starts with 0 on
the X Positive axis and increases in a CCW direction about the Z axis. The code G1 @1^90 is the same
as G1 Y1.
In Relative Mode the distance and angle is also from the XY zero position but it is cumulative. This
can be confusing at first how this works in incremental mode.
For example if you have the following program you might expect it to be a square pattern.
::
F100 G1 @.5 ^90
G91 @.5 ^90
@.5 ^90
@.5 ^90
@.5 ^90
G90 G0 X0 Y0 M2
You can see from the following figure that the output is not what you might expect. Because we added
0.5 to the distance each time the distance from the XY zero position increased with each line.
|Polar Spiral|
Figure 1. Polar Spiral
The following code will produce our square pattern.
::
F100 G1 @.5 ^90
G91 ^90
^90
^90
^90
G90 G0 X0 Y0 M2
As you can see by only adding to the angle by 90 degrees each time the end point distance is the
same for each line.
|Polar Square|
Figure 2. Polar Square
It is an error if:
* An incremental move is started at the origin
* A mix of Polar and and X or Y words are used
Modal Groups
------------
Modal commands are arranged in sets called 'modal groups', and only one member of a modal group may
be in force at any given time. In general, a modal group contains commands for which it is logically
impossible for two members to be in effect at the same time - like measure in inches vs. measure in
millimeters. A machining center may be in many modes at the same time, with one mode from each modal
group being in effect. The modal groups are shown in the following Table.
Table 5. G-Code Modal Groups
Modal Group Meaning
Member Words
Non-modal codes (Group 0)
G4, G10 G28, G30, G52, G53, G92, G92.1, G92.2, G92.3,
Motion (Group 1)
G0, G1, G2, G3, G33, G38.n, G73, G76, G80, G81
G82, G83, G84, G85, G86, G87, G88, G89
Plane selection (Group 2)
G17, G18, G19, G17.1, G18.1, G19.1
Distance Mode (Group 3)
G90, G91
Arc IJK Distance Mode (Group 4)
G90.1, G91.1
Feed Rate Mode (Group 5)
G93, G94, G95
Units (Group 6)
G20, G21
Cutter Diameter Compensation (Group 7)
G40, G41, G42, G41.1, G42.1
Tool Length Offset (Group 8)
G43, G43.1, G49
Canned Cycles Return Mode (Group 10)
G98, G99
Coordinate System (Group 12)
G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3
Control Mode (Group 13)
G61, G61.1, G64
Spindle Speed Mode (Group 14)
G96, G97
Lathe Diameter Mode (Group 15)
G7, G8
=========================== ==========================
Modal Group Meaning Member Words
=========================== ==========================
Stopping (Group 4) M0, M1, M2, M30, M60
Spindle (Group 7) M3, M4, M5
Coolant (Group 8) (M7 M8 can both be on), M9
Override Switches (Group 9) M48, M49
User Defined (Group 10) M100-M199
=========================== ==========================
For several modal groups, when a machining center is ready to accept commands, one member of the
group must be in effect. There are default settings for these modal groups. When the machining
center is turned on or otherwise re-initialized, the default values are automatically in effect.
Group 1, the first group on the table, is a group of G codes for motion. One of these is always in
effect. That one is called the current motion mode.
It is an error to put a G-code from group 1 and a G-code from group 0 on the same line if both of
them use axis words. If an axis word-using G-code from group 1 is implicitly in effect on a line (by
having been activated on an earlier line), and a group 0 G-code that uses axis words appears on the
line, the activity of the group 1 G-code is suspended for that line. The axis word-using G-codes
from group 0 are G10, G28, G30, G52 and G92.
It is an error to include any unrelated words on a line with 'O-' flow control.
Comments
--------
Comments can be added to lines of G code to help clear up the intention of the programmer. Comments
can be embedded in a line using parentheses () or for the remainder of a line using a
semi-colon. The semi-colon is not treated as the start of a comment when enclosed in parentheses.
Comments may appear between words, but not between words and their corresponding parameter. So,
'S100(set speed)F200(feed)' is OK while 'S(speed)100F(feed)' is not.
::
G0 (Rapid to start) X1 Y1
G0 X1 Y1 (Rapid to start; but don't forget the coolant)
M2 ; End of program.
There are several 'active' comments which look like comments but cause some action, like
'(debug,..)' or '(print,..)'. If there are several comments on a line, only the last comment will be
interpreted according to these rules. Hence, a normal comment following an active comment will in
effect disable the active comment. For example, '(foo) (debug,#1)' will print the value of parameter
'#1', however '(debug,#1)(foo)' will not.
A comment introduced by a semicolon is by definition the last comment on that line, and will always
be interpreted for active comment syntax.
Messages
--------
* '(MSG,)' - displays message if 'MSG' appears after the left parenthesis and before any other
printing characters. Variants of 'MSG' which include white space and lower case characters are
allowed. The rest of the characters before the right parenthesis are considered to be a
message. Messages should be displayed on the message display device of the user interface if
provided.
Message Example
::
(MSG, This is a message)
Probe Logging
-------------
* '(PROBEOPEN filename.txt)' - will open filename.txt and store the 9-number coordinate consisting
of XYZABCUVW of each successful straight probe in it.
* '(PROBECLOSE)' - will close the open probelog file. For more information on probing see the `G38
<#gcode:g38>`__ Section.
Logging
-------
* '(LOGOPEN,filename.txt)' - opens the named log file. If the file already exists, it is truncated.
* '(LOGAPPEND,filename)' - opens the named log file. If the file already exists, the data is
appended.
* '(LOGCLOSE)' - closes an open log file.
* '(LOG,)' - everything past the ',' is written to the log file if it is open. Supports expansion of
parameters as described below.
Examples of logging are in 'nc_files/examples/smartprobe.ngc' and in
'nc_files/ngcgui_lib/rectange_probe.ngc' sample G code files.
Debug Messages
--------------
* '(DEBUG,)' - displays a message like '(MSG,)' with the addition of special handling for comment
parameters as described below.
Print Messages
--------------
* '(PRINT,)' - messages are output to 'stderr' with special handling for comment parameters as
described below.
Comment Parameters
------------------
In the DEBUG, PRINT and LOG comments, the values of parameters in the message are expanded.
For example: to print a named global variable to stderr (the default console window).
Parameters Example
::
(print,endmill dia = #<_endmill_dia>)
(print,value of variable 123 is: #123)
Inside the above types of comments, sequences like '#123' are replaced by the value of the
parameter 123. Sequences like '\#<named parameter>' are replaced by the value of the named
parameter. Named parameters will have white space removed from them. So, '#<named parameter>' will
be converted to '#<namedparameter>'.
File Requirements
-----------------
A G code file must contain one or more lines of G code and be terminated with a `Program End
<#mcode:m2-m30>`__. Any G code past the program end is not evaluated.
If a program end code is not used a pair of percent signs '%' with the first percent sign on the
first line of the file followed by one or more lines of G code and a second percent sign. Any code
past the second percent sign is not evaluated.
File Size
---------
The interpreter and task are carefully written so that the only limit on part program size is disk
capacity. The TkLinuxCNC and Axis interface both load the program text to display it to the user,
though, so RAM becomes a limiting factor. In Axis, because the preview plot is drawn by default, the
redraw time also becomes a practical limit on program size. The preview can be turned off in Axis
to speed up loading large part programs. In Axis sections of the preview can be turned off using
`preview control <#axis:preview-control>`__ comments.
G Code Order of Execution
-------------------------
The order of execution of items on a line is defined not by the position
of each item on the line, but by the following list:
* O-word commands (optionally followed by a comment but no other words allowed on the same line)
* Comment (including message)
* Set feed rate mode (G93, G94).
* Set feed rate (F).
* Set spindle speed (S).
* Select tool (T).
* HAL pin I/O (M62-M68).
* Change tool (M6) and Set Tool Number (M61).
* Spindle on or off (M3, M4, M5).
* Save State (M70, M73), Restore State (M72), Invalidate State (M71).
* Coolant on or off (M7, M8, M9).
* Enable or disable overrides (M48, M49,M50,M51,M52,M53).
* User-defined Commands (M100-M199).
* Dwell (G4).
* Set active plane (G17, G18, G19).
* Set length units (G20, G21).
* Cutter radius compensation on or off (G40, G41, G42)
* Cutter length compensation on or off (G43, G49)
* Coordinate system selection (G54, G55, G56, G57, G58, G59, G59.1, G59.2, G59.3).
* Set path control mode (G61, G61.1, G64)
* Set distance mode (G90, G91).
* Set retract mode (G98, G99).
* Go to reference location (G28, G30) or change coordinate system data (G10) or set axis offsets
(G52, G92, G92.1, G92.2, G94).
* Perform motion (G0 to G3, G33, G38.n, G73, G76, G80 to G89), as modified (possibly) by G53.
* Stop (M0, M1, M2, M30, M60).
G Code Best Practices
---------------------
Use an appropriate decimal precision
Use at least 3 digits after the decimal when milling in millimeters, and at least 4 digits after the
decimal when milling in inches.
Use consistent white space
G-code is most legible when at least one space appears before words. While it is permitted to
insert white space in the middle of numbers, there is no reason to do so.
Use Center-format arcs
Center-format arcs (which use 'I- J- K-' instead of 'R-' ) behave more consistently than R-format
arcs, particularly for included angles near 180 or 360 degrees.
Use a Preamble set modal groups
When correct execution of your program depends on modal settings, be sure to set them at the
beginning of the part program. Modes can carry over from previous programs and from the MDI
commands.
Example Preamble for a Mill
.. code:: highlight
G17 G20 G40 G49 G54 G80 G90 G94
G17 use XY plane, G20 inch mode, G40 cancel diameter compensation, G49 cancel length offset, G54 use
coordinate system 1, G80 cancel canned cycles, G90 absolute distance mode, G94 feed/minute mode.
Perhaps the most critical modal setting is the distance units—​If you do not include G20 or G21, then
different machines will mill the program at different scales. Other settings, such as the return
mode in canned cycles may also be important.
Don’t put too many things on one line
Ignore everything in Section `Order of Execution <#gcode:order-of-execution>`__, and instead write
no line of code that is the slightest bit ambiguous.
Don’t set & use a parameter on the same line
Don’t use and set a parameter on the same line, even though the semantics are well defined. Updating
a variable to a new value, such as '#1=[#1+#2]' is OK.
Don’t use line numbers
Line numbers offer no benefits. When line numbers are reported in error messages, the numbers refer
to the line number in the file, not the N-word value.
Linear and Rotary Axis
----------------------
Because the meaning of an F-word in feed-per-minute mode varies depending on which axes are
commanded to move, and because the amount of material removed does not depend only on the feed rate,
it may be easier to use G93 inverse time feed mode to achieve the desired material removal rate.
Common Error Messages
---------------------
* 'G code out of range' - A G code greater than G99 was used, the scope of G codes in LinuxCNC is
0 - 99. Not every number between 0 and 99 is a valid G code.
* 'Unknown g code used' - A G code was used that is not part of the LinuxCNC G code language.
* 'i,j,k word with no Gx to use it' - i, j and k words must be used on the same line as the G code.
* 'Cannot use axis values without a g code that uses them' - Axis values can not be used on a line
without either a modal G code in effect or a G code on the same line.
* 'File ended with no percent sign or program end' - Every G code file must end in a M2 or M30 or be
wrapped with the percent sign %.
--------------
`1 <#_footnoteref_1>`__. The range of persistent parameters may change as development
progresses. This range is currently 5161- 5390. It is defined in the '_required_parameters array' in
file the src/emc/rs274ngc/interp_array.cc .
`2 <#_footnoteref_2>`__. The RS274/NGC interpreter maintains an array of numbered parameters. Its
size is defined by the symbol 'RS274NGC_MAX_PARAMETERS' in the file
src/emc/rs274ngc/interp_internal.hh). This number of numerical parameters may also increase as
development adds support for new parameters.
.. |Polar Spiral| image:: images/polar01.png
.. |Polar Square| image:: images/polar02.png
RS274/NGC Differences
=====================
Changes from RS274/NGC
----------------------
Differences that change the meaning of RS274/NGC programs
Location after a tool change
In LinuxCNC, the machine does not return to its original position after a tool change. This change
was made because the new tool might be longer than the old tool, and the move to the original
machine position could therefore leave the tool tip too low.
Offset parameters are ini file units
In LinuxCNC, the values stored in parameters for the G28 and G30 home locations, the P1…​P9
coordinate systems, and the G92 offset are in "ini file units". This change was made because
otherwise the meaning of a location changed depending on whether G20 or G21 was active when G28,
G30, G10 L2, or G92.3 is programmed.
Tool table lengths/diameters are in ini file units
In LinuxCNC, the tool lengths (offsets) and diameters in the tool table are specified in ini file
units only. This change was made because otherwise the length of a tool and its diameter would
change based on whether G20 or G21 was active when initiating G43, G41, G42 modes. This made it
impossible to run G code in the machine’s non-native units, even when the G code was simple and
well-formed (starting with G20 or G21, and didn’t change units throughout the program), without
changing the tool table.
G84, G87 not implemented
G84 and G87 are not currently implemented, but may be added to a future release of LinuxCNC.
G28, G30 with axis words
When G28 or G30 is programmed with only some axis words present, LinuxCNC only moves the named
axes. This is common on other machine controls. To move some axes to an intermediate point and
then move all axes to the predefined point, write two lines of G code:
G0 X- Y- (axes to move to intermediate point) G28 (move all axes to
predefined point)
Additions to RS274/NGC
----------------------
Differences that do not change the meaning of RS274/NGC programs
G33, G76 threading codes
These codes are not defined in RS274/NGC.
G38.2
The probe tip is not retracted after a G38.2 movement. This retraction move may be added in a
future release of LinuxCNC.
G38.3…​G38.5
These codes are not defined in RS274/NGC
O-codes
These codes are not defined in RS274/NGC
M50…​M53 overrides
These codes are not defined in RS274/NGC
M61..M66
These codes are not defined in RS274/NGC
G43, G43.1
'Negative Tool Lengths'
The RS274/NGC spec says "it is expected that" all tool lengths will be positive. However, G43 works
for negative tool lengths.
'Lathe tools'
G43 tool length compensation can offset the tool in both the X and Z dimensions. This feature is
primarily useful on lathes.
'Dynamic tool lengths'
LinuxCNC allows specification of a computed tool length through G43.1 I K.
G41.1, G42.1
LinuxCNC allows specification of a tool diameter and, if in lathe mode, orientation in the G
code. The format is G41.1/G42.1 D L, where D is diameter and L (if specified) is the lathe tool
orientation.
G43 without H word
In ngc, this is not allowed. In LinuxCNC, it sets length offsets for the currently loaded tool. If
no tool is currently loaded, it is an error. This change was made so the user doesn’t have to
specify the tool number in two places for each tool change, and because it’s consistent with the
way G41/G42 work when the D word is not specified.
U, V, and W axes
LinuxCNC allows machines with up to 9 axes by defining an additional set of 3 linear axes known as
U, V and W
Tool Compensation
=================
Tool Length Offsets
-------------------
Touch Off
~~~~~~~~~
Using the Touch Off Screen in the AXIS interface you can update the tool table automatically.
Typical steps for updating the tool table:
- After homing load a tool with 'Tn M6' where 'n' is the tool number.
- Move tool to an established point using a gauge or take a test cut and measure.
- Click the "Touch Off" button in the Manual Control tab (or hit the End button on your keyboard).
- Select 'Tool Table' in the Coordinate System drop down box.
- Enter the gauge or measured dimension and select OK.
The Tool Table will be changed with the correct Z length to make the DRO display the correct Z
position and a G43 command will be issued so the new tool Z length will be in effect. Tool table
touch off is only available when a tool is loaded with 'Tn M6'.
Figure 1. Touch Off Tool Table
Using G10 L1/L10/L11
~~~~~~~~~~~~~~~~~~~~
The G10 L1/L10/L11 commands can be used to set tool table offsets:
- 'G10 L1 Pn' - Set offset(s) to a value. Current position irrelevant. (see `G10 L1
<#gcode:g10-l1>`__ for details)
- 'G10 L10 Pn' - Set offset(s) so current position w/ fixture 1-8 becomes a value. (see `G10 L10
<#gcode:g10-l10>`__ for details)
- 'G10 L11 Pn' - Set offset(s) so current position w/ fixture 9 becomes a value. (see `G10 L11
<#gcode:g10-l11>`__ for details)
Tool Table
----------
The 'Tool Table' is a text file that contains information about each tool. The file is located in
the same directory as your configuration and is called 'tool.tbl'. The tools might be in a tool
changer or just changed manually. The file can be edited with a text editor or be updated using G10
L1. See the `Lathe Tool Table <#sec:lathe-tool-table>`__ Section for an example of the lathe tool
table format. The maximum number of entries in the tool table is 56. The maximum tool and pocket
number is 99999.
The `Tool Editor <#cha:tooledit-gui>`__ or a text editor can be used to edit the tool table. If you
use a text editor make sure you reload the tool table in the GUI.
Tool Table Format
~~~~~~~~~~~~~~~~~
Table 1. Tool Table Format
T#
P#
X
Y
Z
A
B
C
U
V
W
Dia
FA
BA
Ori
Rem
;
(no data after opening semicolon)
T1
P17
X0
Y0
Z0
A0
B0
C0
U0
V0
W0
D0
I0
J0
Q0
;rem
T2
P5
X0
Y0
Z0
A0
B0
C0
U0
V0
W0
D0
I0
J0
Q0
;rem
T3
P12
X0
Y0
Z0
A0
B0
C0
U0
V0
W0
D0
I0
J0
Q0
;rem
In general, the new tool table line format is:
- ; - opening semicolon, no data
- T - tool number, 0-99999 (tool numbers must be unique)
- P - pocket number, 1-99999 (pocket numbers must be unique)
- X..W - tool offset on specified axis - floating-point
- D - tool diameter - floating-point, absolute value
- I - front angle (lathe only) - floating-point
- J - back angle (lathe only) - floating-point
- Q - tool orientation (lathe only) - integer, 0-9
- ; - beginning of comment or remark - text
The file consists of one opening semicolon on the first line, followed by up to a maximum of 56 tool
entries.
Earlier versions of LinuxCNC had two different tool table formats for mills and lathes, but since
the 2.4.x release, one tool table format is used for all machines. Just ignore the parts of the tool
table that don’t pertain to your machine, or which you don’t need to use.
Each line of the tool table file after the opening semicolon contains the data for one tool. One
line may contain as many as 16 entries, but will likely contain much fewer.
The units used for the length, diameter, etc., are in machine units.
You will probably want to keep the tool entries in ascending order, especially if you are going to
be using a randomizing tool changer. Although the tool table does allow for tool numbers in any
order.
Each line may have up to 16 entries. The first two entries are required. The last entry (a remark
or comment, preceded by a semicolon) is optional. It makes reading easier if the entries are
arranged in columns, as shown in the table, but the only format requirement is that there be at
least one space or tab after each of the entries on a line and a newline character at the end of
each entry.
The meanings of the entries and the type of data to be put in each are as follows.
Tool Number (required)
The 'T' column contains the number (unsigned integer) which represents a code number for the
tool. The user may use any code for any tool, as long as the codes are unsigned integers.
Pocket Number (required)
The 'P' column contains the number (unsigned integer) which represents the pocket number (slot
number) of the tool changer slot where the tool can be found. The entries in this column must all be
different.
The pocket numbers will typically start at 1 and go up to the highest available pocket on your tool
changer. But not all tool changers follow this pattern. Your pocket numbers will be determined by
the numbers that your tool changer uses to refer to the pockets. So all this is to say that the
pocket numbers you use will be determined by the numbering scheme used in your tool changer, and the
pocket numbers you use must make sense on your machine.
Data Offset Numbers (optional)
The 'Data Offset' columns (XYZABCUVW) contain real numbers which represent tool offsets in each
axis. This number will be used if tool length offsets are being used and this tool is
selected. These numbers can be positive, zero, or negative, and are in fact completely optional.
Although you will probably want to make at least one entry here, otherwise there would be little
point in making an entry in the tool table to begin with.
In a typical mill, you probably want an entry for Z (tool length offset). In a typical lathe, you
probably want an entry for X (X tool offset) and Z (Z tool offset). In a typical mill using cutter
diameter compensation (cutter comp), you probably also want to add an entry for D (cutter
diameter). In a typical lathe using tool nose diameter compensation (tool comp), you probably also
want to add an entry for D (tool nose diameter).
A lathe also requires some additional information to describe the shape and orientation of the
tool. So you probably want to have entries for I (tool front angle) and J (tool back angle). You
probably also want an entry for Q (tool orientation).
See the `Lathe User Information <#cha:lathe-user-information>`__ chapter for more detail.
The 'Diameter' column contains a real number. This number is used only if cutter compensation is
turned on using this tool. If the programmed path during compensation is the edge of the material
being cut, this should be a positive real number representing the measured diameter of the tool. If
the programmed path during compensation is the path of a tool whose diameter is nominal, this should
be a small number (positive or negative, but near zero) representing only the difference between the
measured diameter of the tool and the nominal diameter. If cutter compensation is not used with a
tool, it does not matter what number is in this column.
The 'Comment' column may optionally be used to describe the tool. Any type of description is
OK. This column is for the benefit of human readers only. The comment must be preceded by a
semicolon.
Tool Changers
~~~~~~~~~~~~~
LinuxCNC supports three types of tool changers: 'manual', 'random location' and 'fixed
location'. Information about configuring a LinuxCNC tool changer is in the `EMCIO Section
<#sec:emcio-section>`__ of the INI chapter.
Manual Tool Changer
Manual tool changer (you change the tool by hand) is treated like a fixed location tool changer and
the P number is ignored. Using the manual tool changer only makes sense if you have tool holders
that remain with the tool (Cat, NMTB, Kwik Switch etc.) when changed thus preserving the location of
the tool to the spindle. Machines with R-8 or router collet type tool holders do not preserve the
location of the tool and the manual tool changer should not be used.
Fixed Location Tool Changers
Fixed location tool changers always return the tools to a fixed position in the tool changer. This
would also include designs like lathe turrets. When LinuxCNC is configured for a fixed location
tool changer the 'P' number is ignored (but read, preserved and rewritten) by LinuxCNC, so you can
use P for any bookkeeping number you want.
Random Location Tool Changers
Random location tool changers swap the tool in the spindle with the one in the changer. With this
type of tool changer the tool will always be in a different pocket after a tool change. When a tool
is changed LinuxCNC rewrites the pocket number to keep track of where the tools are. T can be any
number but P must be a number that makes sense for the machine.
Cutter Compensation
-------------------
Cutter Compensation allows the programmer to program the tool path without knowing the exact tool
diameter. The only caveat is the programmer must program the lead in move to be at least as long as
the largest tool radius that might be used.
There are two possible paths the cutter can take while cutter compensation is on to the left or
right side of a line when facing the direction of cutter motion from behind the cutter. To visualize
this imagine you were standing on the part walking behind the tool as it progresses across the
part. G41 is your left side of the line and G42 is the right side of the line.
The end point of each move depends on the next move. If the next move creates an outside corner the
move will be to the end point of the compensated cut line. If the next move creates in an inside
corner the move will stop short so to not gouge the part. The following figure shows how the
compensated move will stop at different points depending on the next move.
Figure 2. Compensation End Point
Overview
~~~~~~~~
Tool Table
Cutter compensation uses the data from the tool table to determine the offset needed. The data can
be set at run time with G10 L1.
Programming Entry Moves
Any move that is long enough to perform the compensation will work as the entry move. The minimum
length is the cutter radius. This can be a rapid move above the work piece. If several rapid moves
are issued after a G41/42 only the last one will move the tool to the compensated position.
In the following figure you can see that the entry move is compensated to the right of the
line. This puts the center of the tool to the right of X0 in this case. If you were to program a
profile and the end is at X0 the resulting profile would leave a bump due to the offset of the entry
move.
Figure 3. Entry Move
Z Motion
Z axis motion may take place while the contour is being followed in the XY plane. Portions of the
contour may be skipped by retracting the Z axis above the part and by extending the Z-axis at the
next start point.
Rapid Moves
Rapid moves may be programed while compensation is turned on.
Good Practices
- Start a program with G40 to make sure compensation is off.
Examples
~~~~~~~~
Figure 4. Outside Profile
Figure 5. Inside Profile
.. |Touch Off Tool Table| image:: images/ToolTable-TouchOff.png
.. |Compensation End Point| image:: images/comp-path.png
.. |Entry Move| image:: images/comp02.png
.. |Outside Profile| image:: images/outside-comp.png
.. |Inside Profile| image:: images/inside-comp.png
.. include:: ../../abbreviation.txt
.. _rs-274-reference-page:
=========================
RS-274 G-code Reference
=========================
.. Note::
Text derived from several sources, like NIST RS-274 paper and Linux CNC project.
cf. supra for references.
History
-------
The G-code language, also called RS-274, is a programming language for numerical control. It was
developed by the EIA in the early 1960s, and finally standardised by ISO in February 1980 as RS274D
/ ISO 6983.
The G-code language has several flavours and historical versions. A list of reference documents
follows :
* `The NIST RS274NGC Interpreter - Version 3, T. Kramer, F. Proctor, E. Messina, National Institute
of Standards and Technology, NISTIR 6556, August 17, 2000
<https://www.nist.gov/publications/nist-rs274ngc-interpreter-version-3>`_
* The documentation of the `Linux CNC <http://linuxcnc.org>`_ project, formerly Enhanced Machine
Controller developed at NIST,
* EIA Standard RS-274-D Interchangeable Variable Block Data Format for Positioning, Contouring, and
Contouring/Positioning Numerically Controlled Machines, 2001 Eye Street, NW, Washington,
D.C. 20006: Electronic Industries Association, February 1979
Overview
--------
The RS274/NGC language is based on lines of code. Each line (also called a “block”) may include
commands to a machining center to do several different things.
A typical line of code consists of an optional line number at the beginning followed by one or more
“words.” A word consists of a letter followed by a number (or something that evaluates to a
number). A word may either give a command or provide an argument to a command. For example,
:code:`G1 X3` is a valid line of code with two words. :code:`G1` is a command meaning “move in a
straight line at the programmed feed rate,” and :code:`X3` provides an argument value (the value of
X should be 3 at the end of the move). Most RS274/NGC commands start with either G or M (for
miscellaneous). The words for these commands are called “G codes” and “M codes.”
Language View of a Machining Center
-----------------------------------
Parameters
~~~~~~~~~~
In the RS274/NGC language view, a machining center maintains an array of 5400 numerical
parameters. Many of them have specific uses. The parameter array should persist over time, even if
the machining center is powered down.
.. include:: parameters.rst
Coordinate Systems
~~~~~~~~~~~~~~~~~~
In the RS274/NGC language view, a machining center has an absolute coordinate system and nine
program coordinate systems.
You can set the offsets of the nine program coordinate systems using G10 L2 Pn (n is the number of
the coordinate system) with values for the axes in terms of the absolute coordinate system.
You can select one of the nine systems by using G54, G55, G56, G57, G58, G59, G59.1, G59.2, or
G59.3. It is not possible to select the absolute coordinate system directly. You can offset the
current coordinate system using G92 or G92.3. This offset will then apply to all nine program
coordinate systems. This offset may be cancelled with G92.1 or G92.2.
You can make straight moves in the absolute machine coordinate system by using G53 with either G0 or
G1.
Data for coordinate systems is stored in parameters.
During initialization, the coordinate system is selected that is specified by parameter 5220. A
value of 1 means the first coordinate system (the one G54 activates), a value of 2 means the second
coordinate system (the one G55 activates), and so on. It is an error for the value of parameter 5220
to be anything but a whole number between one and nine.
Format of a Line
----------------
A permissible line of input RS274/NGC code consists of the following, in order, with the restriction
that there is a maximum (currently 256) to the number of characters allowed on a line.
#. an optional block delete character, which is a slash :code:`/` .
#. an optional line number.
#. any number of words, parameter settings, and comments.
#. an end of line marker (carriage return or line feed or both).
Spaces and tabs are allowed anywhere on a line of code and do not change the meaning of the line,
except inside comments. This makes some strange-looking input legal. The line :code:`g0x +0. 12 34y
7` is equivalent to :code:`g0 x+0.1234 y7`, for example.
Blank lines are allowed in the input. They are to be ignored.
Input is case insensitive, except in comments, i.e., any letter outside a comment may be in upper or
lower case without changing the meaning of a line.
Line Number
~~~~~~~~~~~
A line number is the letter :code:`N` followed by an integer (with no sign) between 0 and 99999
written with no more than five digits (000009 is not OK, for example). Line numbers may be repeated
or used out of order, although normal practice is to avoid such usage. Line numbers may also be
skipped, and that is normal practice. A line number is not required to be used, but must be in the
proper place if used.
Word
~~~~
A word is a letter other than :code:`N` followed by a real value.
Words may begin with any of the letters shown in the following table. The table includes :code:`N`
for completeness, even though, as defined above, line numbers are not words. Several letters
(:code:`I`, :code:`J, K`, :code:`L`, :code:`P`, :code:`R`) may have different meanings in different
contexts.
Table. Linux CNC Words and their meanings Letter
.. include:: letters.rst
A real value is some collection of characters that can be processed to come up with a number. A real
value may be an explicit number (such as 341 or -0.8807), a parameter value, an expression, or a
unary operation value.
Number
~~~~~~
The following rules are used for (explicit) numbers. In these rules a digit is a single character
between 0 and 9.
* A number consists of (1) an optional plus or minus sign, followed by (2) zero to many digits,
followed, possibly, by (3) one decimal point, followed by (4) zero to many digits — provided that
there is at least one digit somewhere in the number.
* There are two kinds of numbers: integers and decimals. An integer does not have a decimal point in
it; a decimal does.
* Numbers may have any number of digits, subject to the limitation on line length.
* A non-zero number with no sign as the first character is assumed to be positive. Notice that
initial (before the decimal point and the first non-zero digit) and trailing (after the decimal
point and the last non-zero digit) zeros are allowed but not required. A number written with
initial or trailing zeros will have the same value when it is read as if the extra zeros were not
there.
Parameter Value
~~~~~~~~~~~~~~~
A parameter value is the pound character :code:`#` followed by a real value. The real value must
evaluate to an integer between 1 and 5399. The integer is a parameter number, and the value of the
parameter value is whatever number is stored in the numbered parameter.
The :code:`#` character takes precedence over other operations, so that, for example, :code:`#1+2`
means the number found by adding 2 to the value of parameter 1, not the value found in parameter
3. Of course, :code:`#[1+2]` does mean the value found in parameter 3. The :code:`#` character may
be repeated; for example :code:`##2` means the value of the parameter whose index is the (integer)
value of parameter 2.
Expressions and Binary Operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An expression is a set of characters starting with a left bracket :code:`[` and ending with a
balancing right bracket :code:`]`. In between the brackets are numbers, parameter values,
mathematical operations, and other expressions. An expression may be evaluated to produce a
number. The expressions on a line are evaluated when the line is read, before anything on the line
is executed. An example of an expression is :code:`[ 1 + acos[0] - [#3 ** [4.0/2]]]`.
Binary operations appear only inside expressions. Nine binary operations are defined. There are four
basic mathematical operations: addition :code:`+`, subtraction :code:`-`, multiplication :code:`*`,
and division :code:`/`. There are three logical operations: non-exclusive or :code:`OR`, exclusive
or :code:`XOR`, and logical and :code:`AND`. The eighth operation is the modulus operation
:code:`MOD`. The ninth operation is the “power” operation :code:`**` of raising the number on the
left of the operation to the power on the right. The binary operations are divided into three
groups. The first group is: power. The second group is: multiplication, division, and modulus. The
third group is: addition, subtraction, logical non- exclusive or, logical exclusive or, and logical
and. If operations are strung together (for example in the expression :code:`[2.0 / 3 * 1.5 - 5.5 /
11.0]`), operations in the first group are to be performed before operations in the second group and
operations in the second group before operations in the third group. If an expression contains more
than one operation from the same group (such as the first / and * in the example), the operation on
the left is performed first. Thus, the example is equivalent to: :code:`[((2.0 / 3) * 1.5) - (5.5 /
11.0)]`, which simplifies to :code:`[1.0 - 0.5]`, which is 0.5.
The logical operations and modulus are to be performed on any real numbers, not just on integers.
The number zero is equivalent to logical false, and any non-zero number is equivalent to logical
true.
Unary Operation Value
~~~~~~~~~~~~~~~~~~~~~
A unary operation value is either :code:`ATAN` followed by one expression divided by another
expression (for example :code:`ATAN[2]/[1+3]`) or any other unary operation name followed by an
expression (for example :code:`SIN[90]`). The unary operations are: :code:`ABS` (absolute value),
:code:`ACOS` (arc cosine), :code:`ASIN` (arc sine), :code:`ATAN` (arc tangent), :code:`COS`
(cosine), :code:`EXP` (e raised to the given power), :code:`FIX` (round down), :code:`FUP` (round
up), :code:`LN` (natural logarithm), :code:`ROUND` (round to the nearest whole number), :code:`SIN`
(sine), :code:`SQRT` (square root), and :code:`TAN` (tangent). Arguments to unary operations which
take angle measures (:code:`COS`, :code:`SIN`, and :code:`TAN`) are in degrees. Values returned by
unary operations which return angle measures (:code:`ACOS`, :code:`ASIN`, and :code:`ATAN`) are also
in degrees.
The :code:`FIX` operation rounds towards the left (less positive or more negative) on a number line,
so that :code:`FIX[2.8] = 2` and :code:`FIX[-2.8] = -3`, for example. The :code:`FUP` operation
rounds towards the right (more positive or less negative) on a number line; :code:`FUP[2.8] = 3` and
:code:`FUP[-2.8] = -2`, for example.
Parameter Setting
~~~~~~~~~~~~~~~~~
A parameter setting is the following four items one after the other: (1) a pound character
:code:`#`, (2) a real value which evaluates to an integer between 1 and 5399, (3) an equal sign
:code:`=`, and (4) a real value. For example :code:`#3 = 15` is a parameter setting meaning “set
parameter 3 to 15.”
A parameter setting does not take effect until after all parameter values on the same line have
been found. For example, if parameter 3 has been previously set to 15 and the line :code:`#3=6 G1
x#3` is interpreted, a straight move to a point where x equals 15 will occur and the value of
parameter 3 will be 6.
Comments and Messages
~~~~~~~~~~~~~~~~~~~~~
Printable characters and white space inside parentheses is a comment. A left parenthesis always
starts a comment. The comment ends at the first right parenthesis found thereafter. Once a left
parenthesis is placed on a line, a matching right parenthesis must appear before the end of the
line. Comments may not be nested; it is an error if a left parenthesis is found after the start of
a comment and before the end of the comment. Here is an example of a line containing a comment:
:code:`G80 M5 (stop motion)`. Comments do not cause a machining center to do anything.
.. A comment contains a message if “MSG,” appears after the left parenthesis and before any other
printing characters. Variants of “MSG,” which include white space and lower case characters are
allowed. The rest of the characters before the right parenthesis are considered to be a message.
Messages should be displayed on the message display device. Comments not containing messages need
not be displayed there.
Item Repeats
~~~~~~~~~~~~
A line may have any number of :code:`G` words, but two :code:`G` words from the same modal group may
not appear on the same line.
A line may have zero to four :code:`M` words. Two :code:`M` words from the same modal group may not
appear on the same line.
For all other legal letters, a line may have only one word beginning with that letter.
If a parameter setting of the same parameter is repeated on a line, :code:`#3=15 #3=6`, for example,
only the last setting will take effect. It is silly, but not illegal, to set the same parameter
twice on the same line.
If more than one comment appears on a line, only the last one will be used; each of the other
comments will be read and its format will be checked, but it will be ignored thereafter. It is
expected that putting more than one comment on a line will be very rare.
Item order
~~~~~~~~~~
The three types of item whose order may vary on a line (as given at the beginning of this section)
are word, parameter setting, and comment. Imagine that these three types of item are divided into
three groups by type.
The first group (the words) may be reordered in any way without changing the meaning of the line.
If the second group (the parameter settings) is reordered, there will be no change in the meaning of
the line unless the same parameter is set more than once. In this case, only the last setting of the
parameter will take effect. For example, after the line :code:`#3=15 #3=6` has been interpreted, the
value of parameter 3 will be 6. If the order is reversed to :code:`#3=6 #3=15` and the line is
interpreted, the value of parameter 3 will be 15.
If the third group (the comments) contains more than one comment and is reordered, only the last
comment will be used.
If each group is kept in order or reordered without changing the meaning of the line, then the three
groups may be interleaved in any way without changing the meaning of the line. For example, the line
:code:`g40 g1 #3=15 (foo) #4=-7.0` has five items and means exactly the same thing in any of the 120
possible orders (such as :code:`#4=-7.0 g1 #3=15 g40 (foo)`) for the five items.
Commands and Machine Modes
~~~~~~~~~~~~~~~~~~~~~~~~~~
In RS274/NGC, many commands cause a machining center to change from one mode to another, and the
mode stays active until some other command changes it implicitly or explicitly. Such commands are
called “modal”. For example, if coolant is turned on, it stays on until it is explicitly turned
off. The :code:`G` codes for motion are also modal. If a :code:`G1` (straight move) command is given
on one line, for example, it will be executed again on the next line if one or more axis words is
available on the line, unless an explicit command is given on that next line using the axis words or
cancelling motion.
“Non-modal” codes have effect only on the lines on which they occur. For example, :code:`G4` (dwell)
is non-modal.
Modal Groups
------------
Modal commands are arranged in sets called “modal groups”, and only one member of a modal group may
be in force at any given time. In general, a modal group contains commands for which it is logically
impossible for two members to be in effect at the same time — like measure in inches vs. measure in
millimeters. A machining center may be in many modes at the same time, with one mode from each modal
group being in effect.
.. The modal groups are shown in Table 4.
.. Table . Modal Groups
The modal groups are
.. include:: modal_groups.rst
For several modal groups, when a machining center is ready to accept commands, one member of the
group must be in effect. There are default settings for these modal groups. When the machining
center is turned on or otherwise re-initialized, the default values are automatically in effect.
Group 1, the first group on the table, is a group of :code:`G` codes for motion. One of these is
always in effect. That one is called the current motion mode.
It is an error to put a G-code from group 1 and a G-code from group 0 on the same line if both of
them use axis words. If an axis word-using G-code from group 1 is implicitly in effect on a line (by
having been activated on an earlier line), and a group 0 G-code that uses axis words appears on the
line, the activity of the group 1 G-code is suspended for that line. The axis word-using G-codes
from group 0 are :code:`G10`, :code:`G28`, :code:`G30`, and :code:`G92`.
G and Input Codes
-----------------
For a documentation on G-codes, see :mod:`PythonicGcodeMachine.Gcode.Rs274.GcodeDoc`.
.. include:: gcodes.rst
Order of Execution
------------------
The order of execution of items on a line is critical to safe and effective machine operation. Items
are executed in a particular order if they occur on the same line.
.. include:: execution_order.rst
.. include:: project-links.txt
.. _how-to-refer-page:
===========================
========================================
How to Refer to PythonicGcodeMachine ?
===========================
========================================
Up to now, the official url for PythonicGcodeMachine is @project_url@
Up to now, the official url for PythonicGcodeMachine is |PythonicGcodeMachine@github|
*A permanent redirection will be implemented if the domain change in the future.*
......@@ -17,14 +19,14 @@ A typical `BibTeX <https://en.wikipedia.org/wiki/BibTeX>`_ citation would be, fo
@software{PythonicGcodeMachine,
author = {Fabrice Salvaire}, % actual author and maintainer
title = {PythonicGcodeMachine},
url = {@project_url@},
url = {https://github.com/FabriceSalvaire/pythonic-gcode-machine},
version = {x.y},
date = {yyyy-mm-dd}, % set to the release date
date = {2018-12-24}, % set to the release date
}
@Misc{PythonicGcodeMachine,
author = {Fabrice Salvaire},
title = {PythonicGcodeMachine},
howpublished = {\url{@project_url@}},
year = {yyyy}
howpublished = {\url{https://github.com/FabriceSalvaire/pythonic-gcode-machine}},
year = {2018}
}
......@@ -37,9 +37,9 @@
<div class="reduced-width">
############################
The Pythonic Gcode Machine
############################
#############################
The Pythonic G-code Machine
#############################
.. .. image:: /_static/logo.png
.. :alt: PythonicGcodeMachine logo
......@@ -49,7 +49,7 @@
Overview
********
PythonicGcodeMachine is a free and open source (*) Python toolkit to work with RS-274 / ISO G-Code.
PythonicGcodeMachine is a free and open source (*) Python toolkit to work with RS-274 / ISO G-code.
.. rst-class:: small-text
......@@ -146,6 +146,8 @@ If you want to donate to the project or need a more professional support.
roadmap.rst
installation.rst
faq.rst
examples/index.rst
gcode-reference/index.rst
design-notes.rst
reference-manual.rst
development.rst
......
......@@ -10,7 +10,9 @@
What is PythonicGcodeMachine ?
------------------------------
PythonicGcodeMachine is a free and open source Python toolkit to work with RS-274 / ISO G-Code.
PythonicGcodeMachine is a free and open source Python toolkit to work with RS-274 / ISO G-code.
.. include:: features.txt
How is PythonicGcodeMachine licensed ?
--------------------------------------
......
.. include:: abbreviation.txt
.. _related-projects-page:
==================
......@@ -7,11 +9,43 @@
G-code Tools
------------
* `pygcode — GCODE Parser for Python <https://github.com/fragmuffin/pygcode>`_
* `pygcode <https://github.com/fragmuffin/pygcode>`_ — G-code parser for Python
CAM Tools
---------
CAM / Computer Aided Manufacturing
----------------------------------
* `PyCAM <http://pycam.sourceforge.net>`_ is a toolpath generator for 3-axis CNC machining. It loads
3D models in STL format or 2D contour models from DXF or SVG files. The resulting G-Code can be
used with LinuxCNC or any other machine controller.
* `simple-gcode-generators <https://github.com/LinuxCNC/simple-gcode-generators>`_ — Simple LinuxCNC
G-Code Generators written in Python
This repository contains a collection of Python scrips that generate simple G-Code for LinuxCNC.
CNC / Control Machine
---------------------
* |MachineKit|_ — platform for machine control applications (LinuxCNC fork)
Machinekit is portable across a wide range of hardware platforms and real-time environments, and
delivers excellent performance at low cost. It is based on the HAL component architecture, an
intuitive and easy to use circuit model that includes over 150 building blocks for digital logic,
motion, control loops, signal processing, and hardware drivers. Machinekit supports local and
networked UI options, including ubiquitous platforms like phones or tablets.
* |LinuxCNC|_ — platform for machine control applications
Forked by Machinekit, LinuxCNC was formerly called Enhanced Machine Controller or EMC2, a software
project developed by |NIST|_.
* `PyCNC <https://github.com/Nikolay-Kha/PyCNC>`_ — Python CNC machine controller for Raspberry Pi and other ARM Linux boards
PyCNC is a free open-source high-performance G-code interpreter and CNC/3D-printer controller. It
can run on a variety of Linux-powered ARM-based boards, such as Raspberry Pi, Odroid, Beaglebone
and others. This gives you a flexibility to pick a board you are most familiar with, and use
everything Linux has to offer, while keeping all your G-code runtime on the same board without a
need to have a separate microcontroller for real-time operation. Our choice of Python as main
programming language significantly reduces code base compared to C/C++ projects, reduces
boilerplate and microcontroller-specific code, and makes the project accessible to a broader
audience to tinker with.
#?##################################################################################################
#?#
#?# PythonicGcodeMachine - A Python G-code Toolkit
#?# Copyright (C) 2018 Fabrice Salvaire
#?#
#?# This program is free software: you can redistribute it and/or modify
#?# it under the terms of the GNU General Public License as published by
#?# the Free Software Foundation, either version 3 of the License, or
#?# (at your option) any later version.
#?#
#?# This program is distributed in the hope that it will be useful,
#?# but WITHOUT ANY WARRANTY; without even the implied warranty of
#?# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#?# GNU General Public License for more details.
#?#
#?# You should have received a copy of the GNU General Public License
#?# along with this program. If not, see <http://www.gnu.org/licenses/>.
#?#
#?##################################################################################################
####################################################################################################
#r# ===========================
#r# Annotate a G-code program
#r# ===========================
#r#
#r# For API see
#r#
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Ast`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Condig`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Machine`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Parser`
####################################################################################################
from pathlib import Path
from PythonicGcodeMachine.Gcode.Rs274.Machine import GcodeMachine
####################################################################################################
#r# We build a RS-274 G-code Machine
machine = GcodeMachine()
####################################################################################################
#r# We load a G-code program
program_filename = 'mill-example-1.ngc'
programs_directory = Path(__file__).parents[1].joinpath('programs')
program_path = programs_directory.joinpath(program_filename)
with open(program_path, 'r') as fh:
lines = fh.readlines()
if lines[0].startswith(';'):
lines = lines[1:]
####################################################################################################
#r# We parse the program
program = machine.parser.parse_lines(lines)
#r# We dump the annotated program
def str_list(a_list):
return ' '.join([str(item) for item in a_list])
meaning_format = ' {:5}: {}'
for line in program:
print()
# print(line.ansi_str()) # Fixme: pyterate
print(str(line))
line.check_modal_group()
for word in line.iter_on_word():
if word.is_gm_gcode:
margin = ' '*9
print(meaning_format.format(str(word), word.meaning))
print(margin + 'Modal group: {}'.format(word.modal_group.meaning))
print(margin + 'Execution order: {}'.format(word.execution_order.index))
print(margin + 'Valid G-code: {}'.format(word.is_valid_gcode))
else:
print(meaning_format.format(word.letter, word.meaning))
print(
' execution:',
str_list(line.iter_in_order()), '/',
str_list(line.iter_on_x_word()), '/',
str_list(line.iter_on_setting()),
)
#o#
#?##################################################################################################
#?#
#?# PythonicGcodeMachine - A Python G-code Toolkit
#?# Copyright (C) 2018 Fabrice Salvaire
#?#
#?# This program is free software: you can redistribute it and/or modify
#?# it under the terms of the GNU General Public License as published by
#?# the Free Software Foundation, either version 3 of the License, or
#?# (at your option) any later version.
#?#
#?# This program is distributed in the hope that it will be useful,
#?# but WITHOUT ANY WARRANTY; without even the implied warranty of
#?# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#?# GNU General Public License for more details.
#?#
#?# You should have received a copy of the GNU General Public License
#?# along with this program. If not, see <http://www.gnu.org/licenses/>.
#?#
#?##################################################################################################
####################################################################################################
#r# ===========================
#r# Generate a G-code program
#r# ===========================
#r#
#r# For API see
#r#
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Ast`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Parser`
####################################################################################################
from PythonicGcodeMachine.Gcode.Rs274.Ast import *
from PythonicGcodeMachine.Gcode.Rs274.Parser import GcodeParser
####################################################################################################
#r# Create a G-code line (block) using AST API
line = Line(deleted=False, line_number=1, comment='a G-code block')
# Push some items
# Note: order doesn't matter, see RS-274 for details
line += Word('G', 0)
line += Comment('fast move')
line += Word('X', 10)
line += Word('Y', 20)
print(line)
#o#
#r# More simpler way to pass G/M-code
a_line = Line()
a_line += 'G0'
a_line += Word('X', 10)
print(a_line)
#o#
#r# Using the G-code parser
parser = GcodeParser()
a_line = parser.parse('G0 X0 Y0')
a_line += Word('Z', 0)
print(a_line)
#o#
a_line = Line()
a_line += 'G0'
parsed_line = parser.parse('X1 Y2')
print(list(parsed_line))
first_item = parsed_line[0]
print(first_item)
a_line += parsed_line
print(a_line)
#o#
#r# Expression : the AST way
line2 = line.clone()
line2 += Word('Z', Addition(30, Multiply(Parameter(100), Cosine(30))))
print(line2)
#o#
#r# Expression : the literal way
line3 = line.clone()
line3 += Word('Z', '[30 + [#100 * cos[30]]]')
print(line3)
#o#
#r# Invalid expression
try:
line4 = line.clone()
line4 += Word('Z', '1 + 2]')
print(line4)
except ValueError:
pass
#r# Create a G-code program
program = Program()
program += line
line2.line_number = 2
line2.comment = 'using expression'
program += line2
line3.deleted = True
line3.line_number = 3
line3.comment = None
program += line3
print(program)
#o#
#r# Line cleanup tools
line = Line(deleted=False, line_number=1, comment='a G-code block')
line += 'G0'
line += Comment('fast move')
line += Word('X', 10)
line += Word('Y', 20)
print(line)
#o#
line.toggle()
print(line)
#o#
line.toggle()
line.remove_line_number()
print(line)
#o#
line.remove_comment()
print(line)
#o#
#?##################################################################################################
#?#
#?# PythonicGcodeMachine - A Python G-code Toolkit
#?# Copyright (C) 2018 Fabrice Salvaire
#?#
#?# This program is free software: you can redistribute it and/or modify
#?# it under the terms of the GNU General Public License as published by
#?# the Free Software Foundation, either version 3 of the License, or
#?# (at your option) any later version.
#?#
#?# This program is distributed in the hope that it will be useful,
#?# but WITHOUT ANY WARRANTY; without even the implied warranty of
#?# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#?# GNU General Public License for more details.
#?#
#?# You should have received a copy of the GNU General Public License
#?# along with this program. If not, see <http://www.gnu.org/licenses/>.
#?#
#?##################################################################################################
####################################################################################################
#r# ===============
#r# Query G-codes
#r# ===============
#r#
#r# For API see
#r#
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Config`
#r# * :mod:`PythonicGcodeMachine.Gcode.Rs274.Machine`
####################################################################################################
from pathlib import Path
from PythonicGcodeMachine.Gcode.Rs274.Machine import GcodeMachine
####################################################################################################
#r# We build a RS-274 G-code Machine
machine = GcodeMachine()
####################################################################################################
#r# We get G-code information
gcode = machine.config.gcodes['G0']
print('Modal group:', gcode.modal_group)
print('Execution order:', gcode.execution_order)
#o#
print('\nreStructuredText doc:\n')
print(gcode.doc)
#o#
#r# Convert the reStructuredText doc using `pypandoc <https://github.com/bebraw/pypandoc>`_ and
#r# `Pandoc <https://pandoc.org>`_
try:
print('\nMarkdown doc:')
print(gcode.convert_doc('md'))
except (ImportError, RuntimeError):
pass
#o#
try:
print('\nHTML doc:')
print(gcode.convert_doc('html5'))
except (ImportError, RuntimeError):
pass
#o#
.. -*- Mode: rst -*-
.. _examples-page:
==========
Examples
==========
; http://www.helmancnc.com/cnc-mill-example-program-g01-g02-g03-g90-g91
N40 G90 G00 X0 Y0
N50 G01 X-10 Y-20 R8 (P1)
N60 G01 X-50 R10 (P2)
N70 Y10 (P3)
N80 X-19.97 Y25.01 (P4)
N90 G03 X7.97 Y38.99 R18 (P5)
N100 G01 X30 Y50 (P6)
N110 G91 X10.1 Y-10.1 (P7)
N120 G90 G02 X59.9 Y20.1 R14 (P8)
N130 G01 X70 Y10 (P9)
N140 Y-20 R10 (P10)
N150 X50 (P11)
N160 G03 X30 R10 (P12)
N170 G01 X10 R8 (P13)
N180 X0 Y0
......@@ -2,7 +2,7 @@
####################################################################################################
#
# PythonicGcodeMachine - @licence_header_description@
# PythonicGcodeMachine - A Python G-code Toolkit
# Copyright (C) 2018 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
......
####################################################################################################
#
# PythonicGcodeMachine - @licence_header_description@
# PythonicGcodeMachine - A Python G-code Toolkit
# Copyright (C) 2018 Fabrice Salvaire
#
# This program is free software: you can redistribute it and/or modify
......