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: