o-code.txt
1 [[cha:o-codes]] 2 3 = O Codes 4 5 O-codes provide for flow control in NC programs. Each block has an 6 associated number, which is the number used after O. Care must be taken 7 to properly match the O-numbers. O codes use the letter 'O' not the 8 number zero as the first character in the number like O100 or o100. 9 10 == Numbering 11 12 Numbered O codes must have a unique number for each subroutine, 13 .Numbering Example 14 ---- 15 (the start of o100) 16 o100 sub 17 (notice that the if-endif block uses a different number) 18 (the start of o110) 19 o110 if [#2 GT 5] 20 (some code here) 21 (the end of o110) 22 o110 endif 23 (some more code here) 24 (the end of o100) 25 o100 endsub 26 ---- 27 28 [[ocode:comments]] 29 == Comments 30 (((Comments))) 31 32 Comments on the same line as the O word should not be used as the behavior can 33 change in the future. 34 35 The behavior is undefined if: 36 37 * The same number is used for more than one block 38 * Other words are used on a line with an O- word 39 * Comments are used on a line with an O-word 40 41 [NOTE] 42 Using the lower case o makes it easier to distinguish from a 0 43 that might have been mistyped. For example o100 is easier to 44 see than O100 that it is not a 0. 45 46 [[ocode:subroutines]] 47 == Subroutines 48 (((Subroutines))) 49 50 Subroutines starts at 'Onnn sub' and ends at 'Onnn endsub'. The lines between 51 'Onnn sub' and 'Onnn endsub' are not executed until the subroutine is called 52 with 'Onnn call'. Each subroutine must use a unique number. 53 54 .Subroutine Example 55 ---- 56 o100 sub 57 G53 G0 X0 Y0 Z0 (rapid move to machine home) 58 o100 endsub 59 60 (the subroutine is called) 61 o100 call 62 M2 63 ---- 64 See <<gcode:g53,G53>> & <<gcode:g0,G0>> & <<mcode:m2-m30,M2>> sections for more 65 information. 66 67 .O- Return 68 Inside a subroutine, 'O- return' can be executed. This immediately 69 returns to the calling code, just as though 'O- endsub' was encountered. 70 71 .O- Return Example 72 ---- 73 o100 sub 74 (test if parameter #2 is greater than 5) 75 o110 if [#2 GT 5] 76 (return to top of subroutine if test is true) 77 o100 return 78 o110 endif 79 (this only gets executed if parameter #2 is not greater than 5) 80 (DEBUG, parameter 1 is [#1]) 81 o100 endsub 82 ---- 83 See the <<gcode:binary-operators,Binary Operators>> & <<gcode:parameters,Parameters>> sections for more information. 84 85 .O- Call 86 'O- Call' takes up to 30 optional arguments, which are passed to the 87 subroutine 88 as '#1', '#2' , ..., #N. Parameters from #N+1 to #30 have the same 89 value as in the 90 calling context. On return from the subroutine, the values of 91 parameters #1 through #30 (regardless of the number of arguments) will 92 be restored to the values they had before the call. Parameters #1 - #30 93 are local to the subroutine. 94 95 Because '1 2 3' is parsed as the number 123, the parameters must be 96 enclosed in 97 square brackets. The following calls a subroutine with 3 arguments: 98 99 .O- Call Example 100 ---- 101 o100 sub 102 (test if parameter #2 is greater than 5) 103 o110 if [#2 GT 5] 104 (return to top of subroutine if test is true) 105 o100 return 106 o110 endif 107 (this only gets executed if parameter #2 is not greater than 5) 108 (DEBUG, parameter 1 is [#1]) 109 (DEBUG, parameter 3 is [#3]) 110 o100 endsub 111 112 o100 call [100] [2] [325] 113 ---- 114 115 Subroutine bodies may not be nested. They may only be called after 116 they are defined. They may be called from other functions, and may call 117 themselves recursively if it makes sense to do so. The maximum 118 subroutine nesting level is 10. 119 120 Subroutines can change the value of parameters above #30 and those changes will 121 be visible to the calling code. Subroutines may also change the value of global 122 named parameters. 123 124 [[ocode:fanuc-style-programs]] 125 === Fanuc-Style Numbered Programs === 126 (((Subroutines, M98, M99))) 127 128 Numbered programs (both main and subprograms), the 'M98' call and 129 'M99' return M-codes, and their respective semantic differences are an 130 alternative to the rs274ngc subroutines described above, provided for 131 compatibility with Fanuc and other machine controllers. 132 133 Numbered programs are enabled by default, and may be disabled by 134 placing `DISABLE_FANUC_STYLE_SUB = 1` in the `[RS274NGC]` section 135 of the `.ini` file. 136 137 [NOTE] 138 139 Numbered main and subprogram definitions and calls differ from 140 traditional rs274ngc both in syntax and execution. To reduce the 141 possibility of confusion, the interpreter will raise an error if 142 definitions of one style are mixed with calls of another. 143 144 .Numbered Subprogram Simple Example 145 [source,{ngc}] 146 ---- 147 o1 (Example 1) ; Main program 1, "Example 1" 148 M98 P100 ; Call subprogram 100 149 M30 ; End main program 150 151 o100 ; Beginning of subprogram 100 152 G53 G0 X0 Y0 Z0 ; Rapid move to machine home 153 M99 ; Return from subprogram 100 154 ---- 155 156 .`o1 (Title)` 157 158 The optional main program beginning block gives the main program the 159 number `1`. Some controllers treat an optional following 160 parenthesized comment as a program title, `Example 1` in this example, 161 but this has no special meaning in the rs274ngc interpreter. 162 163 .`M98 P- <L\->` 164 165 Call a numbered subprogram. The block `M98 P100` is analogous to the 166 traditional `o100 call` syntax, but may only be used to call a 167 following numbered subprogram defined with `o100`...`M99`. An 168 optional 'L'-word specifies a loop count. 169 170 .`M30` 171 172 The main program must be terminated with `M02` or `M30` (or `M99`; see 173 below). 174 175 .`O-` subprogram definition start 176 177 Marks the start of a numbered subprogram definition. The block `O100` 178 is similar to `o100 sub`, except that it must be placed later in the 179 file than the `M98 P100` calling block. 180 181 .`M99` return from numbered subroutine 182 183 The block `M99` is analogous to the traditional `o100 endsub` syntax, 184 but may only terminate a numbered program (`o100` in this example), 185 and may not terminate a subroutine beginning with the `o100 sub` 186 syntax. 187 188 The `M98` subprogram call differs from rs274ngc `O call` in the 189 following ways: 190 191 * The numbered subprogram must follow the `M98` call in the program 192 file. The interpreter will throw an error if the subprogram precedes 193 the call block. 194 195 * Parameters `#1`, `#2`, ..., `#30` are global and accessible in 196 numbered subprograms, similar to higher-numbered parameters in 197 traditional style calls. Modifications to these parameters within a 198 subprogram are global modifications, and will be persist after 199 subprogram return. 200 201 * `M98` subprogram calls have no return value. 202 203 * `M98` subprogram call blocks may contain an optional L-word 204 specifying a loop repeat count. Without the L-word, the subprogram 205 will execute once only (equivalent to `M98 L1`). An `M98 L0` block 206 will not execute the subprogram. 207 208 In rare cases, the `M99` M-code may be used to terminate the main 209 program, where it indicates an 'endless program'. When the 210 interpreter reaches an `M99` in the main program, it will skip back to 211 the beginning of the file and resume execution at the first line. An 212 example use of an endless program is in a machine warm-up cycle; a 213 block delete program end `/M30` block might be used to stop the cycle 214 at a tidy point when the operator is ready. 215 216 .Numbered Subprogram Full Example 217 [source,{ngc}] 218 ---- 219 O1 ; Main program 1 220 #1 = 0 221 (PRINT,X MAIN BEGIN: 1=#1) 222 M98 P100 L5 ; Call subprogram 100 223 (PRINT,X MAIN END: 1=#1) 224 M30 ; End main program 225 226 O100 ; Subprogram 100 227 #1 = [#1 + 1] 228 M98 P200 L5 ; Call subprogram 200 229 (PRINT,>> O100: #1) 230 M99 ; Return from Subprogram 100 231 232 O200 ; Subprogram 200 233 #1 = [#1 + 0.01] 234 (PRINT,>>>> O200: #1) 235 M99 ; Return from Subprogram 200 236 ---- 237 238 In this example, parameter `#1` is initialized to `0`. Subprogram 239 `O100` is called five times in a loop. Nested within each call to 240 `O100`, subprogram `O200` is called five times in a loop, for 25 times 241 total. 242 243 Note that parameter `#1` is global. At the end of the main program, 244 after updates within `O100` and `O200`, its value will equal `5.25`. 245 246 [[ocode:looping]] 247 == Looping 248 (((Subroutines, Looping))) 249 250 The 'while loop' has two structures: 'while/endwhile', and 'do/while'. In 251 each case, the loop is exited when the 'while' condition evaluates to 252 false. The difference is when the test condition is done. The 'do/while' 253 loop runs the code in the loop then checks the test condition. The 254 'while/endwhile' loop does the test first. 255 256 .While Endwhile Example 257 ---- 258 (draw a sawtooth shape) 259 G0 X1 Y0 (move to start position) 260 #1 = 0 (assign parameter #1 the value of 0) 261 F25 (set a feed rate) 262 o101 while [#1 LT 10] 263 G1 X0 264 G1 Y[#1/10] X1 265 #1 = [#1+1] (increment the test counter) 266 o101 endwhile 267 M2 (end program) 268 ---- 269 270 .Do While Example 271 ---- 272 #1 = 0 (assign parameter #1 the value of 0) 273 o100 do 274 (debug, parameter 1 = #1) 275 o110 if [#1 EQ 2] 276 #1 = 3 (assign the value of 3 to parameter #1) 277 (msg, #1 has been assigned the value of 3) 278 o100 continue (skip to start of loop) 279 o110 endif 280 (some code here) 281 #1 = [#1 + 1] (increment the test counter) 282 o100 while [#1 LT 3] 283 (msg, Loop Done!) 284 M2 285 ---- 286 287 Inside a while loop, 'O- break' immediately exits the loop, and 'O- 288 continue' immediately skips to the next evaluation of the 'while' 289 condition. If it is still true, the loop begins again at the top. If 290 it is false, it exits the loop. 291 292 [[ocode:conditional]] 293 == Conditional 294 (((Subroutines, Conditional Loops))) 295 296 The 'if' conditional consists of a group of statements with the same 'o' number 297 that start with 'if' and end with 'endif'. Optional 'elseif' and 'else' conditions 298 may be between the starting 'if' and the ending 'endif'. 299 300 If the 'if' conditional evaluates to true then the group of statements 301 following the 'if' up to the next conditional line are executed. 302 303 If the 'if' conditional evaluates to false then the 'elseif' conditions are 304 evaluated in order until one evaluates to true. If the 'elseif' condition is 305 true then the statements following the 'elseif' up to the next conditional 306 line are executed. If none of the 'if' or 'elseif' conditions evaluate to true 307 then the statements following the 'else' are executed. When a condition is 308 evaluated to true no more conditions are evaluated in the group. 309 310 .If Endif Example 311 ---- 312 (if parameter #31 is equal to 3 set S2000) 313 o101 if [#31 EQ 3] 314 S2000 315 o101 endif 316 ---- 317 318 .If ElseIf Else EndIf Example 319 ---- 320 (if parameter #2 is greater than 5 set F100) 321 o102 if [#2 GT 5] 322 F100 323 o102 elseif [#2 LT 2] 324 (else if parameter #2 is less than 2 set F200) 325 F200 326 (else if parameter #2 is 2 through 5 set F150) 327 o102 else 328 F150 329 o102 endif 330 ---- 331 332 Several conditons may be tested for by 'elseif' statements until the 333 'else' path is finally executed if all preceding conditons are false: 334 335 .If Elseif Else Endif Example 336 ---- 337 (if parameter #2 is greater than 5 set F100) 338 O102 if [#2 GT 5] 339 F100 340 (else if parameter #2 less than 2 set F200) 341 O102 elseif [#2 LT 2] 342 F20 343 (parameter #2 is between 2 and 5) 344 O102 else 345 F200 346 O102 endif 347 ---- 348 349 [[ocode:repeat]] 350 == Repeat 351 (((Subroutines, Repeat Loop))) 352 353 The 'repeat' will execute the statements inside of the 354 repeat/endrepeat the specified number of times. The example shows how 355 you might mill a diagonal series of shapes starting at the present 356 position. 357 358 .Repeat Example 359 ---- 360 (Mill 5 diagonal shapes) 361 G91 (Incremental mode) 362 o103 repeat [5] 363 ... (insert milling code here) 364 G0 X1 Y1 (diagonal move to next position) 365 o103 endrepeat 366 G90 (Absolute mode) 367 ---- 368 369 [[ocode:indirection]] 370 == Indirection 371 (((Indirection))) 372 373 The O-number may be given by a parameter and/or calculation. 374 375 .Indirection Example 376 ---- 377 o[#101+2] call 378 ---- 379 380 .Computing values in O-words 381 For more information on computing values see the following sections 382 383 * <<gcode:parameters,Parameters>> 384 * <<gcode:expressions,Expressions>> 385 * <<gcode:binary-operators,Binary Operators>> 386 * <<gcode:functions,Functions>> 387 388 [[ocode:calling-files]] 389 == Calling Files 390 (((Calling Files))) 391 392 To call a separate file with a subroutine name the file the same as 393 your call and include a sub and endsub in the file. The file must be in the 394 directory pointed to by 'PROGRAM_PREFIX' or 'SUBROUTINE_PATH' in the ini file. 395 The file name can include *lowercase* letters, numbers, dash, and underscore 396 only. A named subroutine file can contain only a single subroutine definition. 397 398 .Named File Example 399 ---- 400 o<myfile> call 401 ---- 402 403 .Numbered File Example 404 ---- 405 o123 call 406 ---- 407 408 In the called file you must include the oxxx sub and endsub and the 409 file must be a valid file. 410 411 .Called File Example 412 ---- 413 (filename myfile.ngc) 414 o<myfile> sub 415 (code here) 416 o<myfile> endsub 417 M2 418 ---- 419 420 [NOTE] 421 The file names are lowercase letters only so 'o<MyFile>' is converted to 'o<myfile>' 422 by the interpreter. More information about the search path and options for the 423 search path are in the INI Configuration Section. 424 425 == Subroutine return values(((Return Values))) 426 427 Subroutines may optionally return a value by an optional expression at 428 an 'endsub' or 'return' statement. 429 430 .Return value example 431 ---- 432 o123 return [#2 *5] 433 ... 434 o123 endsub [3 * 4] 435 ---- 436 437 A subroutine return value is stored in the '#<_value>' 438 <<gcode:predefined-named-parameters, predefined named parameter>> , and 439 the '#<_value_returned>' predefined parameter is set to 1, to indicate 440 a value was returned. Both parameters are global, and are cleared just 441 before the next subroutine call. 442 443 [[ocode:errors]] 444 == Errors 445 (((O-Code Errors))) 446 447 The following statements cause an error message and abort the 448 interpreter: 449 450 - a `return` or `endsub` not within a sub defintion 451 - a label on `repeat` which is defined elsewhere 452 - a label on `while` which is defiĆed elsewhere and not referring to a `do` 453 - a label on `if` defined elsewhere 454 - a undefined label on `else` or `elseif` 455 - a label on `else`, `elseif` or `endif` not pointing to a matching `if` 456 - a label on `break` or `continue` which does not point to a matching `while` or `do` 457 - a label on `endrepeat` or `endwhile` no referring to a corresponding `while` or `repeat` 458 459 To make these errors non-fatal warnings on stderr, set bit 0x20 in 460 the `[RS274NGC]FEATURE=` mask ini option. 461 462 463 // vim: set syntax=asciidoc: