NC-Makros und Computercode: ein Vergleich mit Python
Variablen, Bedingungen, Schleifen und Unterprogramme in Python und in NC-Makrosyntax nebeneinander, mit den typischen Stolperfallen: Grad und Bogenmass, Klammern, Runden.
NC-Makrosprachen sind kleine Programmiersprachen. Sie wurden vor Jahrzehnten entworfen und wirken altmodisch, die Ideen dahinter sind aber dieselben wie in jeder modernen Sprache. Diese Seite stellt NC-Makros neben Python, eine Sprache, die oft im Unterricht verwendet wird, weil sie sich fast wie Englisch liest.
Python müssen Sie weder installieren noch lernen. Der Vergleich hat zwei Ziele. Wer Python oder eine ähnliche Sprache schon gesehen hat, kann sein Wissen direkt übertragen. Für alle anderen machen die Python-Zeilen die Struktur hinter der kryptischen NC-Syntax sichtbar.
Die NC-Beispiele verwenden die Syntax von Fanuc Macro B, weil das die verbreitetste Makrosprache ist. Die Details erklärt die Seite Fanuc Macro B. Die sprachunabhängigen Ideen stehen unter Grundlagen Programmablauf.
Variablen: Namen und Nummern
In Python hat eine Variable einen Namen. In einem Fanuc-Makro hat sie eine Nummer nach dem Zeichen #.
tiefe = 12.5
vorschub = 180
#100=12.5 (TIEFE)
#101=180 (VORSCHUB)Nummern merkt man sich schlecht. Schreiben Sie hinter jede Variable einen Kommentar, wenn sie ihren ersten Wert bekommt, und führen Sie eine Liste, welche Nummer was bedeutet. Neuere Fanuc-Steuerungen können Systemvariablen auch über Namen ansprechen, in Werkstattprogrammen sind Nummern aber nach wie vor die Regel.
Python entscheidet selbst, wo eine Variable gilt. Auf einer Fanuc-Steuerung entscheidet der Nummernbereich: #1 bis #33 sind lokal in einem Makro, ab #100 teilen sich alle Programme die Variablen.
Rechnen
Die Grundrechenarten sehen fast gleich aus. Der grosse Unterschied liegt bei den Klammern.
| Zweck | Python | Fanuc-Makro |
|---|---|---|
| Addieren, subtrahieren | a + b, a - b | #1+#2, #1-#2 |
| Multiplizieren, dividieren | a * b, a / b | #1*#2, #1/#2 |
| Klammern | (a + b) * c | [#1+#2]*#3 |
| Quadratwurzel | math.sqrt(a) | SQRT[#1] |
| Betrag | abs(a) | ABS[#1] |
| Sinus, Cosinus | math.sin(x), math.cos(x) | SIN[#1], COS[#1] |
| Arcustangens aus zwei Werten | math.atan2(y, x) | ATAN[#2]/[#1] |
| Kommentar | # Text | (TEXT) |
Im NC-Code sind runde Klammern Kommentare. Alles zwischen ( ) ignoriert die Steuerung. Gerechnet wird mit eckigen Klammern. #3=(#1+#2)*2 ist ein häufiger Anfängerfehler.
Grad und Bogenmass
Sinus und Cosinus erwarten in Python Winkel im Bogenmass. NC-Makros rechnen in Grad, weil Zerspaner in Grad denken. In Python wird zuerst umgerechnet:
x = radius * math.cos(math.radians(30))
#24=#18*COS[30]Wer eine Rechnung in Python oder einer Tabellenkalkulation testet und die Formel ins Makro übernimmt, sollte die Winkeleinheit prüfen. Eine vergessene Umrechnung ergibt Positionen, die plausibel aussehen und trotzdem falsch sind.
Vergleiche
| Bedeutung | Python | Fanuc-Makro |
|---|---|---|
| gleich | a == b | #1 EQ #2 |
| ungleich | a != b | #1 NE #2 |
| grösser | a > b | #1 GT #2 |
| grösser oder gleich | a >= b | #1 GE #2 |
| kleiner | a < b | #1 LT #2 |
| kleiner oder gleich | a <= b | #1 LE #2 |
| beide erfüllt | a and b | [...] AND [...] |
| mindestens eine erfüllt | a or b | [...] OR [...] |
Die Zeichen = < > sind in Fanuc-Bedingungen nicht erlaubt. Die Steuerung erwartet die Abkürzungen aus zwei Buchstaben.
IF und ELSE
Python kennzeichnet den Block, der zu einem if gehört, durch Einrücken. Für weitere Fälle gibt es elif, für den Rest else.
if tiefe > 30:
zustellung = 3
elif tiefe > 10:
zustellung = 5
else:
zustellung = 0
Fanuc Macro B kennt zwei Formen von IF. IF [...] THEN führt genau eine Anweisung aus. IF [...] GOTO n springt zum Satz mit der Satznummer Nn. ELSE und END IF gibt es nicht, deshalb wird dieselbe Logik mit Sprüngen gebaut:
IF[#100 GT 30] GOTO 10
IF[#100 GT 10] GOTO 20
#102=0 (KEIN SPANBRECHEN)
GOTO 30
N10 #102=3
GOTO 30
N20 #102=5
N30 (WEITER)Muss nur ein Wert gesetzt werden, ist die Kurzform einfacher:
#102=0
IF[#100 GT 10] THEN #102=5
IF[#100 GT 30] THEN #102=3Die Reihenfolge ist hier wichtig. Die letzte erfüllte Bedingung gewinnt, deshalb steht der strengste Fall am Schluss.
Schleifen
Eine while-Schleife in Python und eine WHILE-Schleife auf Fanuc funktionieren gleich. Python arbeitet mit Einrückung, Fanuc markiert das Ende mit END und einer Schleifennummer.
aktuell = 0
while aktuell < tiefe:
aktuell = aktuell + zustellung
#110=0
WHILE[#110 LT #100] DO1
#110=#110+#102
END1Für Pythons Zählschleife for bohrung in range(1, 7): gibt es keine direkte Entsprechung. Auf Fanuc schreiben Sie den Zähler selbst:
#120=1
WHILE[#120 LE 6] DO1
(BOHRUNG #120 BEARBEITEN)
#120=#120+1
END1Funktionen und Makroaufrufe
Eine Python-Funktion bekommt Werte als Parameter und kann ein Ergebnis zurückgeben. Ein Fanuc-Makro ist ein eigenes Programm, das mit G65 aufgerufen wird. Die Werte werden mit Buchstaben übergeben, und jeder Buchstabe landet in einer festen lokalen Variablen: X in #24, Y in #25, R in #18 und so weiter.
def tasche(laenge, breite, tiefe):
...
tasche(80, 50, 12)
G65 P9200 X80. Y50. Z12.
(in O9200: #24=80, #25=50, #26=12)Ein Makro kann keinen Wert direkt zurückgeben. Braucht das aufrufende Programm ein Ergebnis, schreibt das Makro es in eine gemeinsame Variable wie #150, und das Hauptprogramm liest es dort aus.
Leere Werte
In Python kann eine Variable None enthalten, also keinen Wert. Fanuc kennt dasselbe unter dem Namen leer oder Null-Variable. Eine lokale Variable ist leer, wenn ihr Buchstabe beim Aufruf nicht angegeben wurde. Damit lässt sich prüfen, ob ein Argument fehlt:
if tiefe is None:
raise ValueError("Tiefe fehlt")
IF[#26 EQ #0] THEN #3000=1 (TIEFE Z FEHLT)#0 ist eine Variable, die immer leer ist. Der Vergleich mit #0 fragt: Ist diese Variable leer? Leer und null sind verschieden: Eine leere Variable in einem Satz wie X#24 lässt die Steuerung die Adresse ganz weglassen, null fährt auf X0.
Runden
| Zweck | Python | Fanuc-Makro |
|---|---|---|
| Nachkommastellen abschneiden | int(a) | FIX[#1] |
| Auf ganze Zahl aufrunden | math.ceil(a) | FUP[#1] |
| Kaufmännisch runden | round(a) | ROUND[#1] |
Zwei Fallen. FUP rundet von null weg, FUP[-1.2] ergibt also −2, während Pythons math.ceil(-1.2) −1 liefert. Pythons round(2.5) ergibt 2, weil eine 5 auf die nächste gerade Zahl gerundet wird. Die NC-Steuerung rundet 2.5 auf 3 auf.
Beide Systeme speichern Zahlen binär. Ein Wert wie 0.002 × 1000 kann als 1.9999999 statt 2 herauskommen. Abschneiden ergibt dann 1. Zählen Sie vor FIX einen kleinen Betrag dazu, oder vergleichen Sie mit einer Toleranz statt auf exakte Gleichheit:
IF[ABS[#1-#2] LT 0.001] GOTO 50 (#1 UND #2 SIND GLEICH)Listen
Python kennt Listen für viele Werte: tiefen = [5, 10, 15]. Fanuc hat keine Listen, aber eine Variablennummer kann berechnet werden. #[100+#1] heisst: die Variable mit der Nummer 100 plus dem Wert von #1. Läuft #1 von 1 bis 3, liest das Programm nacheinander #101, #102 und #103. So speichern Makros Wertetabellen.
Was Makros können und Python nicht
Python läuft auf einem Computer und bewegt nichts. Ein Makro läuft in der Steuerung und hat direkten Zugriff auf die Maschine. Über Systemvariablen liest und schreibt es Werkzeugkorrekturen, Nullpunkte, aktuelle Positionen, aktive G-Codes, Uhrzeit und Stückzähler, und es kann die Maschine mit einem Alarm anhalten. Darin liegt die eigentliche Stärke der Makroprogrammierung.
Vollständiges Beispiel: Lochkreis
Derselbe Lochkreis wie auf der vorherigen Seite, einmal in Python und einmal als Fanuc-Makro.
import math
def lochkreis(mx, my, radius, anzahl, startwinkel):
schritt = 360 / anzahl
bohrung = 1
while bohrung <= anzahl:
winkel = startwinkel + (bohrung - 1) * schritt
x = mx + radius * math.cos(math.radians(winkel))
y = my + radius * math.sin(math.radians(winkel))
print(f"X{x:.3f} Y{y:.3f}")
bohrung = bohrung + 1
lochkreis(0, 0, 40, 6, 0)
Die Python-Version gibt sechs Koordinatenpaare aus. Die Fanuc-Version bewegt die Maschine:
O1000 (HAUPTPROGRAMM)
G90 G54 G17
G00 X0 Y0 Z50.
G98 G81 Z-10. R2. F150 K0 (BOHRZYKLUS SPEICHERN, KEINE BOHRUNG)
G65 P9100 X0 Y0 R40. H6. A0
G80
M30
O9100 (LOCHKREIS)
(X=#24 Y=#25 MITTELPUNKT, R=#18 RADIUS)
(H=#11 ANZAHL BOHRUNGEN, A=#1 STARTWINKEL)
#10=360/#11 (WINKELSCHRITT)
#12=1 (BOHRUNGSZAEHLER)
WHILE[#12 LE #11] DO1
#13=#1+[#12-1]*#10
#14=#24+#18*COS[#13]
#15=#25+#18*SIN[#13]
X#14 Y#15 (AKTIVER G81 BOHRT HIER)
#12=#12+1
END1
M99Zeile für Zeile gehen beide Programme dieselben Schritte. Nur die Schreibweise unterscheidet sich. Die nächste Seite erklärt jedes Fanuc-Element im Detail: Fanuc Macro B.