Serielle Kommunikation / auswerten

Gast #4973386
Hallo,

ich kommuniziere seriell mit einem Modul.
Dazu muss ich auch die Antwort richtig auswerten.

In manchen Beispielen im Netz wird einfach davon ausgegangen das das 
Modul sich wie erwartet verhallt, das ist aber Mist wenn mal ein Fahler 
auftritt.

In dem Beispiel wird es z.B. so gemacht wenn auf eine Antwort gewartet 
wird:
1
while (!sSerial.find("OK"));

das ist aber Mist da es vorkommen kann das Error zurück kommt.

Wie kann ich es in ähnlich einfacher Art umbauen das unterschieden wird 
ob nun OK oder ERROR kommt?
(Firma: Vescomp) #4973405
Lukas schrieb:
> CR LF kommt ja immer zum Schluss, das wertet aber nicht ERROR oder OK
> aus.

 Natürlich kommt das zum Schluss - vorher kannst du ja auch nichts
 auswerten - verstehe nicht wie du das sonst auswerten willst ?
 Zeichen für Zeichen ?

 Normallerweise schreibt man alles in einen Buffer bis CR/LF kommt,
 erst dann wird der Buffer ausgewertet.
Gast #4973406
Lukas schrieb:
> CR LF kommt ja immer zum Schluss, das wertet aber nicht ERROR oder
> OK
> aus.

Nein, das Auswerten sollte ja auch du machen, aber erst, nachdem du 
CR/LF empfangen hast. Du pufferst also so lange, bis CR/LF kommt (oder 
eine maixmale Anzahl Zeichen empfangen wurden), und dann wertest du aus. 
Einen Timeout würde ich auch noch vorsehen. Du weißt ja nicht, was alles 
schiefgeht...
Gast #4973513
Bei Modulen, die mit Text-Kommandos (z.B. AT-Befehle) gesteuert werden, 
mache ich das immer so:

Ich sende den Befehl, danach sammle ich die Antwort in einem Ringpuffer, 
der mindestens so groß ist, wie die gewünschte Antwort. So einen Puffer 
hat man ja ohnehin in der Regel wenn man mit Interrupts arbeitet.

Dann warte ich eine gewisse Anzahl Millisekunden bis die gewünschte 
Antwort irgendwo im Puffer liegt. Danach warte ich zusätzlich so lange, 
bis 100ms lang Stille Herrscht (nichts weiter dazu kommt).

Wenn die erwartete Antwort nicht rechtzeitig kommt, melde ich das als 
Fehler.

Das Zusätzliche Warten auf Stille sorgt dafür das der oder die 
Zeilenumbrüche nach dem Ok auch noch abgeholt werden und dass sich die 
Kommunikation sich nach einer unerwarteten Störung wieder zuverlässig 
einpendelt. Kostet natürlich auch Performance - man muss sich halt 
überlegen, was wichtiger ist.

Ich habe damit viel bessere Erfahrung gemacht, als auf irgendwelche 
Zeilenumbrüche zu warten, deren Format vielleicht sogar unklar ist oder 
sich von Firmware Version zu Version ändert. Außerdem bekomme ich so 
keinen bösen Absturz, wenn das Modul mal mit einer viel längeren Antwort 
daher kommt, als ich erwartet hatte.
(Firma: Vescomp) #4973555
Stefan U. schrieb:
> Dann warte ich eine gewisse Anzahl Millisekunden bis die gewünschte
> Antwort irgendwo im Puffer liegt. Danach warte ich zusätzlich so lange,
> bis 100ms lang Stille Herrscht (nichts weiter dazu kommt).

 Ja, das macht sich besonders gut bei GPS Meldungen aus, vor allem
 da alle hintereinander kommen und erst danach eine Pause...


> Ich habe damit viel bessere Erfahrung gemacht, als auf irgendwelche
> Zeilenumbrüche zu warten, deren Format vielleicht sogar unklar ist oder
> sich von Firmware Version zu Version ändert.

 Zeilenumbruch ist und bleibt immer Zeilenumbruch, da kann sich nichts
 ändern.
Gast #4973630
Marc V. schrieb:
> Natürlich kommt das zum Schluss - vorher kannst du ja auch nichts
>  auswerten - verstehe nicht wie du das sonst auswerten willst ?

Man könnte, unabhängig von <cr><lf>, natürlich auch gucken, ob vom Gerät 
die Buchstabenfolge OK oder ERROR kommt, z.B. mit einer kleinen FSM
(Firma: Vescomp) #4973678
Wolfgang schrieb:
> Man könnte, unabhängig von <cr><lf>, natürlich auch gucken, ob vom Gerät
> die Buchstabenfolge OK oder ERROR kommt, z.B. mit einer kleinen FSM

 Dazu müsste man (in der ISR) viel mehr Abfragen machen, sowohl auf
 bestimmte Zeichen als auch auf deren Reihenfolge.

 Und egal ob OK oder ERROR kommt, trotzdem muss CR/LF abgewartet werden,
 damit sowohl diese als auch die nächste Meldung bearbeitet werden kann.
Gast #4974060
Manche Module haben es gar nicht gerne, wenn man das nächste Kommando 
sendet, bevor die vorherige Antwort komplett beendet ist (mitsamt aller 
Zeilenumbrüche).
#4974100
@Wolfgang (Gast)

>Man könnte, unabhängig von <cr><lf>, natürlich auch gucken, ob vom Gerät
>die Buchstabenfolge OK oder ERROR kommt, z.B. mit einer kleinen FSM

Das KÖNNTE man nicht nur, das MUSS man sogar, wenn man eine solide 
Software jenseits der Fricklerszene schreiben will.
(Firma: Vescomp) #4974273
Falk B. schrieb:
>>Man könnte, unabhängig von <cr><lf>, natürlich auch gucken, ob vom Gerät
>>die Buchstabenfolge OK oder ERROR kommt, z.B. mit einer kleinen FSM

> Das KÖNNTE man nicht nur, das MUSS man sogar, wenn man eine solide
> Software jenseits der Fricklerszene schreiben will.

 Aha.
 Das erweist sich als besonders praktisch wenn 20 oder mehr verschiedene
 Antworten zu erwarten sind.

 Jedes ankommende Zeichen auf sinnvoll oder nicht zu prüfen, ist
 absoluter Schwachsinn, einerseits wegen der benötigten Zeit und
 andererseits wegen der benötigten Tabellen zum Vergleich.

 Prüfen auf:
  1) Timeout
  2) Pufferüberschreitung
  3) Ende der Nachricht
 Ist das, was man jenseits der Fricklerszene machen MUSS.

 Da du mit Programmieren und besonders mit der Logik auf Kriegsfuss
 zu stehen scheinst, will ich versuchen, dir das zu erklären:

 Falls man in der ISR jedes Zeichen prüft, ergibt das bei nur 4
 möglichen Antworten (als Beispiel) schon einen recht schönen Baum.
 Als Beispiel: OK, READY, ERROR, ERFOLG.
 Bei 2 empfangenen Zeichen (E und R) weiss man immer noch nicht, um
 was für eine Meldung es sich handelt, es steht nur fest, dass kein
 Fehler in den bisher empfangener Zeichenfolge vorliegt.
 Also werden jedesmal die bisher empfangenen Zeichen von neuem mit
 möglichen Antworten verglichen, etwa so:
1
 Ist erstes char ein "O" ? -ja-> Ist zweites char ein "K" -> ja es ist, und was jetzt ?
2
        | nein
3
       \/
4
 Ist erstes char ein "R" ? -ja-> Ist zweites char ein "E" ? -> ja, jetzt noch 3 Mal dasselbe wiederholen
5
        |                                                      und trotzdem auf CR/LF warten...
6
        | nein
7
       \/
8
 Ist erstes char ein "E" ? -ja-> Ist man wirklich so Blöd, um das alles weiter in der ISR zu machen ?
9
        | nein
10
       \/
11
  FEHLER -> LOL. Flag setzen, auf CR/LF oder Timeout warten, Antwort löschen...

 P.S.
 Wie schon gesagt:
 Ob mit oder ohne Fehler - ein CR/LF oder Timeout muss sowieso
 abgewartet werden - man kann keine Antwort senden bevor die Meldung
 komplett empfangen worden ist oder ein Timeout zugeschlagen hat...

 P.P.S.
 Im Gegensatz dazu, wird bei der Bearbeitung in der main() nur
 einmal gerade nach unten durchgeprüft, nicht jedesmal von neuem.
Gast #4974416
>  etwa so

Genau das macht die strcmp() Funktion ohen großartige Klimmzüge. 
Voraussetzung ist lediglich, dass der Puffer ein Byte größer ist, als 
die größte Antwort, die man auswerten will, damit man eine 0 als 
String-Terminator hinten dran hängen kann.
#4974433
@ Marc Vesely (Firma: Vescomp) (logarithmus)

>>>Man könnte, unabhängig von <cr><lf>, natürlich auch gucken, ob vom Gerät
>>>die Buchstabenfolge OK oder ERROR kommt, z.B. mit einer kleinen FSM

>> Das KÖNNTE man nicht nur, das MUSS man sogar, wenn man eine solide
>> Software jenseits der Fricklerszene schreiben will.

> Aha.
> Das erweist sich als besonders praktisch wenn 20 oder mehr verschiedene
> Antworten zu erwarten sind.

Das mit dem sinnerfassenden Lesen muss du noch ein wenig üben. Mein 
Kommentar bezog sich darauf, daß man die ANTWORTEN im allgemeinen mit 
einer FSM prüfen muss. Vor einzelnen Zeichen steht da nichts.


> Da du mit Programmieren und besonders mit der Logik auf Kriegsfuss
> zu stehen scheinst, will ich versuchen, dir das zu erklären:

Spar dir deine wertvolle Zeit, du trägst nur Eulen nach Athen ;-)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.