GRBL parallele Loop zu Hauptprogramm

Hallo Zusammen,

ich bin an eine Projekt dran, welches einen Nadelpräger ansteuern soll. Für die, die es nicht kennen:
Ein Nadelpräger ist ein System mit zwei Achsen(X und Y). Auf dem Schlutten sitzt ein Zylinder mit Kolben, welcher von einem Ventil mit Druckluft geschalten wird. Der Kolben ist hierbei die Nadel und vom Funktionsprinzip ist es vergleichbar mit einem Presslufthammer. Sprich: Man steuert das Ventil an und die Nadel fährt bzw. schlägt aus und trifft das Material. Dabei wird ein "Krater" hinterlassen. Wenn man sich nun vorstellt, die Nadel fährt während einer XY Bewegung ein- und aus, erhält man bsp. ein genageltes abbild der abgefahrenen Wege/Vectoren.

Damit die Nadel EINMAL ausfährt habe ich zum Testen(Cooling Output) den folgenden G-Code verwendet:
M8
G4 P0.010
M9
G4 P0.020
----> Also Ausgang setzen - 10ms warten(Nadel ist unten angekommen) - Ausgang absteuern - 20ms warten(Nadel ist wieder oben am Totpunkt angekommen.

Das klappt soweit nur ist mein Problem, dass dies während der Fahrt passieren soll.
Nun hätte ich folgenden Gedanken das Problem zu Lösen:

  • Es wird ein neuer M-Befehl für das ein- und ausschalten definiert, der nicht direkt auf einen Output gelinkt ist und in der GRBL Firmware nur als Flag dient. Bsp. M100 für TRUE und M101 für FALSE
  • Im GRBL benötige ich eine Loop, welche jedoch parallel zu allem anderen abgearbeitet wird - sprich bei einem Delay wird nicht alles andere verzögert. In dieser Loop soll mit delay die Wartezeit erzeugt werden und direkt der Cooling Ausgang angesteuert werden(ich glaube Output_13).
    Dies passiert jedoch nur, wenn M100 gesendet wurde und zwar so lang in Dauerschleife bis ein M101 eingelangt.

Ich habe viel an Programmier und Hardwareerfahrung sowie ebenso in der CNC Technik kenne ich mich aus. Jedoch bin ich mit dem Arduino nicht so gut vertraut um einschätzen zu können, ob dies so machbar ist bzw. wie man es angeht. Themen wie Multithreading lassensich ja nur über Umwege lösen.

Nun wären meine Fragen dazu folgende:

  • Was meint ihr zu der Idee? Ich würde ungern einen weiteren Arduino für diese Logik verwenden müssen.
  • Wie erstelle ich die parallel Loop
  • Wie legt man custom commands an(M100/M101)
  • Wie kann ich die Delays(aktuell 10ms AN und 20ms AUS) ebenso per Befehl senden um diese auch bei Bedarf abändern zu können? Hier wäre es cool die $$ Befehle zu erweitern oder eben auch einen M-Befehl bzw. zwei.

Im Prinzip stelle ich es mir vom G-Code her so vor wie man bsp. einen Laser ansteuern würde(EIN/AUS). Im Hintergrund wird jedoch mit gewissen Zeiten getaktet.

Bin gespannt was ihr dazu sagt und hoffe ihr könnt mir weiterhelfen - vielen Dank vorab!

Arduino macht eine Sache und nur die. Da gibt es nichts paralelles.
Wenn 2 Dinge (fast) gleichzeitig passieren sollen dann müssen sie schnell nacheinander passieren.

Grüße Uwe

Ist das nicht eher ein GRBL - Problem ?

Wie legt man custom commands an(M100/M101)

Das ist auf jeden Fall eine grbl - Frage...

Was Motoren generell angeht, kann ein Arduino bequem mehrere gleichzeitig und unabhängig ansteuern und gleichzeitig auf Serial lesen und schreiben.

Hi

Ein G-Code wird zeilenweise abgearbeitet - da gibt es kein 'Nebenher'.
Du müsstest den Nagler autark nageln lassen, sobald das Nagel-Signal anliegt, wird Dieser laufend angesteuert - Das kann auch ein zweiter Arduino übernehmen, eben Nagel raus, warte 30ms, Nagel rein, warte 30ms, ...
Wenn das Signal weggenommen wird fährt der 2.te Arduino den Nagel nach oben - also ohne Ansteuerung oben, mit Anstsuerung runter, rauf, runter, rauf, ...

MfG

Moin, ich glaube nicht, das das später gut aussieht. Die Nadelpräger die ich kenne platzieren die Prägungen auf einem Raster. Quasi wie Pixel auf einer Pixelmatrix.
Ich denke: "Deine Idee du überdenken musst!"

Raster fahren, prägen, Raster fahren, prägen, Raster fahren, prägen, usw.

Da wäre sogar HPGL - Code , die gute alte Plottersprache fast geigneter zum steurn, denn die arbeitet ausschliesslich mit den Befehlen zumKoordinaten anfahren und den Zuständen PEN UP (PU) / PEN DOWN (PD).
Wurde auch in Nadeldruckern so eingesetzt sowie als Anfangssprache bei CNC-Fräsen.

Hallo Zusammen,

danke für die zahlreichen Antworten und Ansätze!

Also im Grunde ist die Idee mit dem zweiten Arduino ganz gut. Dies löst das Problem, dass nichts gleichzeitig sondern nur Zeile für Zeile abgearbeitet werden kann. Jedoch müsste es in diesem Fall nicht tatsächlich gleichzeitig(multithread) sein. Es genügt dies so schnell zu machen, dass es scheint, als wäre es parallel.

HPGL Code scheidet leider aus, da die Grundbasis G-Code ist. Dies zu konvertieren ist wohl zu aufwändig.

Das angesprochene Rasterprägen ist mir nicht ganz klar. Die Präger die ich kenne, hämmern einfach während der Fahrt immer wieder runter(abhängig der Ein- und Ausschaltzeiten ergibt sich dann ein Punktabstand bzw. eine Auflösung).
Es werden direkt die Vektoren abgefahren somit wird ein Buchstab eines Textes auch wirklich als Vektor gefahren und nicht geplottert!

Im Grunde wäre ein zweiter Arduino die Lösung. Aber "schön" wäre es nicht. Ich scheitere aktuell daran, eine Schleife im GRBL Code einzufügen, in der die Logik(Ausgang setzten - Delay - Ausgang Rücksetzen - Delay) läuft OHNE, dass andere Prozess warten müssen und damit das System nur mehr stockend arbeitet.
Toll wäre etwas wie ein Delay, dass man auf Milisekundenbasis aufrufen kann, aber während dieses Delay kann der Arduino andere Dinge(wie Motoren verfahren - Schritte ausgeben) erledigen.

Vielen Dank bis dato. Ich hoffe ihr habt weitere Ansätze und Ideen für mich.

Toll wäre etwas wie ein Delay, dass man auf Milisekundenbasis aufrufen kann, aber während dieses Delay kann der Arduino andere Dinge(wie Motoren verfahren - Schritte ausgeben) erledigen.

Sobald du in den Basics BlinkWithoutDelay verstanden hast, solltest du dir dies selbst beantworten können, und dich zumindest an einen entsprechenden Test heranwagen.

Statt zu warten, merkt ein Sketch dass es noch zu früh ist, und macht also was anderes (oder nichts, so dass er sofort wieder im nächsten loop Durchlauf ist. ).

Hallo,

danke für den Tipp. Die Idee dahinter habe ich zwar verstanden, jedoch scheitere ich aktuell daran es ins GRBL zu bekommen.

Ich habe den Code so umgeschrieben, dass nun der Command "M8" nicht direkt den Cooling Output setzt sondern nur ein Flag. Mit diesem Flag steuere ich in der protocol.c in der main_loop() nun die Logik mit der Ein- und Ausschaltzeit.
Das klappt wunderbar, wenn ich nur den Befehl M8 sende(Ausgang wird nun getaktet) und mit M9 ist er wieder dauerhaft aus.

Wenn ich jedoch einen Verfahrbefehl(G0 beispielsweise) ausführe, während M8 aktiv ist, wird dieser träge bzw. fällt diese manchmal völlig aus.

Ich denke, ich muss eine Stelle finden, in der eine loop in Dauerschleife fährt und durch nicht verzögert wird(zumindest nicht merklich)

Das Delayproblem habe ich mit der GRBL eigenen Funktion:
void delay_sec(float seconds, uint8_t mode);

Diese hat folgendes Kommentar dabeistehen:
// Non-blocking delay function used for general operation and suspend features.

Hier sollte es sich um kein blockierendes Delay handeln. Es gibt gefühlt auch keine Blockade - somit sollte es wohl das richtige sein - äquivalent zum benannten Beispiel des "BlinkWithoutDelay".

Habt ihr dazu Ideen?
Vielen Dank

PS: Eine Frage zur millis() Funktion. Ich kann diese in GRBL nicht verwenden. Muss ich hier ein define nutzen, das mir nicht bekannt ist?

Das angesprochene Rasterprägen ist mir nicht ganz klar. Die Präger die ich kenne, hämmern einfach während der Fahrt immer wieder runter(abhängig der Ein- und Ausschaltzeiten ergibt sich dann ein Punktabstand bzw. eine Auflösung).

Ich wollte nochmal nachliefern was Rasterprägen ist:
https://images.app.goo.gl/gHMxJrVn8cv3PVFu7

Und hier kann man gut die verschiedenen Arten sehen:
https://images.app.goo.gl/ivkRKWzWqNcnKeX28