Hallo,
ich möchte gerne ein Teil eines über den UART empfangenen Strings
vergleichen.
Ändert sich der Teilstring, so soll ein Counter erhöht werden.
sprich ich will den ersten empfangenen String mit compare_string
vgl. wenn beide ungleich sind, soll der Counter erhöht werden.
Allerdings sende ich immer alle von alarm_data empfangenen
Teilstrings...Wäre dankbar, wenn mir hierbei jemand weiterhelfen könnte.
Grüße
Leider schreibst Du nicht, was nun eigentlich das Problem ist.
Du formulierst auch leider etwas ungeschickt. Zum einen ist mit:
>Ändert sich der Teilstring ...
nicht klar, ob Du zwei zeitlich hintereinander eingehende Strings meinst
oder zwei Teilstrings die zusammen hereingekommen sind. Nach erstem
Überfliegen Deines Codes meinte ich, dass das letztere zutrifft.
und in
>Allerdings sende ich immer alle von alarm_data empfangenen>Teilstrings
wird der Variable alarm_data eine Aktivität (das empfangen)
zugeschrieben, was sinnlos ist, denn eine Variable führt nichts aus und
Du sprichst davon das "Du" etwas tust anstelle des Rechners.
Diese drei Punkte sind für sich genommen schon irgendwie pragmatisch
deutbar, eher ungeschickt, bedeuten aber eine Unsicherheit die sich
durch die Anzahl so akkumuliert, dass der ganze Text als Darstellung
zweifelhaft wird.
Wie gesagt: Der Hauptpunkt ist, das das Problem nicht genannt ist.
Auffällig ist aber, dass compare_data keine Daten enthält, wenn Du
strcmp aufrufst, denn die Variable wird auf dem Stack angelegt, so das
höchstens irgendwelche zufälligen Daten dort stehen, aber nichts
"bestimmtes".
Evtl. hast Du hier ein static vergessen. Der Code der Daten in
compare_data umkopiert muss natürlich auch mindestens einmal ausserhalb
der Funktion vorhanden sein.
Noch ein kleiner Verbesserungstip:
Die Schleifen zum umkopieren könntest Du durch strncmp ersetzen.
Mehr fällt mir nicht auf.
Hallo Guru,
sorry, du hast Recht, dass ist wirklich blöd formuliert.
Also im Grunde möchte ich den empfangenen Teilstring(alarm_data) mit dem
vorherigen, in compare_data abgelegten, String vergleichen.
Unterscheidet sich der neue String vom alten (in compare_data abgelegt),
so soll der counter erhöht werden und der neue String in compare
abgelegt werden. Im Grunde immer ein Vgl. mit dem vorherigen String.
Allerdings macht das mein Programm nicht und sendet einfach nur die
aktuellen Strings alarm_data.
Gruß
Aha. Ich hab Dir ja Tips gegeben. Schau sie Dir mal an.
Es gibt zwei Punkte die Du beachten musst:
1. Was macht das Programm wenn zuvor noch garnichts empfangen wurde?
Z.B. unmittelbar nach einem Reset. Du musst die Variable, die den vorher
empfangenen String speichert passend initialisieren. Z.B. mit '\0'.
2. Wie sorgst Du dafür, das der vorher empfangene String gespeichert
bleibt? Hier entweder static oder globale Variable.
>Allerdings macht das mein Programm nicht und sendet einfach nur die>aktuellen Strings alarm_data.
Das könnte auch problemunangemessen formuliert sein. Nach dem Code ist
es ja gerade Absicht, das der aktuelle String in alarm_data gesendet
wird. Ich vermute aber das Problem ist, das der String "jedesmal"
gesendet wird, als wenn er "jedesmal" unterschiedlich ist.
Das hängt mit dem obigen Tip zusammen, das die Variable ihren Inhalt
nicht hält wenn die Funktion verlassen wird. Also fehlt static bzw. die
Deklaration im globalen Namensraum.
Hallo Guru,
zunächst einmal vielen Dank für deine Tipps.
>Der Code der Daten in>compare_data umkopiert muss natürlich auch mindestens einmal ausserhalb>der Funktion vorhanden sein.
Das versteh ich nicht ganz. Weshalb?
stringbuffer ist ja ne globale Variable, von der ich die Daten in
alarm_data kopiere. wenn ein kompletter String empfangen wurde, wird
system_data == 1 und ich springe in die Funktion.
Gut, compare_data habe ich nun mal static gemacht und mit '\0'
initialisiert. Allerdings klappt es immer noch nicht. Hmmmmm, zum Haare
raufen...
> if(system_data == 1)
Wenn system_data in einer ISR (UART RX?) gesetzt wird, muss es bei der
Definition volatile gekennzeichnet sein.
> // 10 Zeichen aus globalem Puffer stringbuffer> // in lokalen Puffer alarm_data kopieren> j = 0;> for( i = 32; i< 42; i++)> {> alarm_data[j] = stringbuffer[i];> j++;> }> alarm_data[j] = '\0'; // <== #1
Zeile #1 zerstört dir das 10. Zeichen im lokalen Puffer!
> char alarm_data[10];> char compare_data[10];> ...> if( strcmp(alarm_data,compare_data) != 0 )
compare_data[] ist nie initialisiert. Der Stringvergleich damit ist
witzlos.
Wenn du immer mit dem vorherigen Aufruf der Funktion vergleichen
willst, benutze eine statische Variable und u.U. einen Defaultwert fürs
leichtere Debuggen
> static char compare_data[10] = "LEER";
>Allerdings klappt es immer noch nicht. Hmmmmm, zum Haare raufen...
Bitte analysiere einmal selbst das Problem. Schau' Dir genau an was
geschieht. Nimm den Simulator, baue Debug-Ausgaben ein. Lies die
Funktionsbeschreibungen, lies ein C-Buch.
Ich habe Dich schon in die richtige Richtung gedreht, aber nun möchte
ich, dass Du alleine läufst.
Noch ein kleiner abschliessender Tip:
Schau Dir genau an, wie der Vergleich beim ersten und bei den folgenden
Malen abläuft, was verglichen wird und was das Ergebnis ist.
So. Ich halte mich dann mal raus.
> if( strcmp(alarm_data,compare_data) != 0 )
Kann schief gehen, wenn in stringbuffer Nullbytes enthalten sind. Die
for-Schleife kopiert 10 Bytes ohne Rücksicht auf Nullbytes. Aber die
strcmp()-Funktion beendet beim ersten Nullbyte in einem der beiden
Puffer den Vergleich.
Hallo,
ich habs hin bekommen und es läuft sowit auch ganz gut.
eine Verständnisfrage habe ich allerdings noch und ich würde mich
freuen, wenn mir diesbezüglich jemand weiterhelfen könnte.
Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in
alarm_data (char alarm_data[15])...
j = 0;
for( i = 32; i < 42; i++)
{
alarm_data[j] = stringbuffer[i];
j++;
}
j++;
alarm_data[j] = '\0';
...und erhöhe mein Puffer dann nochmal um eins, um '\0' reinzuschreiben.
So klappt das auch mit dem strcmp perfekt.
Nur wenn ich jetzt diese Variante wähle, klappt es nicht. Nach
durchlaufen der for-Schleife, ist j=10. Es muss so ja auch funktionieren
indem ich das zusätzliche Zeichen aus dem stringbuffer einfach mit '\0'
überschreibe. Allerdings klappt es nicht so richtig.
j = 0;
for( i = 32; i <= 42; i++)
{
alarm_data[j] = stringbuffer[i];
j++;
}
alarm_data[j] = '\0';
Welchen Denkfehler mach ich da, ich komm nicht drauf
Hallo Serieller,
ich hab aber char alarm_data[15]!
>Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in>alarm_data (char alarm_data[15])...
> ich hab aber char alarm_data[15]!
Wusste ich nicht. In den bisherigen Fragen tauchte immmer ein Array mit
Größe 10 auf.
>Wenn ich folgendes ausführe, lade ich ja zunächst meine Daten in>alarm_data (char alarm_data[15])...
Dieses Codestück habe ich in deinen Fragen noch nie gesehen.
Der Code oben in Variante 2 kopiert 11 Zeichen aus stringbuffer ab
Position 32 bis einschliesslich 42 nach alarm_data und schliesst
alarm_data mit einem Nullbyte ab.
Deine These "Es muss so ja auch funktionieren indem ich das zusätzliche
Zeichen aus dem stringbuffer einfach mit '\0' überschreibe." ist falsch.
Das Nullbyte wird in obigem Code angehängt und überschreibt nicht.
Aha, ok.
Sprich, bei einem Buffer alarm_data[15]...
>j = 0;>for( i = 32; i < 42; i++)>{> alarm_data[j] = stringbuffer[i];> j++;>}> j++> alarm_data[j] = '\0';
... müsste ich nicht noch zusätzlich
> j++> alarm_data[j] = '\0';
ausführen/schreiben, da das automatisch gemacht wird...VG und vielen
Dank für deine Antworten