Ich möchte von der Seriellen eine gewisse Anzahl von Zeichen einlesen, dann mit strcmp auf tx.txt=, ty.txt= und tz.txt= vergleichen.
Wenn einer dieser 3 Sätze erkannt wurde, brauche ich die Zeichen die nach diesen Sätzen kommen, bis 3xFF kommen.
Dafür müsste ich die Position (Pointer) haben an welcher Stelle der Satz gefunden wurde.
Hier jedoch habe ich keine Ahnung, wie man das macht.
Mein Listing sieht so aus:
char x[] = "......................"; <-- für das LCD
void setup ( void )
{
Serial.begin(115200);
}
void loop ( void )
{
char inSerial[128];
int i = 0;
if (Serial.available()> 0)
{
while ((Serial.available() > 0) & (i < 127))
{
inSerial[i] = Serial.read();
i++;
}
inSerial[i] = '\0';
Check_Protocol(inSerial);
}
}
void Check_Protocol(char inStr[])
{
if (!strcmp(inStr, "tx.txt=")== 0)
{
// hier müssen die nächsten Zeichen aufs LCD geschrieben werden bis 3x$FF kommen
}
if (!strcmp(inStr, "ty.txt=")== 0)
{
// hier müssen die nächsten Zeichen aufs LCD geschrieben werden bis 3x$FF kommen
}
if (!strcmp(inStr, "tz.txt=")== 0)
{
// hier müssen die nächsten Zeichen aufs LCD geschrieben werden bis 3x$FF kommen
}
}
die "57,998 27,198 11,611" sind die Daten die ich in einen String fürs LCD erhalten möchte.
diese Zeichen ˇˇˇ sind 3x$FF und sind als Datensatz-Ende-Markierungen gedacht, leider keine LF/CR Zeichen da.
Wie bekomme ich die "Positionen" im String von den Werten und den 3x$FF's?
Bei fester Position kannst Du inSerial+länge nehmen (Pointer-Arithmetik), oder mit strchr() nach = oder " suchen, und dann noch 1 oder 2 draufaddieren.
Das sieht mir ziemlich nach Nextion aus, oder wer benutzt die drei 0xFF's noch?
void loop ( void ) {
char inSerial[128];
int i = 0;
if (Serial.available()> 0)
Den Buffer lokal zu loop zu machen ist ein fataler Fehler.
Du hast nur das Glück, dass der immer an der gleichen Stelle liegt.
Ausserdem wird - weil auch i lokal zu loop ist - immer nur das erste Zeichen beschrieben.
ja, das sind Daten für eigentlich ein Nextion, richtig.
Das nur das erste Zeichen beschrieben wird, stimmt so nicht, denn ich bekomme in inStr ja die vollen 128Bytes und strcmp findet auch den Text tx.txt= !
Aber ich habe inSerial[128] nun als global umgändert.
Danke für den Tip!
i wird ja in der while-schleife hochgezählt:
while ((Serial.available() > 0) & (i < 127))
{
inSerial[i] = Serial.read(); //read data
i++;
}
Aber wie bekomme ich die Position im String?
Ich brauche die Position von dem tx.txt= und die von den 3 FF's
Auch wird wie fast immer nicht beachtet wie langsam Serial selbst mit so hohen Baudraten ist. Du kannst nicht innerhalb einer while-Schleife alle Daten einlesen wenn sie gerade gesendet werden. Da kommt ein Zeichen an und die Schleife ist zu Ende.
Die Endzeichen darfst du schon gar nicht abspeichern. Du musst solange einlesen bis das Endzeichen dreimal da war. Dann den String terminieren und verarbeiten.
Ich habe mal das Endzeichen einstellbar gemacht. Dadurch kann man das auch einfach mit dem seriellen Monitor testen. Hier ist es dreimal 'Q'
Für den Vergleich des Anfangs-Strings nimmt man strncmp(). Nicht strcmp()! Letzteres vergleicht den kompletten String. Das ist falsch. strncmp() vergleicht die ersten N Zeichen. Dann einfach Zeiger-Arithmetik, da die Länge des Kommando-Strings ja bekannt ist. Man vergleicht die ersten 7 Zeichen. Dann kommt man mit einer Addition +7 auf das Zeichen danach
Beachte den Unterschied zu deinem Code. Ich habe zwar eine while-Schleife, aber die Funktion wird solange aufgerufen bis alles da ist. Wenn nichts da ist kehrt sie sofort nach loop() zurück.
Lass erst mal das Display weg und teste das so mit dem Serial Monitor Da kannst du halt nicht 0xFF eingeben, aber man kann auch mal kurz ein druckbares Zeichen missbrauchen.
mega-hz:
nein, die "Ende-Kennung" sind dreimal FF!
Das war Test-Code!
Ich habe es doch deutlich gemacht, dass man das einstellen kann:
const unsigned char END_CHAR = 'Q';
Wird zu:
const unsigned char END_CHAR = 0xFF;
Ich habe nur erstens mal kein Nextion Display. Also habe ich allgemeinen Code geschrieben. Zweitens ist es auch für dich erst mal praktisch dass so zu testen. Einfach einen UNO nehmen und den seriellen Monitor öffnen. Fertig. Oder du nimmst ein Terminal Program wie HTerm. Da kannst du auch Binär-Daten senden und nicht nur ASCII.
Ja, daß das "Q" z.Z. das Ende Zeichen ist, ist klar, aber es müsste auf 3x Q abgefragt werden!
Wird es ja
if (c == END_CHAR)
{
endLine++;
}
...
if (endLine == 3)
{
}
Ist zugegeben sehr primitiv. Es wird nicht abgefragt ob die Zeichen wirklich dreimal direkt hintereinander kommen. Aber wenn das Endzeichen sonst im Datenstrom nicht auftaucht ist das denke ich ok. Man könnte natürlich noch abfragen ob endLine > 0 ist UND ein anderes Zeichen da ist und dann entsprechend darauf reagieren. Ich glaube aber nicht dass das unbedingt nötig ist.
Ich habe es gerade sowohl mit dem seriellen Monitor und mit HTerm mit 0xFF getestet. Es geht. Was ich aber oft habe ist dass die erste Übertragung nicht erkannt wird und danach geht es immer.
ahh, mist, war noch eine Zeile aus dem alten code mit drin, ja, das funktioniert!
Weil ich auch bedenken wegen der Geschwindigkeit des UNOs mit 115200 Baud hatte,
habe ich dies sowieso auf nem ESP8266 drauf, der kann ja mit seinen 160Mhz schon etwas mehr.
Ich probier das nun mal mit dem TFT und FF's...
Ich würde ein Nextion nicht auf einem Arduino simulieren wollen.
das will ich auch nicht....
Es ist so, Albert programmiert ein schönes Frontend für den GRBL-CNC-Controller SerialComCNC und hat 2.Serielle für ein Nextion-Display implementiert.
Über diese werden o.g. Daten verschickt.
Aber es ist auch möglich, selber Daten zu verschicken die z.B. nach nem Druck auf nen Taster kommen sollen, wie z.B. #GCG91G1X1< um die X-Achse zu verfahren.
Da sowohl die aktuellen XYZ Daten rüberkommen als auch das man selber Befehle schicken kann,
ist es ne Prima Sache um ein mobiles Hand-Einricht-Werkzeug zu realisieren!
Ich benutze ein kleine ILxxx TFT, das blöde ist, ich weiss nicht wie man eine Zeile so neu "printen" kann, ohne das der vorige Inhalt da stehen bleibt!
Immer ein tft.fillScreen(ILI9341_BLACK); ausführen flackert ganz schön....
mega-hz:
Ich benutze ein kleine ILxxx TFT, das blöde ist, ich weiss nicht wie man eine Zeile so neu "printen" kann, ohne das der vorige Inhalt da stehen bleibt!
Setze eine konstante Breite fest und fülle die Differenz mit Leerzeichen auf. Vor allem für Zahlen gibt es da fertige Funktionen in C. Für Integer kann man es auch leicht selbst schreiben.
Meinst Du 250.000 oder 500.000 Baud auf dem ESP oder Arduino?