1. Verwendung von O-Codes

O-codes provide for flow control in NC programs. Each block has an associated number, which is the number used after O. Care must be taken to properly match the O-numbers. O-codes use the letter O not the number zero as the first character in the number like O100 or o100. O-codes are also sometimes called o-words and these terms are interchangeable.

Anmerkung
Using the lower case o makes it easier to distinguish from a 0 that might have been mistyped. For example o100 is easier to see than O100 that it is not a 0.

2. Nummerierung

Nummerierte o-Codes müssen für jedes Unterprogramm eine eindeutige Nummer haben,

Beispiel für eine Nummerierung
(der Beginn von o100)
o100 sub
(beachten Sie, dass der if-endif-Block eine andere Nummer verwendet)
  (der Anfang von o110)
  o110 if [#2 GT 5]
    (etwas Code hier)
  (das Ende von o110)
  o110 endif
  (etwas mehr Code hier)
(das Ende von o100)
o100 endsub

3. Kommentare

Kommentare in der gleichen Zeile wie das o-Wort sollten nicht verwendet werden, da sich das Verhalten in Zukunft ändern kann.

Das Verhalten ist undefiniert, wenn:

  • Die gleiche Nummer für mehr als einen Block verwendet wird.

  • Andere Wörter in einer Zeile mit einem o-Wort verwendet werden.

  • Kommentare in einer Zeile mit einem o-Wort verwendet werden.

4. Subroutines

Unterroutinen beginnen mit oNNN sub und enden mit oNNN endsub. Die Zeilen zwischen oNNNsub und oNNN endsub werden nicht ausgeführt, bis das Unterprogramm mit oNNN call aufgerufen wird. Jede Subroutine muss eine eindeutige Nummer verwenden.

Beispiel für ein Unterprogramm
o100 unter
  G53 G0 X0 Y0 Z0 (Eilgang zum Referenzpunkt der Maschine)
o100 Endsub

(das Unterprogramm wird aufgerufen)
o100 call
M2

Weitere Informationen finden Sie in den Abschnitten G53, G0 und M2.

O- Return (engl. für Rücksprung oder Rückkehr)

Inside a subroutine, o- return can be executed. This immediately returns to the calling code, just as though o- endsub was encountered.

O- Return-Beispiel
o100 sub
  (Prüfung, ob Parameter #2 größer als 5 ist)
  o110 if [#2 GT 5]
    (Rückkehr zum Anfang des Unterprogramms, wenn der Test wahr ist)
    o100 return
  o110 endif
    (dies wird nur ausgeführt, wenn Parameter #2 nicht größer als 5 ist)
    (DEBUG, parameter 1 ist [#1])
o100 endsub

Weitere Informationen finden Sie in den Abschnitten Binäre Operatoren und Parameter.

O- Call (engl. für Aufruf)

o- Call takes up to 30 optional arguments, which are passed to the subroutine as #1, #2 , …, #N. Parameters from #N+1 to #30 have the same value as in the calling context. On return from the subroutine, the values of parameters #1 through #30 (regardless of the number of arguments) will be restored to the values they had before the call. Parameters #1 - #30 are local to the subroutine.

Because 1 2 3 is parsed as the number 123, the parameters must be enclosed in square brackets. The following calls a subroutine with 3 arguments:

O- Call-Beispiel
o100 sub
  (Prüfung, ob Parameter #2 größer als 5 ist)
  o110 if [#2 GT 5]
    (Rückkehr zum Anfang des Unterprogramms, wenn der Test wahr ist)
    o100 return
  o110 endif
    (dies wird nur ausgeführt, wenn Parameter #2 nicht größer als 5 ist)
    (DEBUG, Parameter 1 ist [#1])
    (DEBUG, Parameter 3 ist [#3])
o100 endif

o100 call [100] [2] [325]

Subroutine bodies may not be nested. They may only be called after they are defined. They may be called from other functions, and may call themselves recursively if it makes sense to do so. The maximum subroutine nesting level is 10.

Unterprogramme können den Wert von Parametern oberhalb von #30 ändern und diese Änderungen werden für den aufrufenden Code sichtbar sein. Unterprogramme können auch den Wert von global named parameters (d.h. Parameter, deren Namen mit dem Unterstrich "_" beginnen) ändern.

4.1. Fanuc-Style Numbered Programs

Nummerierte Programme (sowohl Haupt- als auch Unterprogramme), die M-Codes M98 call und M99 return und ihre jeweiligen semantischen Unterschiede sind eine Alternative zu den oben beschriebenen rs274ngc-Unterprogrammen, die aus Gründen der Kompatibilität mit Fanuc- und anderen Maschinensteuerungen bereitgestellt werden.

Nummerierte Programme sind standardmäßig aktiviert und können durch Einfügen von DISABLE_FANUC_STYLE_SUB = 1 in den Abschnitt [RS274NGC] der INI-Datei deaktiviert werden.

Anmerkung
Nummerierte Haupt- und Unterprogrammdefinitionen und -aufrufe unterscheiden sich sowohl in der Syntax als auch in der Ausführung vom traditionellen rs274ngc. Um Verwechslungen vorzubeugen, gibt der Interpreter eine Fehlermeldung aus, wenn Definitionen eines Stils mit Aufrufen eines anderen Stils vermischt werden.
Nummeriertes Unterprogramm Einfaches Beispiel
o1 (Beispiel 1) ; Hauptprogramm 1, "Beispiel 1"
M98 P100 ; Unterprogramm 100 aufrufen
M30 ; Hauptprogramm beenden

o100 ; Beginn des Unterprogramms 100
  G53 G0 X0 Y0 Z0 ; Eilgang zum Referenzpunkt
M99 ; Rückkehr aus Unterprogramm 100
o1 (Titel)

Der optionale Hauptprogramm-Anfangsblock gibt dem Hauptprogramm die Nummer 1. Einige Steuerungen behandeln einen optionalen, in Klammern gesetzten Kommentar als Programmtitel, "Beispiel 1" in diesem Beispiel, aber dies hat keine besondere Bedeutung im rs274ngc-Interpreter.

M98 P- <L->

Aufruf eines nummerierten Unterprogramms. Der Satz M98 P100 ist analog zur traditionellen o100 call-Syntax, darf aber nur zum Aufruf eines folgenden nummerierten Unterprogramms verwendet werden, das mit o100M99 definiert wurde. Ein optionales L-Wort legt eine Schleifenanzahl fest.

M30

Das Hauptprogramm muss mit M02 oder M30 (oder M99; siehe unten) beendet werden.

O- Beginn der Unterprogrammdefinition

Markiert den Beginn einer nummerierten Unterprogrammdefinition. Der Block o100 ist ähnlich wie o100 sub, außer dass er später in der Datei platziert werden muss als der aufrufende Block M98 P100.

M99 Rückkehr aus nummeriertem Unterprogramm

Der Block M99 ist analog zur traditionellen o100 endsub-Syntax, darf aber nur ein nummeriertes Programm beenden (o100 in diesem Beispiel) und darf nicht ein Unterprogramm beenden, das mit der o100 sub-Syntax beginnt.

Der Unterprogrammaufruf M98 unterscheidet sich vom rs274ngc `o call`in folgender Weise:

  • Das nummerierte Unterprogramm muss in der Programmdatei auf den M98-Aufruf folgen. Der Interpreter gibt einen Fehler aus, wenn das Unterprogramm vor dem Aufrufblock steht.

  • Die Parameter #1, #2, …, #30 sind global und in nummerierten Unterprogrammen zugänglich, ähnlich wie höher nummerierte Parameter in Aufrufen im traditionellen Stil. Änderungen an diesen Parametern innerhalb eines Unterprogramms sind globale Änderungen, die nach der Rückkehr des Unterprogramms bestehen bleiben.

  • M98"-Unterprogrammaufrufe haben keinen Rückgabewert.

  • M98"-Unterprogrammaufrufblöcke können ein optionales L-Wort enthalten, das eine Schleifenwiederholungszahl angibt. Ohne das L-Wort wird das Unterprogramm nur einmal ausgeführt (äquivalent zu M98 L1). Ein M98 L0-Satz führt das Unterprogramm nicht aus.

In seltenen Fällen kann der M-Code M99 zur Beendigung des Hauptprogramms verwendet werden, wo er ein Endlosprogramm anzeigt. Wenn der Interpreter ein M99 im Hauptprogramm erreicht, springt er an den Anfang der Datei zurück und setzt die Ausführung bei der ersten Zeile fort. Ein Beispiel für die Verwendung eines Endlosprogramms ist ein Aufwärmzyklus einer Maschine; ein M30-Satz zum Löschen des Programmendes könnte verwendet werden, um den Zyklus an einem sauberen Punkt zu beenden, wenn der Bediener bereit ist.

Vollständiges Beispiel für ein nummeriertes Unterprogramm
o1 ; Hauptprogramm 1
  #1 = 0
  (PRINT,X MAIN BEGIN: 1=#1)
  M98 P100 L5 ; Unterprogramm 100 aufrufen
  (PRINT,X MAIN END: 1=#1)
M30 ; Hauptprogramm beenden

o100 ; Unterprogramm 100
  #1 = [#1 + 1]
  M98 P200 L5 ; Aufruf des Unterprogramms 200
  (PRINT,>> o100: #1)
M99 ; Rückkehr aus Unterprogramm 100

o200 ; Unterprogramm 200
  #1 = [#1 + 0.01]
  (PRINT,>>>>> o200: #1)
M99 ; Rückkehr aus Unterprogramm 200

In diesem Beispiel wird der Parameter #1 auf 0 initialisiert. Das Unterprogramm o100 wird fünfmal in einer Schleife aufgerufen. Innerhalb jedes Aufrufs von "o100 wird das Unterprogramm o200 fünfmal in einer Schleife aufgerufen, also insgesamt 25-mal.

Beachten Sie, dass der Parameter #1 global ist. Am Ende des Hauptprogramms, nach den Aktualisierungen innerhalb von o100 und o200, wird sein Wert gleich 5.25 sein.

5. Looping

Die while-Schleife hat zwei Strukturen: while/endwhile, und do/while. In beiden Fällen wird die Schleife verlassen, wenn die while Bedingung als falsch bewertet wird. Der Unterschied besteht darin, wann die Testbedingung erfüllt ist. Die do/while Schleife führt den Code in der Schleife aus und überprüft dann die Testbedingung. Die while/endwhile Schleife führt zuerst den Test durch.

While Endwhile Beispiel
(eine Sägezahnform zeichnen)
G0 X1 Y0 (auf Startposition fahren)
#1 = 0 (Parameter #1 den Wert 0 zuweisen)
F25 (Vorschubgeschwindigkeit einstellen)
o101 while [#1 LT 10]
  G1 X0
  G1 Y[#1/10] X1
  #1 = [#1+1] (Inkrementieren des Testzählers)
o101 endwhile
M2 (Programm beenden)
Do While-Beispiel
#1 = 0 (Parameter #1 wird der Wert 0 zugewiesen)
o100 do
  (Fehlersuche, Parameter 1 = #1)
  o110 if [#1 EQ 2]
    #1 = 3 (weisen Sie dem Parameter #1 den Wert 3 zu)
    (msg, #1 wurde der Wert 3 zugewiesen)
    o100 continue (zum Anfang der Schleife springen)
  o110 endif
  (hier etwas Code)
  #1 = [#1 + 1] (Inkrementieren des Testzählers)
o100 while [#1 LT 3]
(msg, Schleife fertig!)
M2

Innerhalb einer while-Schleife wird mit o- break die Schleife sofort verlassen, und mit o- continue wird sofort zur nächsten Auswertung der while Bedingung übergegangen. Wenn sie immer noch wahr ist, beginnt die Schleife wieder von vorne. Wenn sie falsch ist, wird die Schleife verlassen.

6. Conditional

Die if Bedingung besteht aus einer Gruppe von Anweisungen mit der gleichen o Nummer, die mit if beginnen und mit endif enden. Optionale elseif und else Bedingungen können zwischen dem beginnenden if und dem endenden endif stehen.

Wenn die if Bedingung als wahr bewertet wird, dann wird die Gruppe von Anweisungen nach der if bis zur nächsten Bedingungszeile ausgeführt.

Wenn die if Bedingung als falsch bewertet wird, werden die elseif Bedingungen der Reihe nach ausgewertet, bis eine als wahr bewertet wird. Wenn die elseif Bedingung wahr ist, werden die auf die elseif folgenden Anweisungen bis zur nächsten Bedingungszeile ausgeführt. Wenn keine der if oder elseif Bedingungen als wahr ausgewertet wird, werden die auf die else folgenden Anweisungen ausgeführt. Wenn eine Bedingung zu wahr ausgewertet wird, werden keine weiteren Bedingungen in der Gruppe ausgewertet.

If Endif Beispiel
(if parameter #31 is equal to 3 set S2000)
o101 if [#31 EQ 3]
  S2000
o101 endif
If ElseIf else EndIf-Beispiel
(if parameter #2 is greater than 5 set F100)
o102 if [#2 GT 5]
  F100
o102 elseif [#2 LT 2]
(else if parameter #2 is less than 2 set F200)
  F200
(else if parameter #2 is 2 through 5 set F150)
o102 else
  F150
o102 endif

Mehrere Bedingungen können durch elseif Anweisungen getestet werden, bis der else Pfad schließlich ausgeführt wird, wenn alle vorangegangenen Bedingungen falsch sind:

If elseif else endif-Beispiel
(wenn Parameter #2 größer als 5 ist, F100 einstellen)
o102 wenn [#2 GT 5]
  F100
(wenn Parameter #2 kleiner als 2 ist, wird F200 gesetzt)
o102 elseif [#2 LT 2]
  F20
(Parameter #2 liegt zwischen 2 und 5)
o102 else
  F200
o102 endif

7. Repeat

Mit repeat werden die Anweisungen innerhalb von repeat/endrepeat die angegebene Anzahl von Malen ausgeführt. Das Beispiel zeigt, wie Sie eine diagonale Reihe von Formen fräsen könnten, beginnend an der aktuellen Position.

Beispiel mit repeat
(5 diagonale Formen fräsen)
G91 (Inkremental-Modus)
o103 repeat [5]
... (Fräscode hier einfügen)
G0 X1 Y1 (diagonale Bewegung zur nächsten Position)
o103 endrepeat
G90 (Absoluter Modus)

8. Indirektion

Die o-Zahl kann durch einen Parameter und/oder eine Berechnung angegeben werden.

Beispiel für Indirektion
o[#101+2] call
Berechnung von Werten in O-Wörtern

Weitere Informationen zur Berechnung von Werten finden Sie in den folgenden Abschnitten:

9. Calling Files

Um eine separate Datei mit einem Unterprogramm aufzurufen, geben Sie der Datei den gleichen Namen wie Ihrem Aufruf und fügen Sie ein sub und endsub in die Datei ein. Die Datei muss sich in dem Verzeichnis befinden, auf das PROGRAM_PREFIX oder SUBROUTINE_PATH in der INI-Datei verweist. Der Dateiname darf nur Kleinbuchstaben, Zahlen, Bindestriche und Unterstriche enthalten. Eine benannte Subroutinendatei kann nur eine einzige Subroutinendefinition enthalten.

Beispiel für eine benannte Datei
o<myfile> call
Beispiel für eine nummerierte Datei
o123 call

In der aufgerufenen Datei müssen die oxxx sub und endsub enthalten sein und die Datei muss eine gültige Datei sein.

Beispiel für eine aufgerufene Datei
(filename myfile.ngc)
o<myfile> sub
  (code here)
o<myfile> endsub
M2
Anmerkung
Die Dateinamen sind nur Kleinbuchstaben, so dass o<MyFile> vom Interpreter in o<myfile> umgewandelt wird. Weitere Informationen über den Suchpfad und Optionen für den Suchpfad finden Sie im Abschnitt zur INI-Konfiguration.

10. Subroutine return values

Unterprogramme können optional einen Wert durch einen optionalen Ausdruck in einer endsub oder return Anweisung zurückgeben.

Beispiel für einen Rückgabewert
o123 return [#2 *5]
...
o123 endsub [3 * 4]

Der Rückgabewert eines Unterprogramms wird im <_value> <gcode:predefined-named-parameters,predefined named parameter>> gespeichert, und der <_value_returned> vordefinierte Parameter wird auf 1 gesetzt, um anzuzeigen, dass ein Wert zurückgegeben wurde. Beide Parameter sind global und werden kurz vor dem nächsten Unterprogrammaufruf gelöscht.

11. Errors

Die folgenden Anweisungen führen zu einer Fehlermeldung und zum Abbruch des Interpreters:

  • ein "return" oder "endsub", außerhalb einer Unterdefinition

  • ein Label (benamte Markierung) für repeat, das an anderer Stelle definiert ist

  • ein Label für while, das an anderer Stelle definiert ist und sich nicht auf ein do bezieht

  • ein an anderer Stelle definiertes Label für if

  • ein undefiniertes Label bei else oder elseif

  • ein Label auf else, elseif oder endif, das nicht auf ein passendes if verweist

  • eine Bezeichnung für break oder continue, die nicht auf ein passendes while oder do verweist

  • eine Bezeichnung für endrepeat oder ``endwhile`, die nicht auf ein entsprechendes while oder repeat verweist

Um diese Fehler zu nicht-fatalen Warnungen auf stderr zu machen, setzen Sie Bit 0x20 bei der Option [RS274NGC]FEATURE= in mask ini.