/ docs / src / gcode / o-code.txt
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: