Original-URL des Artikels: https://www.golem.de/news/anleitung-selbstgebaute-maschinen-steuern-1510-116331.html    Veröffentlicht: 01.10.2015 12:01    Kurz-URL: https://glm.io/116331

Anleitung

Selbst gebaute Maschinen steuern

Der Selbstbau von Werkzeugmaschinen war lange Zeit aufwendig und für Hobbybastler kaum zu stemmen. Doch in den vergangenen Jahren hat sich das geändert. Wir haben uns selbst an den Bau und Betrieb gewagt.

Dank Arduino und Co., Lego, preisgünstiger Metallbausätze und dem Maschinenpark im lokalen Makerspace ist der Bau einer eigenen Werkzeugmaschine selbst für Hobbybastler mittlerweile machbar - sei es nun ein 3D-Drucker, Lasercutter oder eine CNC-Fräse. Viele Konstruktionen und Baupläne stehen unter einer offenen Lizenz. Doch ohne Software bleibt jede Werkzeugmaschine leblos. Die Maschine selbst benötigt ein Firmware-Programm, um Motoren anzusteuern oder Sensoren auszuwerten. Und auch diese Firmware erwartet Steuerungskommandos, die per Software aus dem eigentlichen Objekt oder Vorbild erzeugt werden müssen. Wir haben uns angeschaut, wie wir mit Marlin als Firmware einen selbst gebauten Plotter steuern können, was es mit der Steuerung per G-Code auf sich hat und wie G-Code automatisch generiert werden kann. Auch wenn wir mit einem Plotter nur in zwei Dimensionen bleiben, die Grundlagen sind auch auf viele andere Arten von Maschinen anwendbar.

Offene CNC-Maschinen dank 3D-Druckern

Lange Zeit waren der Bau und Betrieb von rechnergesteuerten Maschinen (CNC) für Hobbybastler allenfalls ein Nischenthema. Wer sich überhaupt daran wagte, hatte üblicherweise einen akademischen oder entsprechenden beruflichen Hintergrund. Zu komplex schien es. Ließen sich die Materialien noch im Baumarkt beschaffen oder aus kaputten Druckern ausbauen, so erforderte die notwendige elektronische Steuerung und Programmierung doch fortgeschrittene Kenntnisse. Die Hürden schienen hoch.

Das änderte sich erst mit Adrian Bowyer und seinem ersten Reprap-3D-Drucker. Bowyer stellte Hardware wie auch Software unter offene Lizenzen. Bastler, die bislang nur einfache Automaten mit ihren Arduinos als Grundlage gebaut hatten, waren begeistert und wollten den Drucker nachbauen und verbessern. Maschinenbau als Hobby fand immer mehr Anhänger. Und bei 3D-Druckern blieb es nicht, es gibt wohl kaum eine Werkzeugmaschine, die es mittlerweile nicht in einer selbst gebauten wohnzimmertauglichen Variante gibt.

Trotz der Vielfalt an Entwürfen und Arten von Maschinen, der Eigenbau von 3D-Druckern ist im CNC-Hobbybereich immer noch die treibende Kraft. Dementsprechend existiert eine Vielzahl von Software und Elektronikkomponenten, die zwar für den Betrieb von 3D-Druckern konzipiert wurden, sich mehrheitlich aber für fast jede Art von Maschine eignen.

Erforderliche Elektronik in kompakter Form

Den eigentlichen Anlass für den Bau unseres Plotters lieferte ein Test der neu erschienenen Bam&Dice-Due-Maschinensteuerung. Sie besteht aus mehreren Bestandteilen. Die Basis bildet ein Arduino Due, der einen leistungsfähigen ARM-Cortex-M3-Mikrocontroller hat. Darauf aufgesteckt wird die Bam&Dice-Platine. Sie hat eine Vielzahl von Anschlüssen für Sensoren und Aktuatoren, Eprom-Speicher, aber auch ein WLAN-Modul auf Basis des populären ESP8266-1-Moduls. Optisch am auffälligsten sind aber die fünf Steckplätze für die Motortreiber. Die Motortreiber für die Schrittmotoren liegen jeweils als eigene Module vor. Teil des Paketes ist ein Controller mit einem LC-Display und einem Smartcard-Reader. Die Maschine kann damit auch ohne angeschlossenen Rechner betrieben werden.

Die Bam&Dice-Steuerung ist gedacht und eingerichtet für den Betrieb eines 3D-Druckers, wir wollten aber wissen, ob und wie sie sich auch für andere Arten von Maschinen umkonfigurieren lässt. Für unseren Plotter müssen wir lediglich zwei Schrittmotoren und einen Servo sowie zwei Endstopp-Schalter ansteuern. Wir müssen weder Thermistorsensoren auslesen noch einen Extruder mit seinem Heizelement kontrollieren oder ein Heizbett mit Strom versorgen.

Ein einzelner Arduino reicht selten

Damit wirkt eine solche komplette Maschinensteuerung eigentlich überdimensioniert für unsere Aufgabe. Doch sie erspart uns nicht nur viel Gefummel mit Breadboards und Verbindungskabeln, sondern ermöglicht als Dreingabe auch den computerlosen Betrieb. Der Aufwand, die notwendigen Ströme und Spannungen für die verschiedenen Komponenten bereitzustellen, sollte nicht unterschätzt werden. Gerade bei stärkeren (Schritt-)Motoren können unbedarfte Bastellösungen schnell zum Problem werden. Eine fertige Maschinensteuerung mit integrierten Wandlern erfordert zumeist nur einen einzelnen Stromzufluss und übernimmt den Rest für uns.

Offene Firmware auf offener Hardware

Es gibt aber noch einen anderen Grund, sich nach vorhandenen Maschinensteuerungen umzusehen, speziell nach solchen, wie es sie für Eigenbau-3D-Drucker gibt: Damit können wir eine fertige Firmware wie Marlin einsetzen, statt alles selbst programmieren zu müssen. Und zu programmieren gäbe es vieles. Bei der Motor- und Servosteuerung sowie Überwachung von Sensoren fängt es an, doch dazu bräuchten wir noch eine Schnittstelle, um G-Code entgegenzunehmen und umzusetzen. Doch Marlin unterstützt dazu auch noch eine vollständig menügeführte Steuerung per LCD und Drehknopf, das Laden von Steuerungsanweisungen von einer SD-Karte und vieles andere.

Ursprünglich entstand Marlin als Steuerfirmware für Ramps, einem Aufsatzboard für den Arduino Mega zur Steuerung des Reprap-3D-Druckers. Da das Design der Ramps-Platine unter einer offenen Lizenz steht, bildet es die Basis für eine Vielzahl von kompatiblen Nachbauten. Dazu zählt auch der Bam&Dice-Aufsatz. Am Pin-Layout ist die Verwandtschaft noch erkennbar. Der Unterschied liegt vor allem in der Unterstützung höherer Ströme sowie den deutlich leistungsfähigeren Motortreibern. Und Schrittmotoren können mit einem Substepping von bis zu 1/128 angesteuert werden.

Populär trotz Vorbehalten

Der große Erfolg von Marlin beruht nicht nur auf einer vergleichsweise großen Entwicklerbasis, sondern auch auf seiner Konfigurationsfähigkeit. Es unterstützt eine große Anzahl von Maschinensteuerungen und elektronischen Komponenten im 3D-Druckerbereich. Allerdings zieht das auch zunehmend Kritik auf sich, da sich der Code immer weiter aufbläht und die Konfiguration über einen wilden Mix an #define-Anweisungen und Variablenzuweisungen im Quellcode zunehmend aufwendiger wird. Da Marlin aber derzeit die größte Anzahl an Steuerungskommandos unterstützt, gilt es trotzdem als gute Wahl.

Marlin per Arduino IDE installieren

Auf dem Arduino Due als Teil des Bam&Dice-Paketes ist Marlin bereits eingespielt, der Hersteller empfiehlt allerdings, die jeweils aktuelle Version einzuspielen. Per USB wird dazu der Arduino über den Programmier-Port an einen Computer angeschlossen. Die Marlin-Variante des Herstellers kann nun über die Arduino-IDE kompiliert und auf den Arduino übertragen werden. Diese Softwarevariante unterscheidet sich ein wenig vom Original. Das Original wurde für den Atmel Atmega2560 geschrieben, der auf den Cortex-Mikrocontrollern des Due nur mit Änderungen läuft.

Nach dem Update führten wir über den Controller bereits erste Aktionen mit unserem Plotter aus. Alternativ funktioniert das auch über eine Druckersteuer-Software auf unserem Computer wie Prontointerface, das ebenfalls Bam&Dice beiliegt.

Marlin für den 2D-Betrieb umkonfigurieren

Für die Verwendung mit unserem Plotter müssen wir aber Marlin umkonfigurieren. Das heißt, den Quellcode zu bearbeiten. Die Arduino IDE ist dafür ausreichend. Die Konfigurationsdaten sind über mehrere Dateien verteilt, wobei nur eine tatsächlich für uns relevant ist. Die pins*.h-Dateien legen fest, welche GPIO-Pins des Arduino die jeweiligen Funktionen der Maschinensteuerung kontrollieren. Änderungen an dieser Datei greifen tief in die Steuerung ein und sollten nur erfolgen, wenn Anschlüsse der Steuerung zweckentfremdet werden sollen. Die nachfolgenden Einstellungen, die wir durchführen werden, stehen in Configuration.h. Weitere Einstellungsmöglichkeiten befinden sich in Configuration_adv.h, zumeist gelten sie aber allein für 3D-Drucker und eher exotische Elektronikkomponenten.

Die erste Änderung betrifft die Einstellung, wie viele Schritte der Schrittmotor machen muss, damit sich unser Stift einen Millimeter in eine Richtung bewegt. Der Wert muss nicht experimentell ermittelt werden, sondern lässt sich aus den Daten des Schrittmotors, dem Motortreiber sowie den Eigenschaften des jeweiligen Linearantriebs für den Stift errechnen.

Ein wenig Grundschulmathematik

In unserem Fall verwenden wir für die X- und Y-Richtung identische Gewindestangen, um den Stift zu bewegen. Drehen wir eine Mutter genau einmal vollständig auf diesem Gewinde, bewegt sie sich um eine definierte Länge. Den Wert müssen wir nicht messen; unter anderem dank deutscher Gründlichkeit ist diese Länge (die sogenannte Steigung) normiert. Für die von uns verwendeten M8-Gewinde beträgt der Anstieg 1,25 Millimeter. Als Nächstes müssen wir wissen, wie viele Schritte unsere, ebenfalls identischen, Schrittmotoren für eine volle Achsumdrehung der Gewinde benötigen. Das erfahren wir aus dem Datenblatt: 200. Aus dem oben ermittelten Anstieg sehen wir aber, dass der Motor für einen Millimeter gar nicht 200 Schritte ausführen muss. Daraus ergibt sich eine erste Rechnung: 200 / 1,25 = 160 Schritte für einen Millimeter.

Doch wir müssen noch den Motortreiber einkalkulieren. Per Jumper auf dem Bam&Dice-Board haben wir ein Substepping für den Schrittmotor von 1/128 eingestellt, um eine möglichst ruhige Bewegung zu erreichen. Die Marlin-Software muss also deutlich mehr Schritte an den Motortreiber senden. Unsere angepasste Rechnung lautet nun wie folgt: (200 * 128) / 1,25 = 20.480 Schritte. Statt nun auch noch den Rechenweg für zahnriemenbasierte Linearantriebe anzugeben, verweisen wir hier nur auf einen komfortablen Onlinerechner - er errechnet auch die Schrittdefinition für Gewindestangen und berücksichtigt auch Getriebe.

Die so ermittelten Werte werden DEFAULT_AXIS_STEPS_PER_UNIT zugewiesen. Dabei handelt es sich um eine Struktur, die neben den Werten für die X- und Y-Achse auch die für die von uns ungenutzte Z-Achse sowie den Extruder-Motor aufnimmt. Die letzten beiden Werte brauchen uns aber nicht zu interessieren und können in den Standardeinstellungen verbleiben:

Unterhalb der Schrittdefinition können auch die Werte für die Beschleunigung des Antriebs angegeben werden, in mm/s^2. Standardmäßig sind hier recht hohe Werte angegeben. Moderne Software zur Erzeugung von G-Code aus Druckvorlagen setzen diese Werte üblicherweise durch G-Code-Anweisungen dynamisch während des Drucks, weshalb dieser Wert bei 3D-Druckern eher uninteressant ist. Während des Baus unserer Maschine und dem direkten Zugriff während unserer Experimente war es aber deutlich praktischer, die Beschleunigung zu begrenzen. Wir trugen jeweils Werte von 120 mm/s^2 ein.

Marlin Grenzen setzen

Die weiteren Anpassungen, die wir vornehmen müssen, haben eigentlich einen positiven Grund. Marlin hat eine längere Entwicklungsgeschichte hinter sich, in der auch viel Wissen um die Fehler eingeflossen ist, die beim Betrieb einer Maschine, speziell eines 3D-Druckers, auftreten können. Dementsprechend hat Marlin eine Vielzahl von Sicherheitsmechanismen eingebaut. Das ist ebenfalls einer der Gründe dafür, dass eine fertige Lösung einer Eigenprogrammierung vorzuziehen ist.

So passen wir als Nächstes die Einstellung der zulässigen Druckfläche an, beziehungsweise in unserem Fall der Zeichenfläche. Durch unsere Konstruktion bedingt, setzen wir für X_MAX_POS = 115 ein (11,5 cm) und für Y_MAX_POS = 130 (13 cm). Schicken wir später Positionierungsanweisungen an die Steuerung, die über diesen Werten liegen, wird Marlin nur bis an diese Grenzen fahren.

Eine saubere Positionierung unseres Stifts setzt voraus, dass ein definierter Nullpunkt existiert. Nun können wir den Stift jedes Mal beim Maschinenstart von Hand positionieren und Marlin anweisen, diesen Punkt als Nullpunkt anzunehmen, doch das ist mühselig. Deshalb setzen wir an unserem Plotter je einen selbst gebauten Endstopp-Taster am Anfang jeder Achse ein. Berührt der Stift einen Taster, weiß Marlin, dass der Nullpunkt auf der betreffenden Achse erreicht ist. Somit können wir das sogenannte Auto-Homing benutzen. Marlin kann damit selbstständig den Nullpunkt anfahren und ermitteln.

Unser Eigenbau bricht mit Konventionen

Die Sache hat nur einen Haken: Reguläre Endstopp-Taster liefern normalerweise ein Signal, wenn sie nicht ausgelöst werden, und kein Signal, sobald sie ausgelöst werden. Das klingt zuerst unlogisch, ist aber eine wichtige Sicherheitsfunktion. Marlin stoppt automatisch, sobald ein Endstopp ausgelöst wurde, also kein Signal mehr anliegt, unabhängig von Steueranweisungen. Tritt nun im Betrieb ein Problem mit einem Endstopp auf - wie ein loses Kabel -, interpretiert Marlin diesen Signalverlust automatisch als ausgelösten Endstopp und verhindert womögliche größere Schäden an der Maschine.

In unserem Fall ist aber die Situation genau umgekehrt. Unsere Eigenbau-Endstopps senden ein Signal bei Berührung. Deshalb müssen wir die Signalausführung umkehren, die entsprechende Konfigurationsoption ist je nach Standpunkt richtig oder irreführend benannt: Virtuelles Aufheizen

Eine weitere Sicherheitsfunktion betrifft speziell 3D-Drucker. Teil eines FDM-3D-Druckers ist der Druckkopf mit seiner Schmelzeinheit (Hotend). Ihm wird mit Hilfe eines Motors das Druckmaterial (Filament) zugeführt. Wird versucht, diesen Motor anzusteuern, solange das Hotend kalt ist, kann das zu Schäden am Drucker führen. Deshalb verhindert Marlin Motorbewegungen nicht nur, solange das Hotend zu kalt ist, sondern sogar, wenn es davon ausgeht, dass der entsprechend Wärmesensor (Thermistor) kaputt oder nicht angeschlossen ist. Nun haben wir keinen Thermistor angeschlossen, der Schutz tritt also in Aktion. Leider gibt es keinen einfachen Weg, diesen Schutz abzuschalten. Allerdings gibt es eine Debug-Einstellung, um einen Thermistor vorzugaukeln, dieser Scheinthermistor hat die Nummer 998 und liefert stets 25 °Celsius:

Zu guter Letzt benutzen wir zum Heben und Senken des Stiftes einen Servo, deshalb müssen wir die Servo-Pins noch aktivieren. Die angegebene Zahl entspricht der Zahl der Servo-Anschlüsse auf dem Bam&Dice-Board:

Damit haben wir Marlin vorerst fertig konfiguriert. Der geänderte Quellcode wird wieder kompiliert und auf den Arduino übertragen. Jetzt können wir erste Experimente mit unserem Plotter durchführen.

Die Maschine kontrollieren per G-Code

Die Ansteuerung der Maschine erfolgt mit G-Code. Während der ersten Experimente sollten die entsprechenden Kommandos über eine serielle Schnittstelle übertragen werden - die im Falle der Arduino-basierten Bam&Dice-Steuerung über den gleichen USB-Port bereitgestellt wird wie zu dessen Firmware-Programmierung. Im eigentlichen Betrieb kann ein G-Code-Programm auch von einer SD-Karte abgespielt werden.

Deshalb können die nachfolgenden Aufrufe auch über die serielle Konsole der Arduino-IDE vorgenommen werden. Die einzustellende Bitrate für Marlin beträgt 115200 Baud. Praktischer ist aber die Verwendung einer 3D-Drucker-Steuerung wie Pronterface. Sie ermöglicht sowohl das direkte Absetzen von G-Code-Anweisungen, bietet aber eine einfache grafische Oberfläche, um Standardanweisungen mit einem Klick aufzurufen und auch Dateien mit G-Code-Anweisungen auszuführen. Diese Art von Programmen wird als Host-Programm bezeichnet.

G-Code erinnert an Assembler

Die Steuerung der Maschine per G-Code erfolgt ohne weitere Abstraktion: Ein G-Code-Programm beschreibt unmittelbar, welche Schritte die Maschine ausführen soll. Als Format kommt einfacher ASCII-Text zum Einsatz. Damit unser Plotter ein Quadrat der Größe 1x1 cm ausgehend von den Ursprungskoordinaten 0,0 malt, müssen wir folgende Befehle übermitteln:

Wer bereits mit Assembler gearbeitet hat, wird sich heimisch fühlen. G-Code hat vergleichbare Anfänge und entwickelte sich gleichfalls aus lochkartenbasierten Steuerungen. Die einfache Syntax und Semantik benötigt keine aufwendige Auswertung, die Steuerung läuft auch auf schwächerer Hardware. Im Laufe der Zeit hielten auch Elemente höherer Programmiersprachen in G-Code Einzug wie Schleifen, Variablen und Unterroutinen. Allerdings werden diese von den Firmware-Programmen im Selbstbaubereich nur sehr eingeschränkt oder gar nicht unterstützt. Eine ernsthafte Einschränkung ist das aber nicht unbedingt.

Schon anhand des kleinen Beispiels wird deutlich, warum es G-Code heißt: Die wichtigsten Anweisungen werden mit dem Buchstaben G eingeleitet, danach folgt eine ein- bis dreistellige Nummer für die Art der Anweisung. Je nach Anweisungen können darauf Parameter folgen, die jeweils ebenfalls mit festgelegten Buchstaben beginnen und eventuell von Zahlen begleitet werden.

Mit G-Code von A nach B

Die Bedeutung von G-Code-Anweisungen ist weitgehend normiert. G1 weist die Maschine an, das Werkzeug, also unseren Stift, präzise von einer Position an die gegebene Position zu bewegen. Für unseren Plotter sind für die neue Position zwei Koordinaten notwendig, zum Beispiel "X10 Y10". Der Buchstabe kennzeichnet die jeweilige Achse, die Zahl die Position in Millimetern. Im Falle eines 3D-Druckers oder einer Fräse käme noch die Z-Achse für die Höhe des Werkzeugs hinzu: "G1 X15.50 Y5.30 Z0.50". Wie hier ersichtlich, können auch Fließkommazahlen benutzt werden. Ein alternativer Befehl zum Bewegen des Werkzeugs ist G2, statt einer geraden Linie, wird das Werkzeug auf einer Kreisbahn bewegt. Für diesen Befehl sind nicht nur die Zielkoordinaten anzugeben, sondern auch der angenommene Kreismittelpunkt.

Einstellungen per G-Code

Ob diese Positionsdaten absolut zum Nullpunkt der Maschine interpretiert werden oder relativ zur aktuellen Position, kann ebenfalls per Anweisung festgelegt werden. Die Anweisung G90 legt die absolute Positionierung fest, "X10" heißt also 10 Millimeter vom Nullpunkt auf der X-Achse entfernt, unabhängig davon, wo sich das Werkzeug gerade befindet. Um eine relative Positionierung festzulegen, wird die Anweisung G91 abgesetzt. "X10" bedeutet dann 10 Millimeter von der aktuellen Position auf der X-Achse entfernt. Bisher haben wir die Maßangaben automatisch als Millimeter behandelt. Mit der Anweisung G21 tut das auch die Maschine, wer unbedingt mit Inch arbeiten will, erreicht das über G20.

Ein anderer nützlicher G-Code ist G28. Er weist die Maschine an, das Werkzeug selbstständig am Nullpunkt zu positionieren. Bei Marlin und anderen 3D-Drucker-basierten Firmware-Steuerungsprogrammen werden dabei die Endstopp-Schalter zur exakten Positionierung benutzt. Dabei müssen wir bei unserem Plotter beachten, dass G28 ohne Parameter alle Achsen auf den Nullpunkt positionieren will. Wir haben aber keine Z-Achse und auch keinen Z-Endstopp. Beim Versuch, das Werkzeug auf der Z-Achse zu positionieren, läuft Marlin in eine Endlosschleife. Deshalb müssen wir das Kommando immer mit expliziter Achsen-Angabe aufrufen: "G28 X Y".

Ein G-Code für jede Aufgabe

Das ist nur ein sehr kleiner Auszug aus der Liste der vielen G-Code-Befehle, teilweise haben wir auch optionale Parameter unterschlagen. Im Reprap-Wiki sind die Befehle und ihre Parameter weitgehend vollständig dokumentiert. Tatsächlich können wir mit den oben beschriebenen Anweisungen unseren Plotter aber bereits fast vollständig betreiben.

Es fehlt lediglich ein weiterer Befehl. Das Senken und Heben des Stiftes übernimmt ein Servo. Eine entsprechende Anweisung für Servos existiert nicht im Umfeld der normierten G-Befehle. Hier handelt es sich um eine maschinenspezifische Eigenschaft. Marlin unterstützt aber Servos über die Anweisung M280. Als Parameter ist einerseits die Angabe des betreffenden Servos über den Parameter P notwendig sowie der Winkel über den S-Parameter. Die Anweisung M280 P0 S120 stellt den Servo mit dem Index 0 auf 120 Grad. Wer Schäden beim Bau seiner Maschine vermeiden will, sollte übrigens beachten, dass Marlin angeschlossene Servos beim Maschinenstart standardmäßig auf 90 Grad stellt.

Kein G-Code-Programm kann alle knechten

Mit sehr wenigen Ausnahmen sind M-Anweisungen praktisch nicht normiert. Doch das ist nicht der einzige Grund dafür, dass vollständige G-Code-Programme zwischen Maschinen kaum ausgetauscht werden können. Das gilt sogar schon bei einem Werkzeugwechsel, zum Beispiel, wenn wir bei unserem Plotter den Stift mit einer Malbreite von 0,5 Millimetern gegen einen Filzstift mit einer 2 Millimeter dicken Spitze austauschen.

Zur Erinnerung: G-Code gibt exakt die Arbeitsschritte für die Maschine vor, die Maschine selbst hat keinerlei Vorstellung, was wir eigentlich erreichen wollen. Wollen wir mit unserem dünnen 0,5-Millimeter-Stift eine 1 Zentimeter lange und 2 Millimeter dicke Linie zeichnen, benötigen wir vier einzelne Striche direkt übereinander, je 0,5 Millimeter versetzt, mit dem dickeren Filzstift hingegen nur eine Linie. Deswegen müssen wir unterschiedlichen G-Code verwenden, das ist keine reine Optimierungsfrage. Wird der G-Code für den dünnen Stift mit dem dicken Stift angewendet, wird die vierte und letzte Linie mit 1,5 Millimeter Versatz gezeichnet, da der Stift aber dicker ist, wird auch die gezeichnete Linie deutlich dicker als beabsichtigt.

Noch deutlicher wird das beim Vergleich von Fräsmaschinen und 3D-Druckern. Soll ein Würfel erzeugt werden, tragen Fräsen das Material um den zu erzeugenden Körper ab. Ein 3D-Drucker hingegen trägt das Material des Würfels selbst Schicht für Schicht auf. Die erforderlichen Anweisungen allein zum Bewegen des jeweiligen Werkzeugs unterscheiden sich grundlegend.

Ein einzelnes Programm gibt es nicht

Grundsätzlich gilt also, dass bei der Erzeugung von G-Code die Arbeitsmethode, die jeweiligen Eigenheiten der Maschine und des Werkzeugs zu beachten sind. Deshalb sind ausgefeilte Programme zum Erzeugen von G-Code üblicherweise spezifisch für eine Arbeitsmethode und benötigen eine ganze Reihe von Angaben über den jeweiligen Maschinentyp und die Werkzeugeigenschaften.

Nichtsdestotrotz, in Grenzen ist G-Code für ähnlich funktionierende Maschinen durchaus konvertierbar. Der Unterschied zwischen unserem Plotter und einem Lasergravierer besteht in erster Linie im Aktivieren und Deaktivieren des Stiftes versus des Lasers. Das werden wir später ausnutzen.

Konvertierung per Inkscape

Von Hand G-Code zu schreiben ist möglich, sobald es aber über einfache geometrische Figuren hinausgeht, wird es aufwendig. Hier brauchen wir Hilfe. Unter Hobbyenthusiasten hat sich mittlerweile Inkscape als beliebtes Programm für 2- und 2,5-dimensionale CAD-Konstruktionen erwiesen. Das offene und erweiterbare Vektorgrafikprogramm kann in der aktuellen Version sogar direkt G-Code ausgeben. Leider ist die G-Code-Erweiterung tatsächlich zu professionell: Sie geht davon aus, dass das Werkzeug, beziehungsweise das Werkstück, über alle drei Achsen gesteuert werden kann. Die für unsere Maschine notwendige Ansteuerung eines Servos statt der Z-Achse lässt sich damit nicht konfigurieren.

Also machen wir uns auf die Suche nach alternativen Plugins oder Programmen - und sind überrascht. Für 3D-Drucker, Lasercutter, Fräs- und Graviermaschinen gibt es durchaus eine überraschend große Softwarebasis, für vermeintlich simple, selbst gebaute Plotter ist die Basis hingegen bemerkenswert dünn.

Mit Laser statt Stift

Fündig werden wir aber doch. Das Lasergravur-Plugin von J Tech Photonics ist zwar, wie der Name bereits sagt, für Lasergravierer gedacht, lässt sich aber auch für unseren Plotter nutzen. Es ist nicht nur prinzipiell konfigurierbar, sondern produziert auch hübsche Ergebnisse. Insbesondere werden Bögen in G3-Anweisungen für kreisförmige Werkzeugbewegungen übersetzt statt in viele kleine G1-Linien. Allerdings hat das Plugin eine Schwäche: Es generiert nur Umrisse. Ausgefüllte Flächen kann es nicht erzeugen. Die Installation verlangt keinen Aufwand, nach dem Download müssen die vier Dateien des Paketes in das Extensions-Verzeichnis von Inkscape kopiert werden.

Für die Arbeit mit dem Plugin müssen das zu zeichnende Objekt oder die Objekte in Inkscape erst in Pfade übersetzt werden. Auf die ausgewählten Pfade wird dann das Plugin angewendet. Der entsprechende Menüeintrag befindet sich unter Erweiterungen - Generate Gcode - J Tech Photonics Laser Tool. Im erscheinenden Dialog müssen wir zwei Einträge ändern. Den Wert in Laser ON Command ändern wir auf unsere Servo-Steuerung: M280 P0 S120, damit wird der Stift abgesenkt. Laser OFF Command ändern wir auf M280 P0 S90, um den Stift anzuheben. Dann muss noch der Speicherort für die erzeugte Datei mit dem G-Code-Programm unter Verzeichnis angegeben werden und der eigentliche Name der Datei bei Dateiname. Mit Apply wird die Erzeugung gestartet. Je nach Komplexität der Grafik kann das durchaus dauern, insbesondere bei vektorisierten Fotografien.

Verbesserungspotenzial im G-Code

Die erzeugte G-Code-Datei können wir bereits auf unsere Maschine laden und das Bild zu Papier bringen. Allerdings enthält der Code noch einige Unschönheiten, die schon am Anfang deutlich werden:

Die M280-Anweisungen haben jeweils zwei S-Parameter. Der zweite S-Parameter wird leider vom Plugin festcodiert eingefügt. Marlin interpretiert praktischerweise nur den ersten S-Parameter. Das muss allerdings nicht für jede Maschinensteuerung gelten.

Die Anweisungen G90 und G21 sorgen dafür, dass die Maschine immer absolut positioniert und als Einheit Millimeter verwendet wird. Was allerdings fehlt, ist ein G28-Kommando. Daher wird die Zeichnung irgendwo auf unserem Blatt gemalt, je nachdem, wo sich unser Stift gerade befindet und von der Maschine als Nullpunkt angenommen wird.

Neue G-Code-Anweisungen

Die beiden G0-Kommandos setzen zuerst die Bewegungsgeschwindigkeit für die nächste Bewegung. Der F-Parameter steht für Feed (zu Deutsch: Vortrieb). Danach wird der Stift an die angegebene Position bewegt. Die G0-Anweisung funktioniert analog zur früher beschriebenen G1-Anweisung, allerdings mit dem Unterschied, dass die Bewegung so schnell wie möglich erfolgen soll. Bei Marlin werden G0 und G1 identisch umgesetzt.

Die G4-Anweisung haben wir noch nicht vorgestellt. Sie pausiert die Ausführung des G-Codes. Das Plugin benutzt sie als Zeitspanne, in welcher der Laser seine volle Leistung aufbauen soll. Wir brauchen sie nicht, sie verlangsamt nur den Zeichenvorgang.

Das Plugin anpassen

Sowohl die fehlende G28-Anweisung als auch die überflüssigen Parameter wie Befehle lassen sich in einem Texteditor mit Suchen & Ersetzen einfügen beziehungsweise entfernen, per Script könnten wir das auch komplett automatisieren. Oder wir nutzen die Gelegenheit, einen etwas tieferen Blick in das Plugin zu werfen.

Die beiden Dateien des Plugins sind laser.inx und laser.py. Die erste Datei definiert Metadaten und den Export-Dialog, die zweite den eigentlichen Quellcode. Wir kopieren beide Dateien und benennen sie um in gplotter.inx und gplotter.py.

Zuerst bearbeiten wir die inx-Datei. In Zeile 3 und 4 setzen wir den Namen und den Identifier des Plugins neu. In der folgenden Zeile ändern wir den Verweis auf die abhängige Datei laser.py in gplotter.py. Die gleiche Änderung erfolgt auch in Zeile 28, dort wird festgelegt, dass diese Datei beim Aufruf des Menüpunktes ausgeführt werden soll.

Die weiteren Änderungen in dieser Datei sind eher kosmetischer Natur. In den Definitionen der Eingabeboxen für die Laser-an- und Laser-aus-Anweisungen in Zeile 8 und 9 ersetzen wir das Wort "Laser" durch "Pen" im Attribut _gui-text. Der vordefinierte Wert wird auf unsere Servo-Anweisungen gesetzt: "M280 P0 S120" und "M280 P0 S90". Zum Schluss geben wir noch einen Standardwert für den Verzeichniseintrag in Zeile 16 vor, um uns das Leben ein wenig bequemer zu machen.

Python-Code hacken für Anfänger

Die Änderungen im eigentlichen Python-Quellcode des Plugins beschränken sich ebenfalls auf reine Textänderungen, echte Kenntnisse von Python sind nicht erforderlich. In Zeile 86 wird eine Struktur namens default definiert. Sie enthält einen Eintrag mit dem Schlüssel "header", die Zeichenkette darin wird ergänzt durch unsere Nullpunktpositionierung "G28 X Y":

Jetzt folgt ein weiter Sprung zu Zeile 2414. Dort löschen wir den hartcodierten Parameter S0 aus der Zeichenkette.

Schließlich müssen wir zur Hauptroutine effect() des Plugins ganz am Ende der Datei. Dort wird die Struktur self.tools (Zeile 3160) definiert. Sie enthält den Eintrag "gcode before path", in der dortigen Zeichenkette werden der S-Parameter und dessen Wert eingefügt, auch die G4-Warteanweisungen finden sich hier. Diese Teile werden entfernt, so dass nur noch der Wert des Parameters aus dem Dialog eingesetzt wird:

Analog wird mit dem nachfolgenden Eintrag "gcode after path" verfahren, hier bleibt übrig:

Die beiden Dateien werden nun ebenfalls in das Extension-Verzeichnis von Inkscape kopiert. Nach einem Neustart des Programms befindet es sich im gleichen Untermenü wie das ursprüngliche Photonics-Plugin.

Wir können nun SVG-Zeichnungen in Inkscape zu G-Code für unseren Plotter konvertieren, allerdings bislang nur Umrisse. Doch auch Füllungen sind über Tricks möglich. Eine umfangreiche Anleitung dazu liefert das Evil-Mad-Scientist-Wiki. Die Anleitung bezieht sich zwar auf den Eggbot, sie lässt sich aber eins zu eins übertragen.

Fazit

Es gilt die Regel: Wer etwas lernen will, sollte erst einmal klein anfangen. Deshalb haben wir ganz bewusst mit einem Plotter angefangen, auch wenn sich der praktische Nutzen gegenüber einer Fräse oder einem Lasercutter in Grenzen hält.

Die wirkenden Kräfte bei einem Plotter sind gering, und er erfordert keine schwere Konstruktion. Vom Betrieb geht keine immanente Gefahr aus wie bei einem Lasercutter, und es sind nicht so viele verschiedenartige Komponenten wie bei einem 3D-Drucker erforderlich.

Der Bau der Maschine erwies sich tatsächlich als weitgehend unkompliziert, auch wenn manchmal etwas Improvisation erforderlich war. Die Elektrik war ebenfalls schnell erledigt. Die Anschlüsse des Bam&Dice-Boards sind zwar teilweise etwas fummelig, ansonsten erwies es sich aber als simpel und zuverlässig. Dieser Teil unseres Projekts war an einem Wochenende erledigt.

Unerwartet kompliziert und zeitaufwendig erwies sich hingegen der Softwareteil. Das erforderliche Wissen, um die Firmware Marlin an Eigenbauprojekte anzupassen, ließ sich noch recht leicht recherchieren. Software zur Generierung von G-Code für selbst gebaute Plotter hingegen mussten wir mit der Lupe suchen, auch Hilfestellungen dazu im Internet gibt es nicht allzu viele. Paradoxerweise - oder gerade deswegen - findet sich zu aufwendigeren Maschinen deutlich mehr Software zum Betrieb und auch Material zum Nachschlagen und Lernen. Gelegentlich dachten wir, dass wir doch besser mit einer Fräse oder einem 3D-Drucker angefangen hätten.

Dank quelloffener Software gelang es uns aber trotzdem, die Maschine in Betrieb zu nehmen und schließlich ansehnliche Zeichenergebnisse zu erhalten.

Der Selbstbau einer Werkzeugmaschine ist keine Hexerei. Handwerkliches Geschick und ein wenig Wille, auch einmal den Quellcode von Software anzufassen, sind für die erste eigene Maschine ausreichend.  (am)


Verwandte Artikel:
Android-App für Raspberry programmieren: werGoogelnKann (kann auch Java)   
(23.08.2017, https://glm.io/129559 )
Pinselplotter: Sylvias Watercolorbot malt mit Wasserfarben   
(18.07.2013, https://glm.io/100452 )
US Air Force: Biegbares Arduino-Board für die Uniform oder den Jetflügel   
(12.02.2018, https://glm.io/132721 )
Autosaw: Roboter helfen beim Möbelbauen   
(28.02.2018, https://glm.io/133060 )
Zeloslaser Cutter 2.0: Offener Lasercutter aus Deutschland   
(05.08.2015, https://glm.io/115587 )

© 1997–2019 Golem.de, https://www.golem.de/