GCODE stream Zeile mit sscanf() richtig interpretieren.
-
Hallo SeppJ.
Sehr vielen Dank für deine so schnelle Antwort, die mir auch schon ein ganzes Stück weiter geholfen hat.@SeppJ sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
Damit wir uns auch richtig verstehen: Da steht also so etwas wie "G0 -0.123 4.56"?
Ja genau so ist es. Eine Zeile sieht exakt so aus:
G0 X-0.123 Y0.456 bzw. G0 X12.345 Y-22.654 oder G0 X-15.234 Y8.678
und in der darauffolgenden Zeile der GCODE-Datei kommt immer die Angabe für Z
G0 Z0.789 oder G0 Z-1.234 wobei der Wert für Z bei meiner Stickmaschine ignoriert werden kann.
Ich erkenne nur das in der Zeile kein X und Y ist und somit muss es Z sein und die Nadel wird dann einmal gestochen, dann folgt in der nächsten Zeile wieder X-Y Angaben die von der Maschine ausgeführt werden usw. bis am Ende der GCODE Datei M30 als Stoppzeichen erkannt wird.Dein Vorschalg das Auslesen mit "%lf" zu machen scheint zu funktionieren. Ich konnte damit zumindest die Werte in die beiden Variablen "x_wert1" und "y_wert1" übergeben und die Abfrage:
if (ZahlLesen == 2)
funktionert jetzt auch.
In meinem Programm habe ich mit "Canvas" eine Simulationsdarstellung erstellt und darin werden mir auch die Verfahrwege bereits wieder angezeigt. Allerdings muss ich erst noch die Startposition bzw. 0-Koordinaten von Canvas anders bestimmen. Denn das angezeigte Stickbild liegt zum Teil jetzt außerhalb. Aber das bekomme ich schon hin...Das ist halt immer so ein Problem für einen "Versuchsprogrammierer" wie mich, der einmal im Jahr damit zu tun hat. Weil man erstens nicht die passenden Funktionen kennt, die man benutzen könnte, so wie dein Vorschlag mit fscanf, zum anderen auch keine Information darüber hat, wie man diese Funktionen richtig benutzen kann. So wie deine Idee das "%lf" zu verwenden.
Ich hatte gestern noch im Netz nach sscanf gesucht und auch jede Menge Seiten gefunden. Aber mal so eine richtige Beschreibung was damit eigentlich alles Möglich ist und was all die %... die es da gibt überhaupt machen konnte ich leider nicht finden.
Habe auch im Netz gesehen das es auch noch %s gibt, welches vermutlich für ASCII Strings sein könnte.Ich danke dir SeppJ recht freundlich für die Tolle Idee mit dem %lf welche bereits funktioniert. Den Rest hoffe ich mal, bekomme ich dann auch noch hin. Auch werde ich mir noch das fscanf anschauen um herauszufinden was der Unterschied zwischen sscanf und fscanf ist. Ich denke mal das f steht vielleicht für Float bzw. Fließkommazahl. Aber das werde ich sehen...
Danke für die schnelle Hilfe und besten Gruß Eric.
-
@Eric
sscanf parst einen string; Du liest ja in Deinem Programm erst mal eine Zeile in einen string ein:fgets(OneLine, sizeof(OneLine), stream);
fscanf hingegen parst direkt das File ohne den Umweg über einen string ...
aus:fgets(OneLine, sizeof(OneLine), stream); int ZahlLesen = sscanf(OneLine, "G0 X%ld.%ld Y%ld.%ld", &x_wert1, &x_wert2, &y_wert1, &y_wert2);
wird also:
int ZahlLesen = fscanf(stream, "G0 X%ld.%ld Y%ld.%ld", &x_wert1, &x_wert2, &y_wert1, &y_wert2);
-
@Eric sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
Aber mal so eine richtige Beschreibung was damit eigentlich alles Möglich ist und was all die %... die es da gibt überhaupt machen konnte ich leider nicht finden.
-
Wie lernst du C? Das Format
%f
ist ziemlich grundlegend, ebenso die diversen f/s/(nix)-Versionen der Lesefunktionen. Und du wusstest auch nicht so recht, das C nicht C++ ist.Ich frage, weil du ein recht anspruchsvolles Projekt vor hast, aber da anscheinend Mängel bestehen, wie du die Sprache beigebracht bekommst. Deine Methode kann nicht grundverkehrt sein, da du keine Probleme mit Ablaufsteuerung zu haben scheinst, aber das macht es umso merkwürdiger, wo die anderen Lücken herkommen. Da kann und sollte man etwas verbessern.
-
Danke auch an Swordfish für die klassen Links. Letztendlich kommt man aber immer zu der Seite:CPPREFERENCE die ja wirklich sehr gut zu sein scheint. UND das Beste ist, es gibt diese Seite auch auf deutsch... deutsche Seite. Für diese Seite habe ich mir gleich mal den Link zu den Favoriten gelegt...
Besten Dank auch an Belli, für die Darstellung wie man das mit fscanf richtig nutzen kann.
Also, ich sehe dank eurer Hilfe jetzt erst einmal wieder Licht am Ende des Tunnels. Danke an alle für die super tolle schnelle Hilfe.
-
@Eric sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
es gibt diese Seite auch auf deutsch... deutsche Seite
Ich empfehle dir dennoch, immer die englische Seite zu nutzen, sofern du genügend Englisch verstehst. Einerseits liest sich der maschinenübersetzte Text schlecht, andererseits fehlen z.B. in der hier verlinkten scanf*-Doku in der deutschen Übersetzungen die Beispiele!
-
@Eric sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
UND das Beste ist, es gibt diese Seite auch auf deutsch...
This page has been machine-translated from the English version of the wiki using Google Translate.
Gewöhn' Dich lieber an Englisch.
-
@SeppJ sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
Wie lernst du C?
Leider hatte ich nie die Gelegenheit C so richtig von einem der es kann zu lernen. Habe mir alles selber erarbeiten müssen. Hatte mal so 1995 oder so in der Zeit damit angefangen. Arbeite deshalb auch noch mit Borland C++ Builder der Version 4.0. Ist sehr alt, aber funktioniert zum Glück noch immer...
Das Format
%f
ist ziemlich grundlegend, ebenso die diversen f/s/(nix)-Versionen der Lesefunktionen. Und du wusstest auch nicht so recht, das C nicht C++ ist.Ja das hast du wirklich gut erkannt. Es ist tatsächlich für mich nicht ganz einfach C von C++ zu unterscheiden. Für mich ist C++ die Erweiterung von C. Das es nicht ganz so ist, ist mir aber klar.
Ich frage, weil du ein recht anspruchsvolles Projekt vor hast, aber da anscheinend Mängel bestehen, wie du die Sprache beigebracht bekommst.
Ja, es war und es ist wirklich ein anspruchsvolles Programm und auch mein erstes dieser Größe. Außer ein paar kleinen Programmschnipseln die Werte über UART an einen Mikrocontroller übertragen, habe ich auch noch nicht mehr gemacht.
Deine Methode kann nicht grundverkehrt sein, da du keine Probleme mit Ablaufsteuerung zu haben scheinst, aber das macht es umso merkwürdiger, wo die anderen Lücken herkommen. Da kann und sollte man etwas verbessern.
Natürlich kann man immer etwas Verbessern. Aber das gelingt halt nur, wenn man Fachmänner zu Rate ziehen kann, die mir leider in meinem Privatfeld nicht zur Verfügung stehen. Aber auf der anderen Seite bin ich kein wirklicher Programmierer und das Stickmaschinenprogramm ist eigentlich mein erstes richtig großes Programm welches ich "programmiere". Wahrscheinlich auch mein letztes, wenn es die Zukunft nicht bringen sollte, das man doch wieder etwas besonderes auf PC Seite benötigt, was es so nicht gibt. Ich bin mir aber auch zu 100% sicher, wenn ich den gesamten Programmcode hier einstellen würde, findet man wahrscheinlich in jeder zweiten Zeile etwas, wo ein Fachmann die Hände über dem Kopf zusammen schlagen würde. Wie z.B. in der Reihenfolge solche Gesichtsausdrücke...
Aber letztendlich... es funktioniert doch.
Das ich letztendlich doch etwas mehr über das Digitale weiß, liegt daran, das ich schon seit mehr als 30 Jahren mit Mikrocontrollern rum mache. Damals aber Assembler gelernt hatte, weil C für Mikrocontroller zu diesem Zeitpunkt noch nicht etabliert war und eine Programmierung für den PC nicht weiter von Nöten war... und auch ohne damit zu prahlen, aber in Assembler für Mikrocontroller bin ich König.
Also alles soweit gut. Werde mein Programm jetzt an das neue Format der GCODE-Datei anpassen und Dank eurer tollen Hilfe ist es für die weitere Verwendung in den nächsten Jahren hoffentlich auch weiterhin verwendbar.
Nochmals vielen Danke für die Hilfe und besten Gruß Eric.
-
@Eric
löst das Problem mit den auf 2 Zeilen verteilten zusammengehörenden Daten mit einem Aufruf:while( 3==fscanf(stream,"%*[^X]X%lf%*[^Y]Y%lf%*[^Z]Z%lf",&a,&b,&c) ) printf("%f %f %f\n",a,b,c);
fgets verwendet man, wenn es auf Zeilenumbrüche ankommt, was mit fscanf etwas schwieriger ist.
fgets(OneLine, sizeof(OneLine), stream);
Ist suboptimal, wenn OneLine ein Zeiger ist. (nein, Zeiger und Array sind nicht dasselbe)
Besser ist die explizite Längenangabe:char z[1000]; while(fgets(z,1000,stream)) ...
-
@Belli sagte in GCODE stream Zeile mit sscanf() richtig interpretieren.:
fscanf hingegen parst direkt das File ohne den Umweg über einen string ...
aus:
fgets(OneLine, sizeof(OneLine), stream);
int ZahlLesen = sscanf(OneLine, "G0 X%ld.%ld Y%ld.%ld", &x_wert1, &x_wert2, &y_wert1, &y_wert2);G-Code besteht leider nicht nur aus G0 Zeilen. Man weiß nicht immer was da kommt. Daher ist für den Anfang das Zeilenweise lesen schon ok.
Denn zwischen Zeile 1 und 2 kann noch mit dem String gearbeitet werden.