Skip to content
m-code.rst 23.8 KiB
Newer Older
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
--------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M0`` - pause a running program temporarily. LinuxCNC remains in the Auto Mode so MDI and other
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  manual actions are not enabled. Pressing the resume button will restart the program at the
  following line.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M1`` - pause a running program temporarily if the optional stop switch is on. LinuxCNC remains in
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  the Auto Mode so MDI and other manual actions are not enabled. Pressing the resume button will
  restart the program at the following line.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M2, M30 Program End
-------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  at the beginning of the file.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

Both of these commands have the following effects:

#. Change from Auto mode to MDI mode.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
#. 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``).
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M60 Pallet Change Pause
-----------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M60`` - exchange pallet shuttles and then pause a running program temporarily (regardless of the
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  setting of the optional stop switch).  Pressing the cycle start button will restart the program at
  the following line.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M3, M4, M5 Spindle Control
--------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

Use $ to operate on specific spindles. If $ is omitted then thr commands operate on all spindles.

For example

Fabrice Salvaire's avatar
Fabrice Salvaire committed
.. code:: text
Fabrice Salvaire's avatar
Fabrice Salvaire committed

   ---
   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

Fabrice Salvaire's avatar
Fabrice Salvaire committed
It is OK to use ``M3`` or ``M4`` if the `S <#sec:set-spindle-speed>`__ spindle speed is set to zero. If
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M6 Tool Change
--------------

Manual Tool Change
~~~~~~~~~~~~~~~~~~

If the HAL component hal_manualtoolchange is loaded, M6 will stop the spindle and prompt the user to
Fabrice Salvaire's avatar
Fabrice Salvaire committed
change the tool based on the last ``T-`` number programmed. For more information on
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
selected (using a T word - see Section `Select Tool <#sec:select-tool>`__), program ``M6``. When the
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  unless it has been turned off by an ``M9``.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
change in hal and possibly classic ladder.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M7, M8, M9 Coolant Control
--------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
It is OK to use any of these commands, regardless of the current coolant state.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M19 Orient Spindle
------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  true within Q timeout an error occurs.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``P`` Direction to rotate to position.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
   * ``0`` rotate for smallest angular movement (default)
   * ``1`` always rotate clockwise (same as M3 direction)
   * ``2`` always rotate counterclockwise (same as M4 direction)
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``$`` The spindle to orient (actually only determines which HAL pins carry the spindle position
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  commands)
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M19 is cleared by any of M3,M4,M5.

Fabrice Salvaire's avatar
Fabrice Salvaire committed
Spindle orientation requires a quadrature encoder with an index to sense the spindle shaft position
and direction of rotation.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

INI Settings in the [RS274NGC] section.

ORIENT_OFFSET = 0-360 (fixed offset in degrees added to M19 R word)

HAL Pins

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.orient-angle`` (out float) Desired spindle orientation for M19. Value of the M19 R word
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  parameter plus the value of the [RS274NGC]ORIENT_OFFSET ini parameter.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.orient-mode`` (out s32) Desired spindle rotation mode.  Reflects M19 P parameter word,
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  Default = 0
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.orient`` (out bit) Indicates start of spindle orient cycle.  Set by M19. Cleared by any
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  of M3,M4,M5. If spindle-orient-fault is not zero during spindle-orient true, the M19 command fails
  with an error message.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.is-oriented`` (in bit) Acknowledge pin for spindle-orient.  Completes orient cycle. If
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.orient-fault`` (in s32) Fault code input for orient cycle.  Any value other than zero
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  will cause the orient cycle to abort.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``spindle.N.locked`` (out bit) Spindle orient complete pin. Cleared by any of M3,M4,M5.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M48, M49 Speed and Feed Override Control
----------------------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M48`` - enable the spindle speed and feed rate override controls.
* ``M49`` - disable both controls.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
These commands also take an optional $ parameter to determine which spindle they operate on.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M50 Feed Override Control
-------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M50 <P1>`` - enable the feed rate override control. The P1 is optional.
* ``M50 P0`` - disable the feed rate control.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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).
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M51 Spindle Speed Override Control
----------------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M51 <P1> <$→``- enable the spindle speed override control for the selected spindle. The P1 is
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  optional.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M51 P0 <$→`` - disable the spindle speed override control program.  While disabled the spindle
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  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).
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M52 Adaptive Feed Control
-------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M52 <P1>`` - use an adaptive feed. The P1 is optional.
* ``M52 P0`` - stop using adaptive feed.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
pin ``motion.adaptive-feed`` is used for this purpose. Values on ``motion.adaptive-feed`` should range
Fabrice Salvaire's avatar
Fabrice Salvaire committed
from 0 (feed hold) to 1 (full speed).
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M53 Feed Stop Control
---------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M53 <P1>`` - enable the feed stop switch. The P1 is optional.  Enabling the feed stop switch will
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  allow motion to be interrupted by means of the feed stop control. In LinuxCNC, the HAL pin
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  ``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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  feed when M53 is not active.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M61 Set Current Tool
--------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M61 Q-`` - change the current tool number while in MDI or Manual mode. One use is when you power
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  up LinuxCNC with a tool currently in the spindle you can set that tool number without doing a tool
  change.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

It is an error if:

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* Q- is not 0 or greater
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M62 - M65 Digital Output Control
--------------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M62 P-`` - turn on digital output synchronized with motion. The P- word specifies the digital
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  output number.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``M63 P-`` - turn off digital output synchronized with motion. The P- word specifies the digital
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  output number.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
M64 & M65 happen immediately as they are received by the motion controller. They are not
synchronized with movement, and they will break blending.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M66 Wait on Input
-----------------

::

   M66 P- | E- <L->

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
   * ``Mode 0: IMMEDIATE`` - no waiting, returns immediately. The current value of the input is stored
Fabrice Salvaire's avatar
Fabrice Salvaire committed
     in parameter #5399
Fabrice Salvaire's avatar
Fabrice Salvaire committed
   * ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``Q-`` - specifies the timeout in seconds for waiting. If the timeout is exceeded, the wait is
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* Mode 0 is the only one permitted for an analog input.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M66 Example Lines

::

   M66 P0 L3 Q5 (wait up to 5 seconds for digital input 0 to turn on)

Fabrice Salvaire's avatar
Fabrice Salvaire committed
M66 wait on an input stops further execution of the program, until the selected event (or the
programmed timeout) occurs.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

Example HAL Connection

::

   net signal-name motion.digital-in-00 <= parport.0.pin10-in

M67 Analog Output,Synchronized
------------------------------

::

   M67 E- Q-

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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).
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M68 Analog Output, Immediate
----------------------------

::

   M68 E- Q-

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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).
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M70 Save Modal State
--------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
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``.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
A pair of ``M70`` and ``M72`` instructions will typically be used to protect a program against
Fabrice Salvaire's avatar
Fabrice Salvaire committed
inadvertant modal changes within subroutines.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

The state saved consists of:

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* 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)
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* current feed and speed (``F`` and ``S`` values)
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* 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)
Fabrice Salvaire's avatar
Fabrice Salvaire committed

Note that in particular, the motion mode (G1 etc) is NOT restored.

Fabrice Salvaire's avatar
Fabrice Salvaire committed
``current call level`` means either:
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* executing in the main program. There is a single storage location for state at the main program
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  level; if several ``M70`` instructions are executed in turn, only the most recently saved state is
  restored when an ``M72`` is executed.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* executing within a G-code subroutine. The state saved with ``M70`` within a subroutine behaves
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  exactly like a local named parameter - it can be referred to only within this subroutine
Fabrice Salvaire's avatar
Fabrice Salvaire committed
  invocation with an ``M72`` and when the subroutine exits, the parameter goes away.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

A recursive invocation of a subroutine introduces a new call level.

M71 Invalidate Stored Modal State
---------------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
Modal state saved with an ``M70`` or by an ``M73`` at the current call level is invalidated (cannot be
Fabrice Salvaire's avatar
Fabrice Salvaire committed
restored from anymore).
Fabrice Salvaire's avatar
Fabrice Salvaire committed
A subsequent ``M72`` at the same call level will fail.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
If executed in a subroutine which protects modal state by an ``M73``, a subsequent return or endsub
Fabrice Salvaire's avatar
Fabrice Salvaire committed
will **not** restore modal state.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The usefulness of this feature is dubious. It should not be relied upon as it might go away.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M72 Restore Modal State
-----------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
`Modal state saved with an ``M70`` <#mcode:m70-saved-state>`__ code can be restored by executing an
``M72``.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The handling of G20/G21 is specially treated as feeds are interpreted differently depending on
Fabrice Salvaire's avatar
Fabrice Salvaire committed
G20/G21: if length units (mm/in) are about to be changed by the restore operation, ``M72 ``will
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
It is an error to execute an ``M72`` with no previous ``M70`` save operation at that level.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The following example demonstrates saving and explicitely restoring modal state around a subroutine
Fabrice Salvaire's avatar
Fabrice Salvaire committed
call using ``M70`` and ``M72``. Note that the ``imperialsub`` subroutine is not "aware" of the M7x
Fabrice Salvaire's avatar
Fabrice Salvaire committed
features and can be used unmodified:
Fabrice Salvaire's avatar
Fabrice Salvaire committed
.. code:: text
Fabrice Salvaire's avatar
Fabrice Salvaire committed

   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
------------------------------------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
To save modal state within a subroutine, and restore state on subroutine ``endsub`` or any ``return``
path, program ``M73``.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
Aborting a running program in a subroutine which has an ``M73`` operation will **not** restore state .
Fabrice Salvaire's avatar
Fabrice Salvaire committed
Also, the normal end (``M2``) of a main program which contains an ``M73`` will **not** restore state.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The suggested use is at the beginning of a O-word subroutine as in the following example. Using
Fabrice Salvaire's avatar
Fabrice Salvaire committed
``M73`` this way enables designing subroutines which need to modify modal state but will protect the
Fabrice Salvaire's avatar
Fabrice Salvaire committed
calling program against inadvertant modal changes. Note the use of `predefined named parameters
Fabrice Salvaire's avatar
Fabrice Salvaire committed
<#gcode:predefined-named-parameters>`__ in the ``showstate`` subroutine.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
.. code:: text
Fabrice Salvaire's avatar
Fabrice Salvaire committed

   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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
   ; explicit ``return`` will restore caller state
Fabrice Salvaire's avatar
Fabrice Salvaire committed
   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
-----------

Fabrice Salvaire's avatar
Fabrice Salvaire committed
The interpreter supports Fanuc-style main- and sub-programs with the ``M98`` and ``M99`` M-codes. See
Fabrice Salvaire's avatar
Fabrice Salvaire committed
`Fanuc-Style Programs <#ocode:fanuc-style-programs>`__.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

Selectively Restoring Modal State
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Fabrice Salvaire's avatar
Fabrice Salvaire committed
Executing an ``M72`` or returning from a subroutine which contains an ``M73`` will restore `all modal
Fabrice Salvaire's avatar
Fabrice Salvaire committed
state saved <#mcode:m70-saved-state>`__.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
``nc_files/tool-length-probe.ngc``:
Fabrice Salvaire's avatar
Fabrice Salvaire committed
.. code:: text
Fabrice Salvaire's avatar
Fabrice Salvaire committed

   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->

Fabrice Salvaire's avatar
Fabrice Salvaire committed
* ``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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The external program named ``M100`` through ``M199`` (no extension and a capitol M) is executed with the
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed
The error ``Unknown M code used`` denotes one of the following
Fabrice Salvaire's avatar
Fabrice Salvaire committed
* 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
Fabrice Salvaire's avatar
Fabrice Salvaire committed
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.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

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

Fabrice Salvaire's avatar
Fabrice Salvaire committed
To display a graphic message and continue processing the G code file suffix an ampersand to the
command.
Fabrice Salvaire's avatar
Fabrice Salvaire committed

M110 Example display and keep going

::

   #!/bin/bash
   eog /home/john/linuxcnc/nc_files/message.png &
   exit 0