/ docs / src / gcode / m-code.txt
m-code.txt
  1  [[cha:m-codes]]
  2  
  3  = M Codes
  4  
  5  :ini: {basebackend@docbook:'':ini}
  6  :hal: {basebackend@docbook:'':hal}
  7  :ngc: {basebackend@docbook:'':ngc}
  8  
  9  == M Code Quick Reference Table
 10  
 11  [width="60%", options="header", cols="2^,5<"]
 12  |========================================
 13  |Code                                | Description
 14  |<<mcode:m0-m1,M0 M1>>               | Program Pause
 15  |<<mcode:m2-m30,M2 M30>>             | Program End
 16  |<<mcode:m60, M60>>                  | Pallet Change Pause
 17  |<<mcode:m3-m4-m5,M3 M4 M5>>         | Spindle Control
 18  |<<mcode:m6,M6>>                     | Tool Change
 19  |<<mcode:m7-m8-m9,M7 M8 M9>>         | Coolant Control
 20  |<<mcode:m19,M19>>                   | Orient Spindle
 21  |<<mcode:m48-m49,M48 M49>>           | Feed & Spindle Overrides Enable/Disable
 22  |<<mcode:m50,M50>>                   | Feed Override Control
 23  |<<mcode:m51,M51>>                   | Spindle Override Control
 24  |<<mcode:m52,M52>>                   | Adaptive Feed Control
 25  |<<mcode:m53,M53>>                   | Feed Stop Control
 26  |<<mcode:m61,M61>>                   | Set Current Tool Number
 27  |<<mcode:m62-m65,m62-m65>>           | Output Control
 28  |<<mcode:m66,M66>>                   | Input Control
 29  |<<mcode:m67,M67>>                   | Analog Output Control
 30  |<<mcode:m68,M68>>                   | Analog Output Control
 31  |<<mcode:m70,M70>>                   | Save Modal State
 32  |<<mcode:m71,M71>>                   | Invalidate Stored Modal State
 33  |<<mcode:m72,M72>>                   | Restore Modal State
 34  |<<mcode:m73,M73>>                   | Save Autorestore Modal State
 35  |<<mcode:m98-m99,M98 M99>>           | Call and Return From Subprogram
 36  |<<mcode:m100-m199,M100-M199>>       | User Defined M-Codes 
 37  |========================================
 38  
 39  
 40  [[mcode:m0-m1]]
 41  == M0, M1 Program Pause
 42  (((M0, M1 Program Pause)))
 43  
 44  * 'M0' - pause a running program temporarily. LinuxCNC remains in the Auto Mode
 45           so MDI and other manual actions are not enabled. Pressing the resume
 46           button will restart the program at the following line.
 47  
 48  * 'M1' - pause a running program temporarily if the optional stop switch is on.
 49           LinuxCNC remains in the Auto Mode so MDI and other manual actions are
 50           not enabled. Pressing the resume button will restart the program at the
 51           following line.
 52  
 53  [NOTE]
 54  It is OK to program 'M0' and 'M1' in MDI mode,
 55  but the effect will probably not be noticeable,
 56  because normal behavior in MDI mode is 
 57  to stop after each line of input anyway.
 58  
 59  [[mcode:m2-m30]]
 60  == M2, M30 Program End
 61  (((M2, M30 Program End)))
 62  
 63  * 'M2' - end the program. Pressing `Cycle Start` ("R" in the Axis GUI)
 64           will restart the program at the beginning of the file.
 65  
 66  * 'M30' - exchange pallet shuttles and end the program.
 67            Pressing `Cycle Start` will start the program
 68            at the beginning of the file.
 69  
 70  Both of these commands have the following effects:
 71  
 72  . Change from Auto mode to MDI mode.
 73  . Origin offsets are set to the default (like 'G54').
 74  . Selected plane is set to XY plane (like 'G17').
 75  . Distance mode is set to absolute mode (like 'G90').
 76  . Feed rate mode is set to units per minute (like 'G94').
 77  . Feed and speed overrides are set to ON (like 'M48').
 78  . Cutter compensation is turned off (like 'G40').
 79  . The spindle is stopped (like 'M5').
 80  . The current motion mode is set to feed (like 'G1').
 81  . Coolant is turned off (like 'M9').
 82  
 83  [NOTE]
 84  Lines of code after M2/M30 will not be executed. Pressing `Cycle Start`
 85  will start the program at the beginning of the file.
 86  
 87  [WARNING]
 88  Using % to wrap the G code does not do the same thing as a 'Program End'. See
 89  <<gcode:file-requirements,File Requirements>> for more information on what using
 90  % does not do.
 91  
 92  [[mcode:m60]]
 93  == M60 Pallet Change Pause
 94  (((M60 Pallet Change Pause)))
 95  
 96  * 'M60' - exchange pallet shuttles and then pause a running program
 97            temporarily (regardless of the setting of the optional stop
 98            switch). Pressing the cycle start button
 99            will restart the program at the following line.
100  
101  [[mcode:m3-m4-m5]]
102  == M3, M4, M5 Spindle Control
103  (((M3, M4, M5 Spindle Control)))
104  
105  * 'M3 [$n]' - start the selected spindle clockwise at the 'S' speed.
106  * 'M4 [$n]' - start the selected spindle counterclockwise at the 'S' speed.
107  * 'M5 [$n]' - stop the selected spindle.
108  
109  Use $ to operate on specific spindles. If $ is omitted then the commands
110  operate on all spindles. 
111  
112  This example will start spindles 0, 1, and 2 simultaneously at different
113  speeds:
114  [source,{ngc}]
115  ----
116  S100 $0
117  S200 $1
118  S300 $2 
119  M3
120  ----
121  
122  This example will then reverse spindle 1 but leave the other spindles
123  rotating forwards:
124  [source,{ngc}]
125  ----
126  M4 $1
127  ----
128  
129  And this will stop spindle 2 and leave the other spindles rotating:
130  [source,{ngc}]
131  ----
132  M5 $2
133  ----
134  
135  If the $ is omitted then behaviour is exactly as normal for a single
136  spindle machine
137  
138  It is OK to use 'M3' or 'M4' if the <<sec:set-spindle-speed,S>>
139  spindle speed is set to zero. If this is done
140  (or if the speed override switch is enabled and set to zero),
141  the spindle will not start turning.
142  If, later, the spindle speed is set above zero
143  (or the override switch is turned up),
144  the spindle will start turning.
145  It is OK to use 'M3' or 'M4' when the spindle is already
146  turning or to use 'M5' when the spindle is already stopped.
147  
148  [[mcode:m6]]
149  == M6 Tool Change
150  (((M6-Tool-Change)))
151  
152  === Manual Tool Change
153  
154  If the HAL component hal_manualtoolchange is loaded,
155  M6 will stop the spindle and prompt the user to change the tool
156  based on the last 'T-' number programmed.
157  For more information on hal_manualtoolchange see
158  the <<sec:manual-tool-change,Manual Tool Change>> section.
159  
160  === Tool Changer
161  
162  To change a tool in the spindle from the tool currently in the spindle
163  to the tool most recently selected (using a T word - see Section
164  <<sec:select-tool,Select Tool>>), program 'M6'.
165  When the tool change is complete:
166  
167  * The spindle will be stopped. 
168  * The tool that was selected (by a T word on the same line or on any
169     line after the previous tool change) will be in the spindle.
170  * If the selected tool was not in the spindle before the tool change,
171     the tool that was in the spindle (if there was one) will be placed
172     back into the tool changer magazine.
173  * If configured in the .ini file some axis positions may move when a M6
174     is issued. See the <<sec:emcio-section,EMCIO section>> for more
175     information on tool change options.
176  * No other changes will be made. For example, coolant will continue to
177     flow during the tool change unless it has been turned off by an 'M9'.
178  
179  [WARNING]
180  The tool length offset is not changed by 'M6', use '<<gcode:g43,G43>>' after the
181  'M6' to change the tool length offset.
182  
183  The tool change may include axis motion. 
184  It is OK (but not useful) to program a change to the tool already in the spindle.
185  It is OK if there is no tool in the selected slot;
186  in that case, the spindle will be empty after the tool change.
187  If slot zero was last selected,
188  there will definitely be no tool in the spindle after a tool change. The tool
189  changer will have to be setup to perform the tool change in hal and possibly
190  classicladder.
191  
192  [[mcode:m7-m8-m9]]
193  == M7, M8, M9 Coolant Control
194  (((M7, M8, M9 Coolant Control)))
195  
196  * 'M7' - turn mist coolant on. M7 controls iocontrol.0.coolant-mist pin.
197  * 'M8' - turn flood coolant on. M8 controls iocontrol.0.coolant-flood pin.
198  * 'M9' - turn both M7 and M8 off.
199  
200  Connect one or both of the coolant control pins in HAL before M7 or M8 will
201  control an output. M7 and M8 can be used to turn on any output via G code.
202  
203  It is OK to use any of these commands, regardless of the current coolant
204  state.
205  
206  [[mcode:m19]]
207  == M19 Orient Spindle
208  (((M19 Orient Spindle)))
209  
210  * 'M19 R- Q- [P-] [$-]'
211  
212  * 'R' Position to rotate to from 0, valid range is 0-360 degrees
213  
214  * 'Q' Number of seconds to wait until orient completes. If
215        spindle.N.is-oriented does not become true within Q timeout
216        an error occurs.
217  
218  * 'P' Direction to rotate to position.
219  ** '0' rotate for smallest angular movement (default)
220  ** '1' always rotate clockwise (same as M3 direction)
221  ** '2' always rotate counterclockwise (same as M4 direction)
222  
223  * '$' The spindle to orient (actually only determines which HAL pins
224  carry the spindle position commands)
225  
226  M19 is cleared by any of M3,M4,M5.
227  
228  Spindle orientation requires a quadrature encoder with an index to sense the
229  spindle shaft position and direction of rotation.
230  
231  INI Settings in the [RS274NGC] section.
232  
233  ORIENT_OFFSET = 0-360 (fixed offset in degrees added to M19 R word)
234  
235  HAL Pins
236  
237  * 'spindle.N.orient-angle' (out float)
238  Desired spindle orientation for M19. Value of the M19 R word parameter 
239  plus the value of the [RS274NGC]ORIENT_OFFSET ini parameter.
240  
241  * 'spindle.N.orient-mode' (out s32)
242  Desired spindle rotation mode. Reflects M19 P parameter word, Default = 0
243  
244  * 'spindle.N.orient' (out bit)
245  Indicates start of spindle orient cycle. Set by M19. Cleared by any of 
246  M3,M4,M5.
247    If spindle-orient-fault is not zero during spindle-orient true, the 
248  M19 command fails with an error message.
249  
250  * 'spindle.N.is-oriented' (in bit)
251  Acknowledge pin for spindle-orient. Completes orient cycle. If 
252  spindle-orient was true when spindle-is-oriented
253    was asserted, the spindle-orient pin is cleared and the spindle-locked 
254  pin is asserted. Also, the spindle-brake pin is asserted.
255  
256  * 'spindle.N.orient-fault' (in s32)
257    Fault code input for orient cycle. Any value other than zero will 
258  cause the orient cycle to abort.
259  
260  * 'spindle.N.locked' (out bit)
261  Spindle orient complete pin. Cleared by any of M3,M4,M5.
262  
263  [[mcode:m48-m49]]
264  == M48, M49 Speed and Feed Override Control
265  (((M48, M49 Speed and Feed Override Control)))
266  
267  * 'M48' - enable the spindle speed and feed rate override controls.
268  * 'M49' - disable both controls.
269  
270  These commands also take an optional $ parameter to determine which
271  spindle they operate on. 
272  
273  It is OK to enable or disable the controls when 
274  they are already enabled or disabled. 
275  See the <<sub:feed-rate,Feed Rate>> Section for more details.
276  
277  [[mcode:m50]]
278  == M50 Feed Override Control
279  (((M50 Feed Override Control)))
280  
281  * 'M50 <P1>' - enable the feed rate override control. The P1
282                 is optional. 
283  * 'M50 P0' - disable the feed rate control.
284   
285  While disabled the feed override will have no influence,
286  and the motion will be executed at programmed feed rate.
287  (unless there is an adaptive feed rate override active).
288  
289  [[mcode:m51]]
290  == M51 Spindle Speed Override Control
291  (((M51 Spindle Speed Override)))
292  
293  * 'M51 <P1> <$->'- enable the spindle speed override control for the
294                     selected spindle. The  P1 is optional. 
295  * 'M51 P0 <$->'  - disable the spindle speed override control program.
296                     While disabled the spindle speed override will have
297                     no influence, and the spindle speed will have the
298                     exact program specified value of the S-word
299                     (described in <<sec:set-spindle-speed,Spindle Speed>> Section).
300  
301  [[mcode:m52]]
302  == M52 Adaptive Feed Control
303  (((M52 Adaptive Feed Control)))
304  
305  * 'M52 <P1>' - use an adaptive feed. The P1 is optional.
306  * 'M52 P0' - stop using adaptive feed.
307   
308  When adaptive feed is enabled, some external input value is used together
309  with the user interface feed override value and the commanded feed rate
310  to set the actual feed rate. In LinuxCNC, the HAL pin 'motion.adaptive-feed'
311  is used for this purpose. Values on 'motion.adaptive-feed' should range
312  from -1 (programmed speed in reverse) to 1 (full speed). 0 is equivalent
313  to feed-hold.
314  [NOTE]
315  The use of negative adaptive-feed for reverse run is a new
316  feature and is not very well tested as yet. The intended use is for plasma
317  cutters and wire spark eroders but it is not limited to such applications.
318  
319  [[mcode:m53]]
320  == M53 Feed Stop Control
321  (((M53 Feed Stop Control)))
322  
323  * 'M53 <P1>' - enable the feed stop switch. The P1 is optional.
324                 Enabling the feed stop switch will allow motion to be
325                 interrupted by means of the feed stop control. In LinuxCNC,
326                 the HAL pin 'motion.feed-hold' is used for this purpose. A 'true'
327                 value will cause the motion to stop when 'M53' is active.
328  
329  * 'M53 P0' - disable the feed stop switch. The state of 'motion.feed-hold'
330               will have no effect on feed when M53 is not active.
331  
332  [[mcode:m61]]
333  == M61 Set Current Tool
334  (((M61 Set Current Tool)))
335  
336  * 'M61 Q-' - change the current tool number while in MDI or Manual mode without
337               a tool change. One use is when you power up LinuxCNC with a tool
338               currently in the spindle you can set that tool number without
339               doing a tool change.
340  
341  [WARNING]
342  The tool length offset is not changed by 'M61', use '<<gcode:g43,G43>>' after
343  the 'M61' to change the tool length offset.
344  
345  
346  It is an error if:
347  
348  * Q- is not 0 or greater
349  
350  [[mcode:m62-m65]]
351  == M62 - M65 Digital Output Control
352  (((M62 - M65 Digital Output Control)))
353  
354  * 'M62 P-' - turn on digital output synchronized with motion.
355               The P- word specifies the digital output number.
356  
357  * 'M63 P-' - turn off digital output synchronized with motion.
358               The P- word specifies the digital output number.
359  
360  * 'M64 P-' - turn on digital output immediately.
361               The P- word specifies the digital output number.
362  
363  * 'M65 P-' - turn off digital output immediately.
364               The P- word specifies the digital output number.
365  
366  The P-word ranges from 0 to a default value of 3. If needed the the
367  number of I/O can be increased by using the num_dio parameter when loading
368  the motion controller. See the <<sec:motion,Motion Section>> for more
369  information.
370  
371  The M62 & M63 commands will be queued. Subsequent commands referring
372  to the same output number will overwrite the older settings. More than
373  one output change can be specified by issuing more than one M62/M63
374  command.
375  
376  The actual change of the specified outputs will happen at the
377  beginning of the next motion command. If there is no subsequent motion
378  command, the queued output changes won't happen. It's best to always
379  program a motion G code (G0, G1, etc) right after the M62/63.
380  
381  M64 & M65 happen immediately as they are received by the motion
382  controller. They are not synchronized with movement, and they will
383  break blending.
384  
385  [NOTE]
386  M62-65 will not function unless the appropriate motion.digital-out-nn pins are
387  connected in your hal file to outputs.
388  
389  [[mcode:m66]]
390  == M66 Wait on Input
391  (((M66 Wait on Input)))
392  
393  ----
394  M66 P- | E- <L->
395  ----
396  * 'P-' - specifies the digital input number from 0 to 3.
397  * 'E-' - specifies the analog input number from 0 to 3.
398  * 'L-' - specifies the wait mode type.
399  **   'Mode 0: IMMEDIATE' - no waiting, returns immediately.
400         The current value of the input is stored in parameter #5399
401  **   'Mode 1: RISE' - waits for the selected input to perform a rise event.
402  **   'Mode 2: FALL' - waits for the selected input to perform a fall event.
403  **   'Mode 3: HIGH' - waits for the selected input to go to the HIGH state.
404  **   'Mode 4: LOW' - waits for the selected input to go to the LOW state.
405  * 'Q-' - specifies the timeout in seconds for waiting. If the timeout is
406           exceeded, the wait is interrupt, and the variable #5399 will be holding
407           the value -1. The Q value is ignored if the L-word is zero (IMMEDIATE).
408           A Q value of zero is an error if the L-word is non-zero.
409  
410  * Mode 0 is the only one permitted for an analog input.
411  
412  .M66 Example Lines
413  ----
414  M66 P0 L3 Q5 (wait up to 5 seconds for digital input 0 to turn on)
415  ----
416  
417  M66 wait on an input stops further execution of the program, until the
418  selected event (or the programmed timeout) occurs.
419  
420  It is an error to program M66 with both a P-word and an E-word (thus
421  selecting both an analog and a digital input).  In LinuxCNC these
422  inputs are not monitored in real time and thus should not be used for
423  timing-critical applications.
424  
425  The number of I/O can be increased by using the num_dio or num_aio parameter
426  when loading the motion controller. See the <<sec:motion,Motion Section>>
427  for more information.
428  
429  [NOTE]
430  M66 will not function unless the appropriate motion.digital-in-nn pins or
431  motion.analog-in-nn pins are connected in your hal file to an input.
432  
433  .Example HAL Connection
434  ----
435  net signal-name motion.digital-in-00 <= parport.0.pin10-in
436  ----
437  
438  [[mcode:m67]]
439  == M67 Analog Output,Synchronized
440  (((M67 Analog Output, Synchronized)))
441  
442  ----
443  M67 E- Q-
444  ----
445  * 'M67' - set an analog output synchronized with motion.
446  * 'E-' - output number ranging from 0 to 3.
447  * 'Q-' - is the value to set (set to 0 to turn off).
448  
449  The actual change of the specified outputs will happen at the
450  beginning of the next motion command. If there is no subsequent motion
451  command, the queued output changes won't happen. It's best to always
452  program a motion G code (G0, G1, etc) right after the M67. M67 functions
453  the same as M62-63.
454  
455  The number of I/O can be increased by using the num_dio or num_aio parameter
456  when loading the motion controller. See the <<sec:motion,Motion Section>> for
457  more information. 
458  
459  [NOTE]
460  M67 will not function unless the appropriate motion.analog-out-nn pins are
461  connected in your hal file to outputs.
462  
463  [[mcode:m68]]
464  == M68 Analog Output, Immediate
465  (((M68 Analog Output)))
466  
467  ----
468  M68 E- Q-
469  ----
470  * 'M68' - set an analog output immediately.
471  * 'E-' - output number ranging from 0 to 3.
472  * 'Q-' - is the value to set (set to 0 to turn off).
473  
474  M68 output happen immediately as they are received by the motion
475  controller. They are not synchronized with movement, and they will
476  break blending. M68 functions the same as M64-65.
477  
478  The number of I/O can be increased by using the num_dio or num_aio parameter
479  when loading the motion controller. See the <<sec:motion,Motion Section>> for
480  more information.
481  
482  [NOTE]
483  M68 will not function unless the appropriate motion.analog-out-nn pins are
484  connected in your hal file to outputs.
485  
486  [[mcode:m70]]
487  == M70 Save Modal State
488  (((M70 Save Modal State)))
489  
490  To explicitly save the modal state at the current call level, program
491  'M70'. Once modal state has been saved with 'M70', it can be restored
492  to exactly that state by executing an 'M72'.
493  
494  A pair of 'M70' and 'M72' instructions will typically be used to
495  protect a program against inadvertant modal changes within
496  subroutines.
497  
498  [[mcode:m70-saved-state]]
499  
500  The state saved consists of:
501  
502  * current G20/G21 settings (imperial/metric)
503  * selected plane (G17/G18/G19 G17.1,G18.1,G19.1)
504  * status of cutter compensation (G40,G41,G42,G41.1,G42,1)
505  * distance mode - relative/absolute (G90/G91)
506  * feed mode (G93/G94,G95)
507  * current coordinate system (G54-G59.3)
508  * tool length compensation status (G43,G43.1,G49)
509  * retract mode (G98,G99)
510  * spindle mode (G96-css or G97-RPM)
511  * arc distance mode (G90.1, G91.1)
512  * lathe radius/diameter mode (G7,G8)
513  * path control mode (G61, G61.1, G64)
514  * current feed and speed ('F' and 'S' values)
515  * spindle status (M3,M4,M5) - on/off and direction
516  * mist (M7) and flood (M8) status
517  * speed override (M51) and feed override (M50) settings
518  * adaptive feed setting (M52)
519  * feed hold setting (M53)
520  
521  Note that in particular, the motion mode (G1 etc) is NOT restored.
522  
523  'current call level' means either:
524  
525   * executing in the main program. There is a single storage location
526   for state at the main program level; if several 'M70' instructions
527   are executed in turn, only the most recently saved state is restored
528   when an 'M72' is executed.
529  
530   * executing within a G-code subroutine. The state saved with 'M70'
531   within a subroutine behaves exactly like a local named parameter - it
532   can be referred to only within this subroutine invocation with an
533   'M72' and when the subroutine exits, the parameter goes away.
534  
535  A recursive invocation of a subroutine introduces a new call level.
536  
537  [[mcode:m71]]
538  == M71 Invalidate Stored Modal State
539  (((M71 Invalidate Stored Modal State)))
540  
541  Modal state saved with an 'M70' or by an 'M73' at the current call
542  level is invalidated (cannot be restored from anymore).
543  
544  A subsequent 'M72' at the same call level will fail.
545  
546  If executed in a subroutine which protects modal state by an 'M73', a
547  subsequent return or endsub will *not* restore modal state.
548  
549  The usefulness of this feature is dubious. It should not be relied upon as it might
550  go away.
551  
552  [[mcode:m72]]
553  == M72 Restore Modal State
554  (((M72 Restore Modal State)))
555  
556  <<mcode:m70-saved-state,Modal state saved with an 'M70'>> code can be
557  restored by executing an 'M72'.
558  
559  The handling of G20/G21 is specially treated as feeds are interpreted
560  differently depending on G20/G21: if length units (mm/in) are about to
561  be changed by the restore operation, 'M72 'will restore the distance
562  mode first, and then all other state including feed to make sure the
563  feed value is interpreted in the correct unit setting.
564  
565  It is an error to execute an 'M72' with no previous 'M70' save
566  operation at that level.
567  
568  The following example demonstrates saving and explicitely restoring
569  modal state around a subroutine call using 'M70' and 'M72'. Note that
570  the 'imperialsub' subroutine is not "aware" of the M7x features and can be
571  used unmodified:
572  
573  [source,{ngc}]
574  ----
575  O<showstate> sub
576  (DEBUG, imperial=#<_imperial> absolute=#<_absolute> feed=#<_feed> rpm=#<_rpm>)
577  O<showstate> endsub
578  
579  O<imperialsub> sub
580  g20 (imperial)
581  g91 (relative mode)
582  F5 (low feed)
583  S300 (low rpm)
584  (debug, in subroutine, state now:)
585  o<showstate> call
586  O<imperialsub> endsub
587  
588  ; main program
589  g21 (metric)
590  g90 (absolute)
591  f200 (fast speed)
592  S2500 (high rpm)
593  
594  (debug, in main, state now:)
595  o<showstate> call
596  
597  M70 (save caller state in at global level)
598  O<imperialsub> call
599  M72 (explicitely restore state)
600  
601  (debug, back in main, state now:)
602  o<showstate> call
603  m2
604  ----
605  
606  [[mcode:m73]]
607  == M73 Save and Autorestore Modal State
608  (((M73 Save and Autorestore Modal State)))
609  
610  To save modal state within a subroutine, and restore state on
611  subroutine 'endsub' or any 'return' path, program 'M73'.
612  
613  Aborting a running program in a subroutine which has an 'M73'
614  operation will *not* restore state .
615  
616  Also, the normal end ('M2') of a main program which contains an 'M73'
617  will *not* restore state.
618  
619  The suggested use is at the beginning of a O-word subroutine as in the
620  following example. Using 'M73' this way enables designing subroutines
621  which need to modify modal state but will protect the calling program
622  against inadvertant modal changes. Note the use of
623  <<gcode:predefined-named-parameters, predefined named parameters>> in
624  the 'showstate' subroutine.
625  
626  [source,{ngc}]
627  ----
628  O<showstate> sub
629  (DEBUG, imperial=#<_imperial> absolute=#<_absolute> feed=#<_feed> rpm=#<_rpm>)
630  O<showstate> endsub
631  
632  O<imperialsub> sub
633  M73 (save caller state in current call context, restore on return or endsub)
634  g20 (imperial)
635  g91 (relative mode)
636  F5 (low feed)
637  S300 (low rpm)
638  (debug, in subroutine, state now:)
639  o<showstate> call
640  
641  ; note - no M72 is needed here - the following endsub or an
642  ; explicit 'return' will restore caller state
643  O<imperialsub> endsub
644  
645  ; main program
646  g21 (metric)
647  g90 (absolute)
648  f200 (fast speed)
649  S2500 (high rpm)
650  (debug, in main, state now:)
651  o<showstate> call
652  o<imperialsub> call
653  (debug, back in main, state now:)
654  o<showstate> call
655  m2
656  ----
657  
658  [[mcode:m98-m99]]
659  == M98 and M99 ==
660  
661  The interpreter supports Fanuc-style main- and sub-programs with the
662  'M98' and 'M99' M-codes.  See <<ocode:fanuc-style-programs,Fanuc-Style
663  Programs>>.
664  
665  === Selectively Restoring Modal State
666  
667  Executing an 'M72' or returning from a subroutine which contains an
668  'M73' will restore <<mcode:m70-saved-state,*all* modal state saved>>.
669  
670  If only some aspects of modal state should be preserved, an
671  alternative is the usage of <<gcode:predefined-named-parameters,
672  predefined named parameters>>, local parameters and conditional
673  statements. The idea is to remember the modes to be restored at the
674  beginning of the subroutine, and restore these before exiting. Here is
675  an example, based on snippet of 'nc_files/tool-length-probe.ngc':
676  
677  [source,{ngc}]
678  ----
679  O<measure> sub   (measure reference tool)
680  ;
681  #<absolute> = #<_absolute>  (remember in local variable if G90 was set)
682  ;
683  g30 (above switch)
684  g38.2 z0 f15 (measure)
685  g91 g0z.2 (off the switch)
686  #1000=#5063 (save reference tool length)
687  (print,reference length is #1000)
688  ;
689  O<restore_abs> if [#<absolute>]
690      g90 (restore G90 only if it was set on entry:)
691  O<restore_abs> endif
692  ;
693  O<measure> endsub
694  ----
695  
696  [[mcode:m100-m199]]
697  == M100 - M199 User Defined Commands
698  (((M100 - M199 User Defined Commands)))
699  
700  ----
701  M1-- <P- Q->
702  ----
703  
704  * 'M1--' - an integer in the range of 100 - 199.
705  * 'P-' - a number passed to the file as the first parameter.
706  * 'Q-' - a number passed to the file as the second parameter.
707  
708  [NOTE]
709  After creating a new 'M1nn' file you must restart the GUI so it is aware
710  of the new file, otherwise you will get an 'Unkown m code' error.
711  
712  The external program named 'M100' through 'M199' (no extension and a capitol M)
713  is executed with the optional P and Q values as its two arguments.
714  Execution of the G code file pauses until the external program exits.
715  Any valid executable file can be used. The file must be located in the search
716  path specificed in the ini file configuration. See the 
717  <<sec:display-section,Display Section>> for more information on search paths.
718  
719  [WARNING]
720  Do not use a word processor to create or edit the files. A word processor
721  will leave unseen codes that will cause problems and may prevent a bash or
722  python file from working. Use a text editor like Gedit in Ubuntu or Notepad++
723  in other operating systems to create or edit the files.
724  
725  The error 'Unknown M code used' denotes one of the following
726  
727  * The specified User Defined Command does not exist
728  * The file is not an executable file
729  * The file name has an extension
730  * The file name does not follow this format M1nn where nn = 00 through 99
731  * The file name used a lower case M
732  
733  For example to open and close a collet closer that is controlled by a
734  parallel port pin using a bash script file using M101 and M102. Create two
735  files named M101 and M102. Set them as executable files (typically
736  right click/properties/permissions) before running LinuxCNC. Make sure the
737  parallel port pin is not connected to anything in a HAL file.
738  
739  .M101 Example File
740  ----
741  #!/bin/bash
742  # file to turn on parport pin 14 to open the collet closer
743  halcmd setp parport.0.pin-14-out True
744  exit 0
745  ----
746  
747  .M102 Example File
748  ----
749  #!/bin/bash
750  # file to turn off parport pin 14 to open the collet closer
751  halcmd setp parport.0.pin-14-out False
752  exit 0
753  ----
754  
755  To pass a variable to a M1nn file you use the P and Q option like this:
756  
757  ----
758  M100 P123.456 Q321.654
759  ----
760  
761  .M100 Example file
762  ----
763  #!/bin/bash
764  voltage=$1
765  feedrate=$2
766  halcmd setp thc.voltage $voltage
767  halcmd setp thc.feedrate $feedrate
768  exit 0
769  ----
770  
771  To display a graphic message and stop until the message window is closed
772  use a graphic display program like Eye of Gnome to display the graphic
773  file. When you close it the program will resume.
774  
775  .M110 Example file
776  ----
777  #!/bin/bash
778  eog /home/john/linuxcnc/nc_files/message.png
779  exit 0
780  ----
781  
782  To display a graphic message and continue processing the G code file 
783  suffix an ampersand to the command.
784  
785  .M110 Example display and keep going
786  ----
787  #!/bin/bash
788  eog /home/john/linuxcnc/nc_files/message.png &
789  exit 0
790  ----
791  
792  // vim: set syntax=asciidoc: