Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Ablauf für Fräsmaschine programmieren (https://www.delphipraxis.net/121392-ablauf-fuer-fraesmaschine-programmieren.html)

100nF 26. Sep 2008 17:36


Ablauf für Fräsmaschine programmieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

Ich arbeite seit einiger Zeit an einer Platinenfräsmaschine, also ich will selbst eine kleine Fräsmaschine bauen, mit der man Platinen fräsen kann. Erstens geht es mir darum, dass ich dann in Zukunft meine Platinen ohne grossen Aufwand und vor allem ohne "Sauerei" (wie beim Ätzen) herstellen kann. Und der Lerneffekt ist auch eine positive Nebenwirkung :)
Die Elektronik für eine Achse ist schon vorhanden und funktioniert. Mechanisch hab ich bisschen angefangen, jedoch noch lange nicht fertig^^

Der gesamte Ablauf soll von meinem Delphi-Programm gesteuert werden. An die Hardware kann ich per RS232 die Position angeben, welche angefahren werden muss und mit welcher Geschwindigkeit. Dazu habe ich bereits Prozeduren geschrieben:

Delphi-Quellcode:
if WaitForReady then // eine Schlaufe, welche so lange läuft bis die Fräsmaschine bereit ist
  PositionSenden(x, y, z, speed); // x, y, z sind Integer-Werte für die 3 Achsen, speed ist auch eine Ingeger und gibt die Geschwindigkeit an
Das funktioniert soweit ganz gut.
Nun soll das aber ziemlich vollautomatisch ablaufen, will ja nicht jede Position von Hand eingeben :D

Also das Layout habe ich als Bitmap, ein Beispiel wie das Aussehen könnte findet Ihr im Anhang.
Achtung: Jedes Pixel stellt einen Schritt für die Achsen X und Y dar! d.h. es findet keine Umrechnung statt von Pixel zu Schritte.
Die Achse Z kann vollkommen vernachlässigt werden, die wird dann kein grosses Problem mehr. Ebenso die Geschwindigkeit.

Alles was schwarz ist muss nun weggefräst werden. Die Breite des Fräsers werde ich in Pixel angeben, diese kann natürlich variieren! Der Fräser soll nun sozusagen das ganze Bitmap abfahren und an keiner Stelle 2x drüber fahren. Ausserdem soll der Vorgang möglichst effizient gestaltet werden, damit viel Zeit eingespart werden kann. Man muss auch beachten dass die Übertragung der Position relativ viel Zeit beansprucht und somit nur so häufig wie nötig gebraucht werden soll, was bedeutet dass immer möglichst lange Strecken gefahren werden müssen.

Die einzige Idee die ich bis jetzt hatte, war dass man ev. die Schwarzen Flächen in einzelne Vierecke aufteilt und die dann nacheinander gefräst werden. Allerdings weiss ich nicht wie ich das genau machen kann...

Hättet Ihr vielleicht irgendwelche Vorschläge?
Vielleicht hat shcon jemand Erfahrung mit sowas?

Wäre für jede Hilfe sehr dankbar!

MFG
urbanbruhin

Namenloser 26. Sep 2008 18:24

Re: Ablauf für Fräsmaschine programmieren
 
Ich kenn mich jetzt mit Platinendesign nicht wirklich aus, aber wenn du sagst, dass ein Pixel einem "Positionsschritt" des Fräsers entspricht, wieso arbeitest du dann nicht einfach das ganze Bitmap Zeilenweise (oder in Serpentinen) ab? Wenn der aktuelle Pixelwert von weiß auf schwarz wechselt, bewegst du die Fräse nach unten, und umgekehrt.

Bitte entschuldige mich, wenn ich deine Frage falsch verstanden habe.

haentschman 26. Sep 2008 18:50

Re: Ablauf für Fräsmaschine programmieren
 
Hallo...

Meine Gedanken zum Thema. :wink:

1. die Fräsergröße kann nur maximal so groß sein wie die kleinste Lücke oder der kleinste Radius in Ecken.
2. die Bahnen, welche der Fräser zieht, müssen überlappen. z.B. bei einer Fräserbreite von 3 "Pixel" einen Versatz von 2 Pixeln damit nichts stehen bleibt (denn ich bezweifle, daß du die Positionen auf ein 1000stel genau hinkriegst :wink: )
3.
Zitat:

die Schwarzen Flächen in einzelne Vierecke aufteilt
Zitat:

bewegst du die Fräse nach unten, und umgekehrt.
...aber der Fräser ist rund :gruebel: Beim nur "Hoch und Runter würden Ecken stehen bleiben...
...um eine saubere Kante zu haben muß der Fräser an der Kante entlanglaufen.

4. Als Lösungsansatz fällt mir nur ein:
- Regionen für die schwarze Farbe (so ähnlich wie eine Maske in der Bildbearbeitung)
- die Region am Rand abfahren
- dann den Rest...
-> nächste Region usw.

:hi:

100nF 26. Sep 2008 19:24

Re: Ablauf für Fräsmaschine programmieren
 
@haentschman
du hast den nagel auf dem kopf getroffen :mrgreen:

also eigentlich stimmt alles was du schreibst.
die fräserbreite ist natürlich immer kleiner als die kleinste lücke, doch ich werde ev. ja auch verschiedene fräser benutzen, z.B. um bei "gröberen" Platinen wo die kleinsten lücken grösser sind Zeit sparen zu können. ich würde dann halt mal mit verschiedenen fräsern linien fräsen und die breite danach ausmessen. dann in pixel bzw. Schritte umrechnen und im programm eingeben.
das mit dem überlappen stimmt auch, wobei ich die überlappungsbreite auch angeben möchte in pixel. da werde ich dann natürlich durch versuchen möglichst gute werte ermitteln um auch wieder zeit sparen zu können.

ich bin mir nicht ganz sicher ob ich dein lösungsvorschlag richtig verstanden habe. das mit dem "in regionen aufteilen" klingt schonmal nicht schlecht, aber ich glaube das ist das selbe wie ich meinte mit "in einzelne vierecke aufteilen" ?!
oder hast du das anders gemeint?

das problem wäre dann aber, WIE teile ich die schwarzen flächen in einzelne regionen auf?
ach ja, ich hab übrigens gerade gemerkt dass bei dem beispielbild alles schwarze nur aus einer fläche besteht, also alles zusammenhängt. ich denke mal man könnte theoretisch damit rechnen dass es auch bei grösseren platinen so ist, aber bin mir da noch nicht ganz sicher :D

EDIT:
noch zu NamenLozer:
soweit war ich auch schon, doch diese vatiante hat viele nachteile:
- der fräser fährt unnötig über flächen die gar nicht gefräst werden müssen
- da die konturen nicht rundherum in einer linie abgefahren werden wird es wohl keine schönen abgrenzungen zwischen gefrästen und nicht gefrästen flächen geben. es wird einfach nicht schön aussehen...
- hat bestimmt noch weitere nachteile...^^

messie 26. Sep 2008 19:27

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Zitat von NamenLozer
Ich kenn mich jetzt mit Platinendesign nicht wirklich aus, aber wenn du sagst, dass ein Pixel einem "Positionsschritt" des Fräsers entspricht, wieso arbeitest du dann nicht einfach das ganze Bitmap Zeilenweise (oder in Serpentinen) ab? Wenn der aktuelle Pixelwert von weiß auf schwarz wechselt, bewegst du die Fräse nach unten, und umgekehrt.

Ein guter Vorschlag. Nur nimmst Du immer n zeilen gleichzeitig, n ist die Breite Deines Fräsers(jeweilige Werte über die Zeilen mitteln). Wenn Weiss kommt, nimmst Du den Fräser hoch, arbeitest also alle Zeilen der Reihe nach ab.
Das ist am einfachsten. Es gibt auch Vektormodelle, nach denen das geht. Eine Einteilung in Quadrate würde ich nicht empfehlen, wenn überhaupt, dann in Dreiecke. Aber die Abarbeitung nach Zeilen ist das Einfachste. Hier geht es ja nicht um Geschwindigkeit oder maximale Präzision...

Grüße, Messie

Edit: warum gibt es das rote Fenster nicht mehr????

100nF 26. Sep 2008 19:34

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Hier geht es ja nicht um Geschwindigkeit oder maximale Präzision...
naja...ok geschwindigkeit ist nicht alles, doch ich denke die ersparnis von einem richtig guten "ablauf" gegenüber der zeilen-methode wäre riesig. die schrittmotoren sind nunmal nicht die schnellsten :D
und präzision...sobald ich mit SMD-Bauteilen beginne kommt das thema schon einiges näher, die dinger sind echt schon sehr sehr klein. ich weiss zwar nicht ob ich das so genau hinbekomme, doch dieses ziel strebe ich eigentlich schon an.

übrigens werde ich die mechanik etwa so konstruieren dass ein schritt etwa 0,01 bis 0,02mm entspricht. klar, in der praxis heisst das dann nicht dass ich auf diesen wert genau fräsen kann.

ausserdem hab ich mir shcon überlegt, falls das teil dann mal richtig gut funktioniert, bisschen profit daraus zu schlagen. d.h. ich könnte für andere leute einen günstigen platinenservice bereitstellen, ich mein sonst zahlt man ja ein vermögen um mal eben einen prototypen ätzen zu lassen. dann käme auch die zeit wieder in den vordergrund, wie lange der fräser für eine platine braucht...

ach ja, @ messie
warum in dreiecke aufteilen?! versteh ich jetzt nicht ganz :D

messie 26. Sep 2008 19:39

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Zitat von urbanbruhin
soweit war ich auch schon, doch diese variante hat viele nachteile:
- der fräser fährt unnötig über Flächen die gar nicht gefräst werden müssen

Ja, aber das ist das Einfachste. Für alles andere steigt der Aufwand riesig.
Zitat:

Zitat von urbanbruhin
- da die Konturen nicht rundherum in einer linie abgefahren werden wird es wohl keine schönen Abgrenzungen zwischen gefrästen und nicht gefrästen Flächen geben. Es wird einfach nicht schön aussehen...

Eine Platine muss nicht unbedingt schön aussehen. Schön, wenn sie funktioniert. Für das schöne Aussehen arbeitet man mit Vektorgrafik. Der Stift, der das Bild malt, kann auch den Fräser steuern. Das ist aber - wie schon gesagt - weitaus aufwändiger.
Zitat:

Zitat von urbanbruhin
- hat bestimmt noch weitere Nachteile...

Besonders den, dass es effizient ist :). Natürlich kannst Du das perfektionieren, wenn Du den Aufwand investieren kannst und willst.

Grüße, Messie

Edit: komisch, warum gibt es denn das rote Fenster nicht mehr? ist das abgeschafft?
Zitat:

Zitat von urbanbruhin
ach ja, @ messie
warum in dreiecke aufteilen?! versteh ich jetzt nicht ganz

Dreiecke sind die kleinste geometrische stabile Einheit. Auf diese Weise kann man mit den wenigsten Rechenschritten die Außenpunkte einer Fläche bestimmen (Triangulation, hat Gauss damals zur Vermessung eingesetzt). Wenn Du es also besonders genial programmieren willst, wirst Du mit Triangulation weniger Rechenschritte benötigen. Übrigens beruhen alle Positionierungsanlagen auf der Triangulation, angefangen von GPS bis zu Laser-Bahnenschweißanlagen in der Industrie.[/quote]

haentschman 26. Sep 2008 19:45

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

die Abarbeitung nach Zeilen ist das Einfachste.
dann sind zwar die horizontalen Kanten gerade, aber die vertikalen Kanten haben Zacken oder ? :gruebel: (wg. Rundung)

das mit den Regionen meinte ich wie folgt:
- in Bildbearbeitung z.B. kannst du eine Maske um eine bestimmte Farbe erzeugen (Magic Mask oder so...)
- die Maske / der jeweilige Maskenpunkt entspricht dann Deiner Kante der entsprechenden Farbe.
...wie man das mit Delphi hinkriegt :gruebel: , es wird aber gehen.
- die Maske wäre dann Pixelgenau.
- du müßtest dann in alle 3 möglichen Richtungen den Abstand zur Kante berechnen und den Fräser entsprechend positionieren. (links, rechts, geradeaus)
- wenn Deine Maske / Kante geschlossen ist, kommst du logischerweise wieder am Ausgangspunkt an und gehst in die nächste "Region" wenn vorhanden.

...das wird ein schönes Stück Arbeit. 8)

100nF 26. Sep 2008 19:48

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Zitat von messie
Zitat:

Zitat von urbanbruhin
soweit war ich auch schon, doch diese variante hat viele nachteile:
- der fräser fährt unnötig über Flächen die gar nicht gefräst werden müssen

Ja, aber das ist das Einfachste. Für alles andere steigt der Aufwand riesig.

unser kursleiter im kurs "SPS programmieren" hat immer gesagt: warum eine funktion weniger im programm einbauen? warum das programm möglichst kurz halten? die weiteren funktionen kosten ja nichts, es ist gratis!
ok, es kostet zeit, doch da das mein hobby ist ist das eher unwichtig.

Zitat:

Zitat von messie
Zitat:

Zitat von urbanbruhin
- da die Konturen nicht rundherum in einer linie abgefahren werden wird es wohl keine schönen Abgrenzungen zwischen gefrästen und nicht gefrästen Flächen geben. Es wird einfach nicht schön aussehen...

Eine Platine muss nicht unbedingt schön aussehen. Schön, wenn sie funktioniert. Für das schöne Aussehen arbeitet man mit Vektorgrafik. Der Stift, der das Bild malt, kann auch den Fräser steuern. Das ist aber - wie schon gesagt - weitaus aufwändiger.

jo klar, aber wie ich schon erwähnte wären SMD-Platinen das ziel, und da kann ich jede Präzision gebrauchen...(unschönheit wäre in diesem Fall ja auch Ungenauigkeit)

Zitat:

Zitat von messie
Zitat:

Zitat von urbanbruhin
- hat bestimmt noch weitere Nachteile...

Besonders den, dass es effizient ist :). Natürlich kannst Du das perfektionieren, wenn Du den Aufwand investieren kannst und willst.

effizient beim programmieren, ja! aber nicht beim fräsen später dann xD

diese Idee hatte ich eben auch schon, doch sie gefällt mir einfach nicht.
Bekanntlich bringen mehrere Köpfe ja mehr Ideen, also hab ich gedacht ich frag hier im Forum mal nach, könnte gut sein dass jemand eine sehr gute Idee hat!

EDIT: wiedermal kein roter Kasten...:)
@haentschman
OK ich begreifs zwar noch nicht ganz (bin grafikmässig nicht sehr begabt^^) doch ich werde mal schauen ob ich mir das irgendwie selbst erklären kann...mal bisschen grübeln :gruebel:

übrigens danke schonmal für eure Antworten, dachte nicht dass das so schnell geht! :shock:

messie 26. Sep 2008 19:50

Re: Ablauf für Fräsmaschine programmieren
 
Weil es das rote Fenster jetzt nicht mehr gibt: Anwort als Edit im Post darüber.

100nF 26. Sep 2008 20:02

Re: Ablauf für Fräsmaschine programmieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
ok das mit den dreiecken klingt sehr interessant. dann müsste ich also die gesamte schwarze Fläche in kleine Dreiecke aufteilen, oder? joah wird schwierig aber bestimmt nicht unmöglich :mrgreen:
wenn das so klappen würde, könnte ich auch das programm auf dem microcontroller (c-control pro) der hardware umschreiben, so dass ich anstatt x, y, z und speed einfach die 3 endpunkte der dreiecke angeben muss und der dann selbstständig die gesamte fläche ausfräst. wäre vermutlich noch relativ effizient denke ich.

@haentschman
du meinst also eigentlich einen versatz um die weissen flächen zeichnen, das ergibt dann eine linie, und da fährt dann der fräser entlang? danach müssten natürlich noch die "innenräume" ausgefräst werden.
ich hab mal ein bild gemalt, die roten linien wären dann der versatz. hab ich das richtig verstanden?

haentschman 26. Sep 2008 20:08

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

@haentschman
du meinst also eigentlich einen versatz um die weissen flächen zeichnen, das ergibt dann eine linie, und da fährt dann der fräser entlang? danach müssten natürlich noch die "innenräume" ausgefräst werden.
ich hab mal ein bild gemalt, die roten linien wären dann der versatz. hab ich das richtig verstanden?
...genau :wink:

- ich würde im ersten Schritt einmal die Kante entlang fahren (wg. Schönheit 8) und dann kannst du z.B. zeilenweise die Fläche bearbeiten. Die Grenzpunkte links und rechts jeder Zeile sind ja durch die "Maske" bekannt.

Namenloser 26. Sep 2008 20:09

Re: Ablauf für Fräsmaschine programmieren
 
Ich denke, er will es möglichst schnell haben... dann wäre die "Schönheit" wohl erst mal das unwichtigste.

haentschman 26. Sep 2008 20:13

Re: Ablauf für Fräsmaschine programmieren
 
er sagte aber auch, daß er das Fräsen als Dienstleistung anbieten möchte...damit ist Schönheit eines der Kriterien.

...und was kostets mehr, wenn man es gleich richtig macht :mrgreen:

100nF 26. Sep 2008 20:40

Re: Ablauf für Fräsmaschine programmieren
 
also ich möchte einen kompromiss zwischen geschwindigkeit und schönheit haben würd ich mal sagen :mrgreen:

jetzt hab ich also schonmal 2 interessante Vorschläge. Muss mir jetzt mal zu beiden Varianten Gedanken machen und gucken was wohl die bessere ist.

Jetzt geh ich erstmal in den Ausgang und dann schaumer mal weiter xD

markusj 26. Sep 2008 22:58

Re: Ablauf für Fräsmaschine programmieren
 
Da ich an einem ähnlichen Projekt arbeite, meine zwei Cent:

Es gibt verschiedene Befehlssätze für Fräsmaschinen. Gängig sind z.Bsp. der G-Code und HPGL.
Ersteres ist eine ISO-Standarisierte "Programmiersprache" für Fräsmaschinen und wird auch im professionellen Bereich eingesetzt, letzteres primär eine Plottersprache für die es sogar Druckertreiber gibt.

Vergiss die Idee mit Bitmaps am besten ganz schnell wieder!

Und sorry Leute, die Idee mit einer Fräse zeilenweise über die Platine zu fahren ist unpraktikabel. Erstens dauert das ganze ewig und zweitens wird die Qualität der Platine miserabel ausfallen, eine Fräse ist nun mal kein Bildschirm auf dem man einzelne Pixel setzen kann und diese dann sauber erscheinen.

Ich habe keine Ahnung, mit welcher Software du deine Platinen Layoutest, für Eagle gibt es definitiv Plugins zum Export von G-Code.
Wenn du mit Bitmaps arbeiten musst, dann Wandle zuerst einmal die geometrischen Grundelemente in Parameter um mit denen du arbeiten kannst, sprich, bei Linien benötigst du Anfangs- und Endpunkt, bei Kreisen den Radius, den Start- und Mittelpunkt und den Winkel.

Ich für meinen Teil gieße diese Funktionalität direkt in meinen µC, der bekommt dann leicht vereinfachten G-Code eingeflöst und übernimmt die Rasterung selbst (Grüße an Bresenham ;)).

mfG
Markus

100nF 26. Sep 2008 23:33

Re: Ablauf für Fräsmaschine programmieren
 
hmm klingt auch nicht schlecht :D

also ich erstelle die layouts in eagle, aber bei export hab ich nur "Netlist", "Partlist", "Pinlist" und "Image". wie kann ich es als einen solchen code exportieren?

Also Images wären eben auch nicht schlecht, weil eine solche maschine auch sehr gut zum gravieren geeignet wäre, und da müsste man schon auch Grafiken gravieren können.

Und ein Image in einen solchen Code verwandeln...ob ich das hinkriege :?:

EDIT: HPGL hab ich gefunden (bei CAM Processor) aber den G-Code hats nicht in der Liste?!

markusj 26. Sep 2008 23:49

Re: Ablauf für Fräsmaschine programmieren
 
Es gibt verschiedene Plugins, die auf der Eagle-Homepage verlinkt sind.
Direkt mitgeliefert werden keine.
Ich persönlich fand G-Code einfacher als HPGL, aber jedem das seine.

cadsoft.de/download.htm dort der Link ULP. Dann einfach einmal nach G-Code stöbern.

mfG
Markus

PS: Mit reinen Bildern arbeiten kannst du vergessen. Du musst auf jeden Fall die geometrischen Grunddaten extrahieren, um zu bestimmen, was du wie und in welcher Reihenfolge abfährst. Du solltest die Ansteuerung in verschiedene Ebenen trennen, die schrittweise Motoransteuerung ist dabei die niedrigste!

bit4bit 27. Sep 2008 00:02

Re: Ablauf für Fräsmaschine programmieren
 
Hab so was mal gemacht (Doppeleuropakarte beidseitig)

Es reichte aus, einfach nur die Leiterbahnen, Lötpads, Vias und Lötaugen durch ein Umfahren mit dem Fräser freizustellen (d.h. zu isolieren).

Die stehebleibenden, unbenutzten Flächen haben elektrisch eher eine positive Wirkung, außerdem bleibt die Platine dadurch wesentlich stabiler.

Wie schnell dreht Deine Fräse eigentlich?

mfG bit4bit

100nF 27. Sep 2008 00:16

Re: Ablauf für Fräsmaschine programmieren
 
hmm ich kriegs einfach nicht gebacken das g-code plugin zu installieren :wall:
werde es morgen nochmals versuchen...

@bit4bit
finde das aber auch nicht so das wahre...ich wüsste auch nicht ob das dann für höhere Spannungen auch geeignet wäre, weil dann der Abstand grösser sein müsste. Und falls ich das Fräsen dann als Dienstleistung anbiete kann ich nicht mit so einer Sache kommen xD

Zitat:

Wie schnell dreht Deine Fräse eigentlich?
meinst du mich? und meinst du die Schrittmotoren oder die Spindel?
Spindel hab ich noch keine, da mach ich vermutlich entweder einfach einen starken 12V motor ran oder bau einfach einen Dremel auf die Maschine :D
Die Schrittmotoren schaffen glaub paar Umdrehungen pro Sekunde...vielleicht 4-5 oder so...weiss es aber auch nicht genau, ist nur geschätzt.

markusj 27. Sep 2008 00:22

Re: Ablauf für Fräsmaschine programmieren
 
Du musst das G-Code Plugin einfach in den Ordner "ulp" im Eagle-Programmverzeichnis kopieren (in der Regel C:\Programme\Eagele-*\ulp)
Für den Anfang empfielt sich das Plugin gcode-1, fortgeschrittenere können sich bei pcb-gcode austoben.

Normalerweise fräst man nur Weg was sein muss, man hat ja die Möglichkeit größere Abstände zu definieren.

mfG
Markus

100nF 27. Sep 2008 14:31

Re: Ablauf für Fräsmaschine programmieren
 
komisch, hab das jetzt mehrmals ausprobiert aber ich kann beim "CAM Processor" in der Liste keinen entsprechenden Eintrag finden?!
Im Control Panel von Eagle ist die Datei aber aufgeführt unter "User Language Programs"...

Also wenn ich "pcb-gcode" benutzen würde, dann könnte ich einfach fräserdurchmesser usw. angeben, und die datei die er dann erzeugt enthält alle befehle, die ich dann sozusagen direkt an den microcontroller schicken kann? Das wäre ja echt genial!

EDIT:
OK hab da was im Internet gefunden, sieht echt gut aus, bin das grad mal am durchlesen :D
hier der link: klick

markusj 27. Sep 2008 16:21

Re: Ablauf für Fräsmaschine programmieren
 
Das ganze ist auch ein ULP und muss dementsprechend mit "ULP öffnen" aufgerufen werden. Alternativ kannst du in der Eagle-Kommandozeile run pcb-gcode ausführen.
Wenn du auf die Website von PCB-Gcode gehst (http://pcbgcode.org/index.php), findest du dort neben der aktuellsten Version auch noch ein kleines Optimierungsprogramm, das noch einmal Zeit sparen kann.

Du bekommst danach eine G-Code Datei, die du dann weiter verarbeiten kannst. Es gibt verschiedene G-Codes, z.Bsp. für Eilgang G00, Gerade G01 etc.
Je nach dem wie dein System aufgebaut ist, muss dann entweder dein Programm oder der µC diese G-Codes in Schrittanweisungen umsetzen.

Bei mir wird das ganz wie folgend Ablaufen:
1. PC-Programm tauscht die Konfiguration mit dem µC aus.
2. PC-Programm lädt G-Code, überprüft die Syntax und die Maximalwerte (Geschwindigkeit, Verfahrbereich etc.)
3. Evtl. anpassen der Konfiguration des µCs.
4. Versenden der G-Codes via RS232 über ein eigenes Protokoll. Die G-Codes werden dabei vereinfacht, der µC braucht ja für ein G00 keine drei Bytes!
5. Überwachen der Ausführung, nachfüllen des µC-Puffers wenn dieser Bedarf anmeldet.

Die komplette Rasterung und Motoransteuerung wird der µC übernehmen, neben der Ansteuerung via G-Code besteht dabei auch die Möglichkeit, vom PC oder über ein Kontrollinterface die Fräse manuell zu Steuern.

Was du nicht im PC implementierst, musst du natürlich dann im µC umsetzen!

mfG
Markus

jokerfacehro 27. Sep 2008 16:30

Re: Ablauf für Fräsmaschine programmieren
 
wenn du SPS programmierung hast, weißt du das bestimmt, will nur nochmal draufhinweisen:

für jeden steuerschritt einen merker zu setzen und eine havarie-funktion einzubauen

markusj 27. Sep 2008 16:42

Re: Ablauf für Fräsmaschine programmieren
 
WTFH?
Ich kann mit deinen Begriffen gerade wenig anfangen.
Havarie? Dafür gibt es für jede Achse zwei Endschalter die einen sofortigen Stop der Automatik erwirken. Gleichzeitig zählt der µC jeden einzelnen Schritt mit und weiß so zu jedem Zeitpunkt, wo er sich befindet.
Da ich keine SPS programmiere, sondern in meinem Falle einen ATMega168 habe ich keine "Merker".
Tatsächlich muss der AVR aber die ganze Zeit darüber bescheid wissen, wo er gerade steht und wohin er fährt.

Das war es doch, was du mit Merker meintest, oder?

mfG
Markus

100nF 27. Sep 2008 18:41

Re: Ablauf für Fräsmaschine programmieren
 
also mit "Havarie" kann ich auch nicht viel anfangen :gruebel:

und SPS programmieren hab ich in einem Kurs gelernt (Teil meiner Lehre als Automatiker) doch die Fräsmaschine wird mit einem Mikrocontroller realisiert (vorerst mal mit einem C-Control Pro mit Application Board).

@Markus
Also welchen Teil der µC und welchen Teil der PC übernimmt hab ich ja anfangs mal geschrieben (glaub sogar im ersten Beitrag).
Vorerst werde ich das auch mal so sein lassen, kann aber auch sein dass ich das später noch ändere, so dass es dann so ähnlich abläuft wie bei dir.

über den G-Code hab ich jetzt schon einiger gelesen, die einzelnen anweisungen hab ich hier gefunden. bin schonmal fleissig am programmieren :D

EDIT:
So, ging eigentlich ganz gut, bin gerade dabei das Programm für die Platine im ersten Beitrag abzuarbeiten. Der Schrittmotor für die X-Achse areitet jetzt schon fast eine Stunde, doch das Programm befindet sich noch nichtmal in der Hälfte^^

Für die Übersetztung von mm zu Schritten hab ich einfach mal den Faktor 50 angenommen, hab ja noch keine Mechanik...Ich denke aber 50 ist schon die unterste Grenze. Ausserdem hab ich keine Ahnung ob die Geschwindigkeit in Ordnung ist, doch ich fahre grad mit der zweitschnellsten Geschwindigkeit die möglich ist. (jeweils 1ms twischen den Einzelschritten)

Ich würde also meinen dass ich da noch stark optimieren muss :D

@markusj
könntest du vielleicht noch bisschen Informationen geben von deiner Lösung?
z.B. wie dein Protokoll aussieht wäre noch interessant.
Ausserdem habe ich noch keine grosse Erfahrung mit dem Programmieren von Microcontrollern. Wird der gesamte (verkürzte) G-Code in ein EEPROM geladen oder wie? Ich mein, so 100KB sind doch schon eine ziemliche Menge für einen Mikrocontroller...

EDIT2:
und mit welcher Programmiersprache programmierst du deinen Mikrocontrolle? Würdest du deinen Code vom Mikrocontroller auch hier im Forum posten, oder zumindest den Teil der für die Übertragung zuständig ist?

markusj 29. Sep 2008 09:49

Re: Ablauf für Fräsmaschine programmieren
 
Hätte ich doch fast deinen Edit übersehen! :wall:

Ok, ein Paar Infos:

Die Hardware besteht aus einem ATMega168, der drei Schrittmotorplatinen L287/298 ansteuert.

Bisheriger Projektstatus: Elektrische Hardware steht größtenteils, die Fräse befindet sich noch in der Planungsphase. Die Firmware wird gerade entwickelt, das PC-Gegenstück dazu wird langsam mitwachsen.

Ich programmiere das ganze in "C", das ist für AVRs so ziemlich das günstigste und effektivste neben ASM (*grusel*).

Der µC hat mehrere Fifos für unterschiedliche Zwecke, einer davon speichert die empfangenen G-Codes zwischen. Die Ablage findet komplett im SRAM statt, EEPROM wäre viel zu langsam, außerdem macht der "nur" 100.000 (evtl. noch *10?) Schreibzyklen mit.
Je nach Füllstand fordert der µC dann neues "Futter" an oder bremst die Gegenstelle.

Mein Protokoll sieht momentan so aus: Startbyte-Message_Size-Command_Byte-Payload-Command_Byte-Checksumme-Stopbyte.
Bis auf die Payload (welche Message-Size-6 Bytes groß ist), sind alle anderen Elemente je ein Byte groß.
Die Checksumme ist einfach das Zweierkomplement der Summe aller Bytes.

Das ganze ist im Moment noch in Entwicklung, z.Z. optimiere ich gerade meinen abgewandelten Bresenham-Kreisalgorithmus.
Den Source werde ich vermutlich veröffentlichen, tendenziell aber eher im Roboternetz-Forum, in dem es einige CNC-Relevante-Threads gibt.
Zu gegebener Zeit werde ich dort auch einen neuen Thread zu meiner Firmware eröffnen.
Es spricht aber nichts dagegen, das ganze zusammen mit dem "Server"-Programm auch hier auszubreiten.

mfG
Markus

PS: Zum Thema Code-Posten: Gerade bei µCs ist Sourcecode nur begrenzt portabel. Abhängig davon, wie du die Hardware verdahtet hast, welchen µC du gewählt hast etc. bestehen manche Möglichkeiten, andere nicht.
Da der µC die G-Codes selbst umsetzen muss, verwende ich gezwungenermaßen gewisse Ressourcen wie Timer, um möglichst schnell die notwendigen Berechnungen durchführen zu können.
Wenn du diese Ressourcen andersweilig verwendest, gibt es zwaangsläufig Konflikte.
Mein Source ist zwar modularisiert, die Module werden aber stark miteinander vernetzt sein.

100nF 29. Sep 2008 17:32

Re: Ablauf für Fräsmaschine programmieren
 
Okay, also meine Hardware ist wie gesagt das C-Control Pro, welches einen ATMega128 enthält. Die Schrittmotoren werden auch über die Kombination L297/L298 angesteuert.

Den Mega128 programmiere ich in Basic, doch "C" (bzw. "Compact-C") wäre auch möglich. Doch als ich mich entscheiden "musste" gefiel mir Basic schon einiges besser^^

Ich glaube, dass ich das mit der Übertragung alleine überhaupt nicht hinkriege. Das, was ich bis jetzt gemacht habe war so zimelich das billigste - funktionieren tuts aber :D

Dann zum Protokoll, ich glaub das hab ich noch nicht ganz verstanden:
Startbyte --> Darum muss ich mich nicht kümmern oder (Nur beim Initialisieren des Ports angeben)?
Message_Size --> Das gibt einfach die Länge (Anzahl Bits, Bytes?) der Message an?
Command_Byte --> Ist das der Befehl? also im G-Code wäre das z.B. M0 oder G01?
Payload --> Hier sind z.B. die X/Y/Z Koordinaten drin?
Command_Byte --> hmm nochmal das... ich lag glaub doch falsch^^
Checksumme --> Einfach zur Sicherheit nehme ich mal an...
Stopbyte --> Ähnlich wie das Startbyte...

Die übertragenen Bytes werden dann also einfach in eine Variable geschrieben wenn ich das richtig verstanden habe. Ist das irgendwie ein "Array of Irgendwas"?

Benutzt du Threads für die Übertragung? Bei meinem Programm warte ich einfach auf ein "Signal" von der seriellen Schnittstelle, wenn da keines kommt bleibt das Programm an dieser Stelle hängen...also so lange bis ein Signal kommt.

Ach ja, für was brauchst du den Bresenham-Kreisalgorithmus? Ich kenn den zwar nicht, aber wird wohl für Kreise benötigt (laut Wikipedia^^) :D Doch im G-Code sind die Kreise doch irgendwie schon in einzelne Geraden umgewandelt oder?!

Zitat:

PS: Zum Thema Code-Posten: Gerade bei µCs ist Sourcecode nur begrenzt portabel. Abhängig davon, wie du die Hardware verdahtet hast, welchen µC du gewählt hast etc. bestehen manche Möglichkeiten, andere nicht.
Ja das ist mir schon klar, doch ich bin absoluter Anfänger (wie du bestimmt gemerkt hast xD) auf diesem Gebiet, und da ist meine grösste Schwierigkeit im Moment noch der "Gesamtaufbau" des Programms. Dieser ist ja unabhängig von der Programmiersprache und von den einzelnen Befehlen ja grundsätzlich immer ziemlich ähnlich.

Falls du mal im Roboternetz schreibst, kannst mir vielleicht bescheid geben, damit ich das Thema dann auch mitverfolgen kann?

Danke schonmal für die Hilfe!!

mfg
Urban

markusj 29. Sep 2008 18:46

Re: Ablauf für Fräsmaschine programmieren
 
Hi,
Zitat:

Zitat von urbanbruhin
Dann zum Protokoll, ich glaub das hab ich noch nicht ganz verstanden:
Startbyte --> Darum muss ich mich nicht kümmern oder (Nur beim Initialisieren des Ports angeben)?
Message_Size --> Das gibt einfach die Länge (Anzahl Bits, Bytes?) der Message an?
Command_Byte --> Ist das der Befehl? also im G-Code wäre das z.B. M0 oder G01?
Payload --> Hier sind z.B. die X/Y/Z Koordinaten drin?
Command_Byte --> hmm nochmal das... ich lag glaub doch falsch^^
Checksumme --> Einfach zur Sicherheit nehme ich mal an...
Stopbyte --> Ähnlich wie das Startbyte...

Naja, nicht wirklich: Die Übertragung erfolgt über die serielle Schnittstelle, alles was ich angegeben habe, ist für dich von Relevanz.

Startbyte --> 0x0F, dient zum Erkennen eines Telegramms vom PC.
Message_Size --> Anzahl der Bytes des KOMPLETTEN Telegramms.
Command_Byte --> Kommando des PCs an den µC. KEIN G-Code, da es neben G-Codes noch andere Anweisungen (Kalibrierparameter etc.) an den PC gibt. Wenn ein G-Code übetragen wird, enthält das Command_Byte z.Bsp. die Anweisung cmd_code_gcode_transfer.
Payload --> Die Payload enthält die Informationen, die zur Ausführung des Commands benötigt werden. Bei cmd_code_gcode_transfer z.Bsp. würde die Payload den vereinfachten G-Code beinhalten. Anhand des Commands kann dann ein Unterprogramm aufgerufen werden, das sich dann um die Auswertung der Payload kümmert.
Command_Byte --> Zur Sicherheit wird das Command_Byte doppelt übertragen. Stimmt es nicht überein, wird das Telegramm verworfen.
Checksumme --> Zweierkomplement der Summe ALLER Bytes bis hierher. Stimmt sie nicht überein, wird das Telegramm verworfen.
Stopbyte --> 0xF0, dient zum Erkennen eines Telegrammendes.

Die komplette Dekodierung erfolgt in einer State-Machine, die den Eingangs-Fifo nach dem Startbyte durchsucht und dann Schritt für Schritt die einzelnen Überprüfungen durchführt.
Befindet sich das Stopbyte nicht an der von der Messaage_Size angegeben Position schaltet die State-Machine ebenso auf Durchzug wie bei allen anderen Telegramm-Fehlern.
Erst wenn ein Stopbyte auftaucht, "hört" die State-Machine wieder zu.

Zitat:

Zitat von urbanbruhin
Benutzt du Threads für die Übertragung? Bei meinem Programm warte ich einfach auf ein "Signal" von der seriellen Schnittstelle, wenn da keines kommt bleibt das Programm an dieser Stelle hängen...also so lange bis ein Signal kommt.

Normalerweise kann ein AVR keine Threads. Eine Multithreading-Implementation würde kostbare Rechenzeit und andere Ressourcen fressen.
Stattdessen verwende ich ein ausgeklügeltes (?) *hust* Programmdesign damit alle Module ihren Job erldigen können:

Main-Schleife:
- State-Machine zur Auswertung der Telegramme
- G-Code-Interpreter & Preprozessor
- G-Code-Main-Prozessor (sofern nötig)

RS232-Receive-Interrupt:
- Schaufelt empfangene Bytes in den Receive-Fifo (der dann in der Main-Schleife ausgewertet wird)

Timer-Interrupt:
- Steuert die angeschlossenen Motoren je nach aktuellem Steuerbefehl an. (Pinwackeln ;))

+X andere Kleinigkeiten am Rande (ADC für die manuelle Kontrolle, blinkende LEDs, Endschalter etc.)

Solange kein Interrupt in die Ausführung der Main-Schleife springt, wartet diese auf Benutzereingaben und berechnet Anweisungen für den Motor-Timer-Interrupt vor.

Zitat:

Zitat von urbanbruhin
Ach ja, für was brauchst du den Bresenham-Kreisalgorithmus? Ich kenn den zwar nicht, aber wird wohl für Kreise benötigt (laut Wikipedia^^) :D Doch im G-Code sind die Kreise doch irgendwie schon in einzelne Geraden umgewandelt oder?!

Nope, schau dir mal G02 und G03 an, das sind die Befehle für eine Kreisbewegung im/gegen den Uhrzeigersinn.
Der Main-Prozessor wird hauptsächlich diese Berechnungen übernehmen, für eine klassische Gerade wird das ganze hoffentlich direkt in der Motor-ISR erledigt werden können.

Zitat:

Zitat von urbanbruhin
Ja das ist mir schon klar, doch ich bin absoluter Anfänger (wie du bestimmt gemerkt hast xD) auf diesem Gebiet, und da ist meine grösste Schwierigkeit im Moment noch der "Gesamtaufbau" des Programms. Dieser ist ja unabhängig von der Programmiersprache und von den einzelnen Befehlen ja grundsätzlich immer ziemlich ähnlich.

Falls du mal im Roboternetz schreibst, kannst mir vielleicht bescheid geben, damit ich das Thema dann auch mitverfolgen kann?

Kein Problem, es gibt im RN ein/zwei _richtig_ große Threads zum Thema CNC, ich bin dort unter dem selben Nick unterwegs und hab auch schon ein paar Beiträge hinterlassen.

Ich habe allerdings _keine_ Ahnung von der C-Control, nach dem was ich mir gerade ergoogelt habe, wirst du vermutlich von "meiner" Lösung Abstand nehmen müssen.
Bei der C-Control hast du eine Zwischenschicht/eine Art Betriebssystem zwischen dir und der Hardware, die Folge daraus ist vermutlich automatisch, dass du Echtzeitanwendungen eher schwierig umsetzen kannst, vor allem wenn du dich schon hart am Limit dessen bewegst, was der µC an Leistung hat.
Hast du schon einmal versucht, einen Schrittmotor "von null auf hundert" und zurück zu regeln? Kommst du bis in den Bereich, in dem Schrittverluste auftreten?

Im Moment verwende ich für meine Umsetzung Zeitscheiben von 0,1ms. Da mein µC mit 20Mhz taktet und die Ansteuerfrequenz 10kHz beträgt, habe ich je Schritt 2000 Instruktionen zur Berechnung der nächsten Bewegung zur Verfügung.
Je nach dem, wie performant meine Umsetzung ist, kann ich später sogar einen noch kleineren Grundtakt für die Motoransteuerung wählen.
Jedes Mhz weniger reduziert die Reserve, die du für deine Berechnungen hast, immerhin berechnet der µC nebenher wo die Reise hingeht, die Interrupts sind höher priorisiert und wollen nur noch den Schrittmotortreiber ansteuern, das nächste Kommando hat also da zu sein!
Die C-Control Pro scheint mit 14,irgendwas Mhz zu Takten, die Tatsache dass der Code auch noch durch einen Interpreter läuft, verschlechtert deine Chancen nur noch mehr.

mfG
Markus

100nF 29. Sep 2008 19:25

Re: Ablauf für Fräsmaschine programmieren
 
hmm..also ich hab das bisher völlig anders gemacht würde ich sagen. Auf diese Weise wäre ein "zu langsamer" Mikrocontroller eigentlich gar nicht schlimm, ein Fräsvorgang würde einfach länger dauern aber funktionieren würde es.

Ich poste mal den relevanten Teil meines Basic-Programms, falls du willst kannst du es ja mal anschauen.
Code:
Sub OneStep(Achse As Byte, Richtung As Byte) 'Führt einfach nur einen Schritt bei einer Achse in die gewählte Richtung aus
    Select Case Achse
      Case 1 'X-Achse, F.0
        Port_WriteBit(43, Richtung) 'Richtung angeben
        Port_WriteBit(40, 1)
       ' AbsDelay(ISpeed*SpeedFactor)        ' Verzögerung in ms
        Port_WriteBit(40, 0)
        If Richtung=0 Then
          PosX=PosX-1
        Else
          PosX=PosX+1
        End If

      Case 2 'Y-Achse F.1
        Port_WriteBit(44, Richtung) 'Richtung angeben
        Port_WriteBit(51, 0)
       ' AbsDelay(ISpeed*SpeedFactor)        ' Verzögerung in ms
        Port_WriteBit(51, 1)
        If Richtung=0 Then
          PosY=PosY-1
        Else
          PosY=PosY+1
        End If

      Case 3 'Z-Achse F.2
        Port_WriteBit(45, Richtung) 'Richtung angeben
        Port_WriteBit(52, 0)
      ' AbsDelay(ISpeed*SpeedFactor)        ' Verzögerung in ms
        Port_WriteBit(52, 1)
        If Richtung=0 Then
          PosZ=PosZ-1
        Else
          PosZ=PosZ+1
        End If

      End Case
End Sub


In der Main-Prozedur:
Do While True
    GoPosX="    "
    For i=0 To 4
      GoPosX(i)=Serial_Read(0)
    Next

    GoPosY="    "
    For i=0 To 4
      GoPosY(i)=Serial_Read(0)
    Next

    GoPosZ="    "
    For i=0 To 4
      GoPosZ(i)=Serial_Read(0)
    Next

    Speed="    "
    For i=0 To 4
      Speed(i)=Serial_Read(0)
    Next

    Text="Fahre auf Position...       "
    Serial_WriteText(0, Text)
    Serial_Write(0, LF)
    Serial_Write(0, CR)

    InZahlenWandeln()

    GoToPos() ' hier wird OneStep(...) mehrmals aufgerufen

    Text="Erwarte Befehl              "
    Serial_WriteText(0, Text)
    Serial_Write(0, LF)
    Serial_Write(0, CR)
  End While
Die Prozedur GoToPos ist nur sehr schwer verständlich wenn ich den Code poste :D Deshalb eine kurze Erklärung:
Istposition und Sollposition von X, Y und Z werden verglichen. OneStep wird dann mit jeder Achse so häufig aufgerufen, bis die Fräse sich in der Sollposition befinden.
Bsp: Xist, Yist, Zist = 0; Xsoll = 100, Ysoll = 50 und Zsoll=25;
--> OneStep(X) wird 100 mal aufgerufen, Jedes zweite mal wird auch OneStep(Y) und jedes vierte mal auch OneStep(Z) aufgerufen.

Zu deiner Frage noch: Anfangs konnte ich das Teil so schnell laufen lassen bis es Schrittverluste gab. Dann hab ich das Programm ein bisschen abgeändert, nun gibts (höchstwahrscheinlich sehr knapp) keine Schrittverluste mehr. Also mit der maximalen Geschwindigkeit bin ich eigentlich ganz zufrieden, ich glaub nicht dass der Schrittmotor noch schneller laufen könnte.

Mit Interrupt hab ich mich noch nicht auseinandergesetzt, dohc ich habe befürchtet dass dies für eine saubere Lösung notwendig ist :D


Da hab ich wohl einiges zu tun um es so ähnlich hinzukriegen wie du :D
Naja wenigstens wird mir so nicht langweilig^^

mfg
Urban

EDIT:
was ich schon lange fragen wollte, wie greifst du im Delphi-Programm auf die RS232 zu? Benutzt du eine Komponente?

markusj 29. Sep 2008 21:37

Re: Ablauf für Fräsmaschine programmieren
 
Du bekommst damit niemals eine exakt diagonale Bewegung hin, du bewegst deine Achsen immer getrennt.
Noch dazu kommt: Der langsamste Motor bestimmt die Geschwindigkeit. Und die ist niemals die von dir erwartete.
Der Grund: Du arbeitest blockierend und mit Verzögerung.

Dafür habe ich meine Zeitscheiben. Geplant ist folgendes:
Zu einer (linearen) Bewegung gibt es für jede Achse folgenden Datensatz:
- Anzahl zu erledigender Schritte
- Anzahl der zu wartenden Zeitscheiben zwischen zwei Schritten (Geschwindigkeitsfaktor)
- Zeitscheibenzähler

Jede Zeitscheibe wird der Zähler dekrementiert und dann geprüft, ob er null ist.
Für alle Achsen, bei denen dies der Fall ist, werden getoggelt.
Dann wird der Zähler wieder zurückgesetzt auf den Startwert, die Anzahl der zu erledigenden Schritte um eins reduziert, bis diese Anzahl schließlich bei null angekommen ist.
Wenn alle Achsen ihre Zielposition erreicht haben, wird der nächste Job geladen.

@RS232: Im Moment noch gar keine. Die Firmwareentwicklung steht im gerade im Vordergrund, sobald die Firmware so weit ist, dass sie ein Gegenstück braucht, entsteht dieses langsam. Google und die Suchfunze spucken aber diverse Möglichkeiten aus.

mfG & Happy Coding
Markus

100nF 30. Sep 2008 17:53

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Du bekommst damit niemals eine exakt diagonale Bewegung hin, du bewegst deine Achsen immer getrennt.
Ja schon, doch die maximale Abweichung kann nur 1 Schritt sein und das würde ich noch akzeptieren...
Aber ist natürlich schon eine schlechte Lösung, das ist mir schon klar!

Das mit den Zeitscheiben (=Timer?!) habe ich so halbwegs verstanden... aber diese 3 Zeitscheiben-Prozeduren müssen doch genau gleichzeitig ausgeführt werden, da bräuchte es doch Threads?!
Das begreife ich irgendwie nicht. Du kannst ja auch nicht bei allen 3 Schrittmotoren exakt im gleichen Moment einen Schritt ausführen oder, eine minimale Verzögerung zwischendrin hast du doch immer?

Naja...also sobald du mal ein bisschen Code zum angucken hast, wäre ich sehr froh wenn du den mal posten könntest. Ich denke, ich probiere jetzt auch mal mit den Übertragungsroutinen zu beginnen. Wenn ich grad Zeit habe schaue ich auch mal wie die Timer so funktionieren...

Zur RS232: Jo hab da schon paar Sachen gefunden, ich verwendete bisher eine Komponente dafür (TApdComPort). Da gibts dann ein PutChar(), PutString() und ein PutBlock(Word). Bräuchte ich da wohl PutBlock (genügt ein Word für das ganze Telegramm)?

mfg
Urban

markusj 30. Sep 2008 18:24

Re: Ablauf für Fräsmaschine programmieren
 
Mir ist dieser Beitrag im Forum aufgefallen, diese Form der Ansteuerung schaut doch ganz nett aus, oder?

Zur "gleichzeitigen" Ansteuerung: Der Trick besteht darin, dass ich erst berechne, welche Motoren bewegt werden müssen. Diese sind bei mir alle am PortB angeschlossen, ich kann also mit einer einzigen Zuweisung alle nötigen Pins toggeln.
Wie du bereits erraten hast, findet dieser Teil komplett in der Timer-ISR statt.

Ich hatte mir zuerst Gedanken über die Programmstruktur gemacht und dann mit den Bresenham-Routinen angefangen.
Daraufhin habe ich das Kommunikationsprotokoll und die dazugehörigen Routinen so entworfen, dass alle anderen (zu diesem Zeitpunkt ja noch nicht existenten) Module damit arbeiten können.

Im Moment optimiere ich meine Bresenham-Berechnungen "etwas", bei Kreisen mit einem Radius von weniger als ~30000 Schritten schafft der µC ~65k Punkte + Fifo-Zuweisung in einer Sekunde, allerdings ohne Positionskontrolle.

Als nächstes kommt dann vermutlich zuerst einmal das Motor-Management oder der G-Code-Interpreter, das muss ich erst noch sehen.
Das wird dann vermutlich auch der Teil der für dich interessanter ist.

mfG
Markus

100nF 1. Okt 2008 18:10

Re: Ablauf für Fräsmaschine programmieren
 
okay, ich hab mal was zusammengekritzelt...
Delphi-Quellcode:
var
  Befehl_vorhanden,
  Maschine_Bereit: boolean;

  Schritte_X,
  Schritte_Y,
  Schritte_Z,
  Geschwindigkeitsfaktor_X,
  Geschwindigkeitsfaktor_Y,
  Geschwindigkeitsfaktor_Z,
  GF_Down_X,
  GF_Down_Y,
  GF_Down_Z: Integer;

procedure main; // die Hauptprozedur des Programmes
begin
  Alles_Initialisieren; // z.B. die Serielle Schnittstelle initialisieren, Pins auf Ausgang schalten usw.

  begin Endlosschleife  // Läuft ewigs durch, hört nie auf =)
    RS232_Senden_Empfangen; // Siehe weiter unten

    if Befehl_Vorhanden and Maschine_Bereit then // Wenn ein Befehl vorhanden ist und kein Fräsvorgang in arbeit ist...
      Befehl_auswerten; // ...wird der Befehl ausgewertet (siehe weiter unten)
  end;
end;


procedure RS232_Senden_Empfangen;
begin
  Buffer_mit_Empfangsdaten_füllen; // Was in der Zwischenzeit empfangen wurde, wird in den Buffer geladen

  If Buffer_voll then // wenn der Buffer voll ist...
    Sende_Wartebefehl_an_PC; //... wird dem PC mitgeteilt dass er warten muss mit der Übermittlung
 
  If Buffer_leer then // Wenn der Buffer leer ist...
  begin
    Befehl_vorhanden := false; // Wird die Variable auf false gesetzt...
    Sende_Bereit_an_PC; // ...und dem PC mitgeiteilt dass er wieder Daten senden soll
  end
  else
    Befehl_vorhanden := true; // Wenn der Buffer nicht leer ist, wird die Variable auf true gesetzt
end;

procedure Befehl_auswerten; // Wertet den Empfangenen Befehl aus
begin
  Buffer_auslesen; // Der Empfangsfuffer der RS232 wird ausgelesen
  Buffer_splitten(Startbyte, Message_Size, Command_Byte, Payload, Command_Byte, Checksumme, Stopbyte); // Das Telegramm wird in die einzelnen bestandteile zerlegt
 
  // Startbyte usw überprüfen...

  Case Command_Byte of // Wenn der Befehl...
    Kalibrieren: Prozedur_Kalibrieren(Payload); // ...eine Kalibrierung ankündigt, wird diese ausgeführt
    G-Code: Run_G-Code(Payload); //...ein G-Code ankündigt, wird dieser weiterverarbeitet
  End;
end;

procedure Run_G-Code(Payload: G-Code); // Der Empfangene G-Code wird verarbeitet
begin
  Befehl_auslesen; // Liest aus dem Payload heraus, ob M0, M1, G00, G01 usw.
 
  Case Payload.Befehl of // Enthält "M0", "G00" usw.
    M0: ... ;
    M1: ... ;
    ...
    G00: Fahre_Zu_Position(Payload.X, Payload.Y, Payload.Z, schnell); // Die Fräse muss schnell an die angekündigte Position fahren
    G01: Fahre_Zu_Position(Payload.X, Payload.Y, Payload.Z, schnell); // Die Fräse muss an die angekündigte Position fahren
    ...
  end;
end;


procedure Fahre_Zu_Position(X, Y, Z, Geschwindigkeit); // Die Position X, Y, Z wird mit der entsprechenden Geschwindigkeit angefahren
begin
  Maschine_Bereit := false; // Damit Keine zweite Befehlsauswertung stattfinden kann

  Schritte_X := X - Istposition_X; // Die Differenz zwischen Soll- und Istposition ermitteln
  Schritte_Y := Y - Istposition_Y;
  Schritte_Z := Z - Istposition_Z;

  Geschwindigkeitsfaktor_X_berechnen; // Die Wartezeit zwischen den einzelnen Pins ein-/ausschalten berechnen
  Geschwindigkeitsfaktor_Y_berechnen;
  Geschwindigkeitsfaktor_Z_berechnen;

  GF_Down_X := Geschwindigkeitsfaktor_X; // Variable setzten
  GF_Down_Y := Geschwindigkeitsfaktor_Y;
  GF_Down_Z := Geschwindigkeitsfaktor_Z;

  timer_X_Intervall := Geschwindigkeit; // Den Intervall für die Geschwindigkeit
  timer_Y_Intervall := Geschwindigkeit;
  timer_Z_Intervall := Geschwindigkeit;

  timer_X_aktivieren; // Die Timer werden aktiviert
  timer_Y_aktivieren;
  timer_Z_aktivieren;
end;

procedure Timer_x; // 3 Mal das "selbe" für X, Y, Z)
begin
  GF_Down_X := GF_Down_X - 1; // Die Wartezeit wird immer eines weniger
 
  if GF_Down_X = 0 then // Wenn die Wartezeit gleich Null ist...
  begin
    If Pin_Ein then // ...Wird der Takt-Pin getoggelt
      Pin_aus
    else
      Pin_ein;
   
    GF_Down_X := Geschwindigkeitsfaktor_X; // ...wird die Wartezeit wieder heraufgesetzt

    Schritte_X := Schritte_X - 1; // ...wird die Anzahl zu erledigender Schritte verringert

    If Schritte_X = 0 then // Wenn alle Schritte ausgeführt wurden...
    begin
      Timer_X_deaktivieren; // ...wird der Timer_X deaktiviert
      If (Schritte_Y = 0) and (Schritte_Z = 0) then //...und wenn alle Schritte (X, Y, Z) ausgeführt wurden...
        Maschine_Bereit := true; //...wird die Bereitschaft auf true gestellt damit der nächste Befehl verarbeitet werden kann
    end;
  end;
end;
hast du dir das in ungefähr so vorgestellt?
Soll natürlich nur den Ablauf darstellen, ich programmier den µC natürlich nicht in Delphi^^

mfg
Urban

markusj 1. Okt 2008 19:43

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Zitat von urbanbruhin
okay, ich hab mal was zusammengekritzelt...
Delphi-Quellcode:
...
hast du dir das in ungefähr so vorgestellt?
Soll natürlich nur den Ablauf darstellen, ich programmier den µC natürlich nicht in Delphi^^

Jein:

Für das Senden/Empfangen von Kommandos gibt es zwei FiFos und zwei Prozeduren.
Die für das Senden erstellt das Kommandotelegramm an den PC und speichert es in den Fifo. Das Übertragen übernimmt (oh Überraschung) ein Interrupt, der beim Füllen des TX-Puffers aktiviert wird und bei leerem Puffer deaktiviert wird (Für alle Kenner: Es handelt sich um den UDRE-Interrupt (USART Data Register Empty)).
Beim Empfangen ist es ähnlich, der Receive-Interrupt schaufelt die Daten in den Fifo und setzt intern verschiedene Warn-Flags für einen fast vollen oder vollen RX-Fifo.
Die fürs Empfangen zuständige Prozedur tritt erst hier auf den Plan und wird in der Main-Schleife angepollt. Sie prüft Schritt für Schritt die ankommenden Bytes durch.
Der Trick ist, dass nicht wie bei dir ein Kommando auf einmal ausgelesen wird, sondern es gibt eine Statusvariable für die verschiedenen Zustände. Die Zerlegung findet dann Schrittweise in einer State-Machine statt (Case-Selektor anhand der Statusvariable), wenn ein Schritt durch ist, schaltet er den nächsten aktiv.
Die Dekodierung erfolgt deshalb schrittweise, weil in der Zwischenzeit sonst keine weiteren Punkte berechnet werden können. Dazu aber nun.

Das war der Kommunikationsteil, nun die Auswertung und Ansteuerung.
Für ankommende G-Codes gibt es bei der Kommando-Dekodierung im entsprechenden Schritt eine Subroutine, die den (vereinfachten) G-Code aus der Payload dann in die intern verwendete Struktur überführt und in einen G-Code-Fifo packt.

Nach der Kommando-Dekodierung wird die G-Code-Dekodierung aufgerufen, die entweder einen G-Code dekodiert und in den Ansteuerungs-Fifo abspeichert, oder aber komplexe G-Codes (Kreis!) oder Steuerungs-G-Codes (u.a. die M-Befehle) direkt verarbeitet.

Die Motorsteuerung selbst findet im bereits erklärten Timer-Interrupt statt und kann bereits von Natur aus Linien zeichnen, da zu jeder Achse die Parameter der zurückzulegenden Schritte sowie die Geschwindigkeit festgelegt werden. Das Verhältnis der Geschwindigkeiten zueinander bestimmt die Richtung der Linie, die Schrittzahl die Länge.
Die Berechnung der Schritte findet ZUSAMMEN in einem Timer-Interrupt statt, dort werden dann die Pins gewackelt.
Ist ein solcher Task abgearbeitet, wird der nächste Datensatz aus dem Ansteuerungs-Fifo geholt.

Kreise werden "einfach" als Linien mit höchstens einem Schritt je Achse abgelegt, was zwar häufige FiFo-Operatinen zufolge hat, es aber ermöglicht, ein durchgängiges Konzept zu verwenden.
Gleichzeitig erfordert es aber auch, dass die Kreisberechnungen, die nun in der Main-Schleife stattfinden, häufig genug den FiFo auffüllen können. Deshalb muss die Kommando-Dekodierung aufgeteilt werden, um den FiFo auf gar keine Fall leerlaufen zu lassen.

Die Berechnung erfolgt also möglichst unabhängig von den Interrupts, die ISRs können relativ kurz bleiben, eine zeitnahe Reaktion ist so gewährleistet.

mfG
Markus

100nF 1. Okt 2008 20:35

Re: Ablauf für Fräsmaschine programmieren
 
okay, jetzt ist mir einiges klarer geworden :D

Zitat:

Nach der Kommando-Dekodierung wird die G-Code-Dekodierung aufgerufen, die entweder einen G-Code dekodiert und in den Ansteuerungs-Fifo abspeichert, oder aber komplexe G-Codes (Kreis!) oder Steuerungs-G-Codes (u.a. die M-Befehle) direkt verarbeitet.
kann es dann aber nicht sein, dass z.B. ein M-Befehl ausgeführt wird, bevor er ausgeführt werden soll? Also wenn Der Pc den Befehl schickt: "G01 X:100 Y:100" und sofort danach "M3". Dann wird der G-Befehl in den Ansteuerungs-FIFO geschaufelt, und sofort danach das M3 ausgeführt wird, auch wenn die Position 100.100 nicht erreicht ist?

Ausserdem kann ich mir unter dem FIFO in der Praxis noch nichts vorstellen...
Benutzt du dafür eine Variable, ein Array? Oder wie sieht das aus?

Und kann der Ansteuerungs-FIFO nicht überfüllt werden, wenn eine kreisberechnung ausgeführt wird?

Werde später dann mal meinen "Code" nochmal überarbeiten, ich finde sowas irgendwie noch nützlich. Erstens ist es eine gute Vorlage wenn ich mit dem programmieren beginne, und zweitens kann ich ohne grosse Worte mitteilen wie ich mir den Ablauf vorstelle :D

Ach ja, also bei der kommunikationsgeschichte komm ich noch nicht 100% nach, aber das liegt daran dass ich das Grundprinzip der seriellen Datenübertragung noch nicht ganz verstanden habe, also in welcher Form ich die Daten empfange usw. Werde mal schauen ob ich da was gutes zum lesen finde...

Gruss
Urban

markusj 1. Okt 2008 21:59

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Zitat von urbanbruhin
okay, jetzt ist mir einiges klarer geworden :D
Zitat:

Nach der Kommando-Dekodierung wird die G-Code-Dekodierung aufgerufen, die entweder einen G-Code dekodiert und in den Ansteuerungs-Fifo abspeichert, oder aber komplexe G-Codes (Kreis!) oder Steuerungs-G-Codes (u.a. die M-Befehle) direkt verarbeitet.
kann es dann aber nicht sein, dass z.B. ein M-Befehl ausgeführt wird, bevor er ausgeführt werden soll? Also wenn Der Pc den Befehl schickt: "G01 X:100 Y:100" und sofort danach "M3". Dann wird der G-Befehl in den Ansteuerungs-FIFO geschaufelt, und sofort danach das M3 ausgeführt wird, auch wenn die Position 100.100 nicht erreicht ist?

Wenn man beim Programmieren nicht aufpasst - ja ;)
Tatsächlich ist es so, dass es verschiedene Steuerkommandos gibt, die sich verschiedenartig auswirken. Ein Wartezeitbefehl hindert mich nicht daran, schon das nächste Kommando vorzuberechnen, auch ein M3 (Frässpindel Drehrichtung Uhrzeigersinn einschalten) vermutlich nicht, je nach dem wo diese Kommandos interpretiert und umgesetzt werden, und ob eine serielle Abarbeitung garantiert ist.
Unter Umständen muss der Interpreter seine Arbeit aber auch unterbrechen, z.Bsp. bei einem Werkzeugwechsel-Befehl (außer du hast das Geld, dir diese Mechanik einzubauen ;)). In diesem Falle steuern die Motoren ihre Zielposition an und gehen dann, mangels neuer Befehle, auf Standby.

Klar ist auf jeden Fall, dass eine serielle Abarbeitung der G-Codes GARANTIERT sein muss.

Zitat:

Zitat von urbanbruhin
Ausserdem kann ich mir unter dem FIFO in der Praxis noch nichts vorstellen...
Benutzt du dafür eine Variable, ein Array? Oder wie sieht das aus?

Und kann der Ansteuerungs-FIFO nicht überfüllt werden, wenn eine kreisberechnung ausgeführt wird?

FiFo: Ein Array voller Daten, die in der Reihenfolge gelesen werden, in der sie geschrieben wurden. (First in, First out)
Die praktische Umsetzung erfolgt anhand eines Lese- und eines Schreibzeigers, kommt ein Datensatz, wird er geschrieben und der Schreibzeiger eins erhöht. Zudem wird der Counter der die Anzahl der Bytes im Puffer angibt ebenfalls hochgezählt.
Beim Auslesen wird das gelesen, worauf der Lesezeiger gerade zeigt, danach wird dieser eine Speicherstelle weitergeschoben und dann der Counter um eins runtergezählt.
Erreicht einer der Zeiger das Ende des Arrays, wird er auf das erste Element zurückgesetzt. So kann man das Array unendlich lange mit Daten befüllen und wieder auslesen, man sollte nur darauf achten, dass man seine eigenen Daten nicht überschreibt oder liest wo es nichts gibt (dafür der Counter).

Die Kreisberechnung wird natürlich nur aufgerufen, wenn der FiFo noch ausreichend Platz hat. Die Kreisberechnung liefert bei einem Aufruf immer den nächsten Punkt zurück, daraufhin muss dann noch geprüft werden, ob mit diesem Schritt das Ziel dann erreicht ist oder eben nicht.
Meine FiFo-Implementation verhindert ferner ein Überlaufen, ist dieser voll wird ein false (0 bei C) zurückgegeben

Zitat:

Zitat von urbanbruhin
Ach ja, also bei der kommunikationsgeschichte komm ich noch nicht 100% nach, aber das liegt daran dass ich das Grundprinzip der seriellen Datenübertragung noch nicht ganz verstanden habe, also in welcher Form ich die Daten empfange usw. Werde mal schauen ob ich da was gutes zum lesen finde...

RS232 überträgt die Daten byteweise, daher ist mein "Protokoll" oder besser gesagt, Containerformat, entsprechend ausgelegt.
Ein ATMega (also auch dein M128) hat einen zweistufigen Eingangspuffer. Der vor dir verborgene Teil enthält die Bits, die gerade empfangen werden.
Sobald ein Byte "voll" ist, landet es im UDRn, dem USART Data Register n (wobei n beim Mega128 null oder eins sein kann, der M128 hat nämlich zwei USARTs). An dieser Stelle kann ein Interrupt aufgerufen werden, der die Daten in eine Variable deiner Wahl transportiert, oder du pollst deinen UART auf neue Daten und blockierst dabei die Ausführung anderer Dinge.

100nF 3. Okt 2008 23:35

Re: Ablauf für Fräsmaschine programmieren
 
also ich hab jetzt nochmal kurz an meinem "code" gearbeitet. fehlt natürlich noch sehr vieles, hab einfach mal angefangen den code abzuändern.
Delphi-Quellcode:
var
  Befehl_vorhanden,
  Maschine_Bereit: boolean;

  Schritte_X,
  Schritte_Y,
  Schritte_Z,
  Geschwindigkeitsfaktor,
  GF_Down_X,
  GF_Down_Y,
  GF_Down_Z: Integer;

  Sende_FiFo,
  Empfangs_FiFo,
  G-Code_FiFo: Array;

procedure main; // die Hauptprozedur des Programmes
begin
  Alles_Initialisieren; // z.B. die Serielle Schnittstelle initialisieren, Pins auf Ausgang schalten usw.

  begin Endlosschleife  // Läuft ewigs durch, hört nie auf =)
    If Empfangs_FiFo_leer then // Wenn der Buffer leer ist...
    begin
      Befehl_vorhanden := false; // Wird die Variable auf false gesetzt...
      RS232_Senden(Warte_auf_Befehl); // ...und dem PC mitgeiteilt dass er wieder Daten senden soll
    end
    else
      Befehl_vorhanden := true; // Wenn der Buffer nicht leer ist, wird die Variable auf true gesetzt

    If Empfangs_FiFo_voll then // wenn der Buffer voll ist...
      RS232_Senden(PC_muss_warten); //... wird dem PC mitgeteilt dass er warten muss mit der Übermittlung

    Befehl_auswerten; // ...wird der Befehl ausgewertet (siehe weiter unten)

    if Befehl_Vorhanden and Maschine_Bereit then // Wenn ein Befehl vorhanden ist und kein Fräsvorgang in arbeit ist...
      Run_G-Code;
  end;
end;


procedure RS232_Senden(Sendedaten);
begin
  Sende_FiFo_mit_Sendedaten_füllen; // Was in der Zwischenzeit empfangen wurde, wird in den Buffer geladen

  // Der Sende_FiFo wird wieder geleert sobald die Übertragung per Interrupt stattgefunden hat
end;

procedure RS232_Empfangen; // Wird per Interrupt ausgelöst (Sobald etwas empfangen wird)
begin
  Empfangs_FiFo_mit_Empfangsdaten_füllen; // Was in der Zwischenzeit empfangen wurde, wird in den Empfangs_FiFo geladen
end;

procedure Befehl_auswerten; // Wertet den Empfangenen Befehl aus
begin
  Empfangs_FiFo_auslesen; // Der Empfangsfuffer der RS232 wird ausgelesen
  Empfangs_FiFo_splitten(Startbyte, Message_Size, Command_Byte, Payload, Command_Byte, Checksumme, Stopbyte); // Das Telegramm wird in die einzelnen bestandteile zerlegt
 
  // Startbyte usw überprüfen...

  Case Command_Byte of // Wenn der Befehl...
    Kalibrieren: Prozedur_Kalibrieren(Payload); // ...eine Kalibrierung ankündigt, wird diese ausgeführt
    G-Code: G-Code_FiFo_hinzufügen(Payload); //...ein G-Code ankündigt, wird dieser in den G-Code_FiFo geschrieben
  End;
end;

procedure Run_G-Code(G-Code); // Der Empfangene G-Code wird verarbeitet
begin
  Befehl_auslesen; // Liest aus dem Payload heraus, ob M0, M1, G00, G01 usw.
 
  Case G-Code.Befehl of // Enthält "M0", "G00" usw.
    M0: ... ;
    M1: ... ;
    ...
    G00: Fahre_Zu_Position(Payload.X, Payload.Y, Payload.Z, schnell); // Die Fräse muss schnell an die angekündigte Position fahren
    G01: Fahre_Zu_Position(Payload.X, Payload.Y, Payload.Z, schnell); // Die Fräse muss an die angekündigte Position fahren
    ...
  end;

  G-Code_FiFo_Anweisung entfernen; // Der ausgeführte Befehl wird aus der FiFo entfernt - oder muss man das nicht machen?
end;


procedure Fahre_Zu_Position(X, Y, Z, Geschwindigkeit); // Die Position X, Y, Z wird mit der entsprechenden Geschwindigkeit angefahren
begin
  Maschine_Bereit := false; // Damit Keine zweite Befehlsauswertung stattfinden kann

  Schritte_X := X - Istposition_X; // Die Differenz zwischen Soll- und Istposition ermitteln
  Schritte_Y := Y - Istposition_Y;
  Schritte_Z := Z - Istposition_Z;

  Geschwindigkeitsfaktor_berechnen; // Die Wartezeit zwischen den einzelnen Pins ein-/ausschalten berechnen

  GF_Down_X := Geschwindigkeitsfaktor; // Variable setzten
  GF_Down_Y := Geschwindigkeitsfaktor;
  GF_Down_Z := Geschwindigkeitsfaktor;

  timer_Intervall := Geschwindigkeit; // Den Intervall für die Geschwindigkeit

  timer_aktivieren; // Der Timer wird aktiviert
end;

procedure Timer;
begin
  GF_Down_X := GF_Down_X - 1; // Die Wartezeit wird immer eines weniger
  GF_Down_Y := GF_Down_Y - 1;
  GF_Down_Z := GF_Down_Z - 1;
 
  if GF_Down_X = 0 then // Wenn die Wartezeit gleich Null ist...
  begin
    If Pin_X_Ein then // ...Wird der Takt-Pin getoggelt
      Pin_X_aus
    else
      Pin_X_ein;
   
    GF_Down_X := Geschwindigkeitsfaktor; // ...wird die Wartezeit wieder heraufgesetzt

    Schritte_X := Schritte_X - 1; // ...wird die Anzahl zu erledigender Schritte verringert
  end;

  if GF_Down_Y = 0 then // Wenn die Wartezeit gleich Null ist...
  begin
    If Pin_Y_Ein then // ...Wird der Takt-Pin getoggelt
      Pin_Y_aus
    else
      Pin_Y_ein;
   
    GF_Down_Y := Geschwindigkeitsfaktor; // ...wird die Wartezeit wieder heraufgesetzt

    Schritte_Y := Schritte_Y - 1; // ...wird die Anzahl zu erledigender Schritte verringert
  end;

  if GF_Down_Z = 0 then // Wenn die Wartezeit gleich Null ist...
  begin
    If Pin_Z_Ein then // ...Wird der Takt-Pin getoggelt
      Pin_Z_aus
    else
      Pin_Z_ein;
   
    GF_Down_Z := Geschwindigkeitsfaktor; // ...wird die Wartezeit wieder heraufgesetzt

    Schritte_Z := Schritte_Z - 1; // ...wird die Anzahl zu erledigender Schritte verringert
  end;
     
  If (Schritte_X = 0) and (Schritte_Y = 0) and (Schritte_Z = 0) then //wenn alle Schritte (X, Y, Z) ausgeführt wurden...
  begin
    Maschine_Bereit := true; //...wird die Bereitschaft auf true gestellt damit der nächste Befehl verarbeitet werden kann
    Timer_deaktivieren; // ...wird der Timer deaktiviert
  end:
end;
naja, ist bestimmt nocht nicht so wie du dir das vorstellst, aber ich geh jetzt erstmal schlafen^^

mfg
Urban

EDIT: hab den code noch kurz bisschen abgeändert :D

markusj 4. Okt 2008 00:32

Re: Ablauf für Fräsmaschine programmieren
 
Ich schmier mal schnell einen Pseudo-Pseudo-Code hin, damit du dich nicht so quälen musst. Du bist nämlich noch ein gutes Stück von mir entfernt.
Es stellt sich aber dennoch die Frage, ob es Sinn macht, meine Gedankengebäude nachzuprogrammieren wenn ich das Konzept noch nicht einmal vollständig durchdacht habe.

Noch ein Hinweis zu deiner Maschine_Bereit Sache: Sinn und Zweck der Fifos ist es doch gerade, DAS unnötig zu machen. Die Maschine soll nahtlos ihren Job abarbeiten, ohne beim PC immer nerven zu müssen. Die CNC baut sich einen FiFo auf und arbeitet DEN schrittweise ab.
Der PC selbst soll möglichst wenig mit allem zu tun haben, was Verzögerungen bewirkt, optimal ist es, wenn die Motion-Control schon nach dem letzten Schritt "weiß" wo sie als nächstes hinfährt, dieses Element aus dem Motion-Fifo holt und beim nächsten Timer-Interrupt einfach weiterarbeiten kann.

Delphi-Quellcode:
var rx_fifo, tx_fifo, gcode_fifo, motion_fifo : TFifo;
var rx_errors, decode_state : byte;

procedure main; //alles hat einen anfang
  begin
  while (true) do
    begin
    command_decode;   //kommandodekodierung
    gcode_preprocessor;   //g-code-interpretierung;
    end;
  end;
 
 procedure rs232_receive;
  begin
  if not rx_fifo.add(rx_register) then
    rx_errors := rx_errors or FEHLERCODE_FÜR_VOLLEN_FIFO;
    else
    begin
    if rx_fifo.size-5 < rx_fifo.count then
      rx_errors := rx_errors or WARNCODE_FÜR_FAST_VOLLEN_FIFO;
    end;
  end;
 
procedure rs232_transmit;
  var out_buf : byte;
  begin
  if tx_fifo.get(@out_buf) then
    tx_register = out_buf
    else disable_rs232_transmit_interrupt;
  end;
 
procedure command_decode;
  begin
  case decode_state of
    wait_for_startflag : //eingangsfifo nach startflag durchsuchen und bei gefundenem startflag die nächste stufe scharfschalten
    read_message_size : //sobald ein byte gekommen ist, als message_size interpretieren + nächsten schritt aktivieren
    receiving_telegram : //warten (nachsehen, danach funktion verlassen wenn nicht alles da) bis alle angekündigten bytes da sind, danach nächster schritt
    check_stopflag : //prüfen ob das telegramm tatsächlich da ein ende hat wo es eines haben sollte, wenn ja: weiter
    check_cmd_code : //doppelten commandocode prüfen, weiter wenn ok,
    check_sum : //checksumme prüfen, weiter wenn ok
    launch_parser : //payload an den parser übergeben, z.bsp für gcode
    rst_wait_stopflag : //wenn ein fehler aufgetreten ist, überspringen wir hier solange eingehende bytes, bis ein stopflag dabei ist, danach schritt eins scharfschalten
  if rx_errors <> 0 then //irgendwann beim dekodieren oder empfangen ist ein fehler aufgetreten, das teilen wir dem master mit
    begin
    if transmit_command(receive_error,@rx_errors,sizeof(rx_errors)) then
      rx_errors := 0; //transfer erfolgreich, wir können den fehler löschen.
    end;
  end;
 
procedure gcode_preprocessor;
  begin
  //mach was sinnvolles mit dem gcode, abhängig vom aktuellen zustand berechnungen anstelle, neue codes aus dem gcode_fifo entnehmen und interpretieren und dann in den motion_fifo einfügen oder oder
  end;
 
procedure timer1_interrupt;
  begin
  //zu toggelnde pins ermitteln
  //toggeln
  //distanzen updaten etc.
  //zurücktoggeln
  //wenn job done, neuen nachladen oder in idle-mode gehen
  end;
mfG
Markus

100nF 4. Okt 2008 09:45

Re: Ablauf für Fräsmaschine programmieren
 
Zitat:

Es stellt sich aber dennoch die Frage, ob es Sinn macht, meine Gedankengebäude nachzuprogrammieren wenn ich das Konzept noch nicht einmal vollständig durchdacht habe.
ich denke das ist nicht so schlecht, denn so sehe ich mal andere (bessere) möglichen Varianten, wie man das lösen könnte.
Ich will ja auch nicht einfach nur deinen Code 1:1 abschreiben, doch beim Grundgerüst komme ich ohne Hilfe wohl nirgens hin, und wenn ich das habe kann ich vermutlich den Rest relativ selbständig machen.
Und wenn dein Konzept aus irgendeinem Grund nicht funktionieren würde, dann wäre das auch halb so wild weil ich auch so schon einiges lernen konnte!

Und danke für deinen "Code"!

Vielleicht werde ich dieses Wochenende mal mit dem Programmieren beginnen...

Ach ja, hast du deine Schrittmotorplatinen (L297/L298) selbst gemacht? Ich hab nämlich mal 3 Platinen mit der "Direct-Toner"-Methode gemacht, doch nur eine davon war nach langem nachbessern funktionstüchtig :?
Danach hatte ich die Schnauze voll von dem riesen Aufwand, und hab mal nach Platinen-Ätz-Service gesucht. Da hab ich aber gemerkt dass das vom Preis her überhaupt nicht in Frage kommt. Also wenn du deine Platinen selbst gemacht hast, würdest du auch für ein bisschen Geld nochmal 3 von diesen machen? :angel:

mfg
Urban

EDIT: Ich habe ja mal was von Threads geschrieben. Nun hab ich in der Hilfedatei des C-Controls mal bisschen gelesen, und ich würde meinen dass das eigentlich eine gute Sache ist für diese Anwendung. z.B. Das Senden/Empfangen der RS232 kann man doch sehr gut in einem Thread plazieren denke ich mal. Und vielleicht auch deine "command_decode"-Prozedur. Naja, wenn ich schon die Möglichkeit habe, Threads zu benutzen, sollte ich es mir wohl auch zu nutzen machen :D


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:23 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz