Forum: Mikrocontroller und Digitale Elektronik Bytes gehen in uC UART Ausgang zu Linux-Rechner "verloren"


von Tom (Gast)


Lesenswert?

Hallo miteinander

Ich benutze einen TMS320 Mikrocontroller um den Ausgang eines Hall 
Sensor periodisch zu messen. Die drei Messwerte (16bit) sende ich 
mittels UART an einen PC mit einer Frequenz von 1kHz (d.h. Messwerte 
werden je alle 1ms übertragen, UART Baudrate ist 460800). Zum Auslesen 
auf dem PC benutze ich Putty.

Nach jeder Messung sende ich ein Frame mit folgendem Format:

0x55 0x55 [Byte0][Byte1][Byte2][Byte3][Byte4][Byte5]

Die beiden erste bytes (0x55) dienen dabei dem framing.

Wenn ich die Daten nun auf Linux analysiere, fällt mir auf, dass von 
Zeit zu Zeit ein byte verloren zu gehen scheint, d.h. ein Frame enthält 
nur 7 Bytes anstelle von 8. Typischerweise sieht ein Datenstream im 
post-processing dann so aus:

Hinweis: Die Framestart-Bytes 0x55 werden als U angezeigt
1
bytearray(b'UU\x04\x00\x01\x00\xf7\xff')
2
bytearray(b'UU\x01\x00\x03\x00\xf4\xff')
3
bytearray(b'UU\xfd\xff\x06\x00\xf2\xff')
4
bytearray(b'UU\xfb\xff\n\x00\xf4\xff')
5
bytearray(b'UU\xfa\xff\x10\x00\xf4\xff')
6
Error:     bytearray(b'UU\xfd\xff\x00\xf6\xffU')  <---- hier wurden nur 5 Bytes empfangen
7
bytearray(b'UU\x05\x00\x10\x00\xf8\xff')
8
bytearray(b'UU\x08\x00\t\x00\xf7\xff')
9
bytearray(b'UU\x06\x00\x05\x00\xf7\xff')
10
bytearray(b'UU\x03\x00\x02\x00\xf7\xff')
11
bytearray(b'UU\xfd\xff\x03\x00\xf8\xff')
12
bytearray(b'UU\xfa\xff\x06\x00\xf7\xff')

Komischerweise habe ich dasselbe Problem auf einer Windows Maschine 
scheinbar nicht, ich benutze dort ebenfalls Putty mit denselben 
Einstellungen. Zudem benutze ich das selbe Python Skript um den 
Datenstream zu postprozessieren.

Ich habe die Rohdaten schon auf dem Speicher des Mikrocontrollers 
angeschaut, da scheint auch alles in Ordnung zu sein. Das Problem 
scheint also beim Auslesen der UART Daten auf Linux mit Putty 
aufzutreten.

Hat vielleicht jemand eine Idee, weshalb Linux gewisse Bytes fallen 
lassen könnte?

von Monk (roehrmond)


Lesenswert?

Möglicherweise kann Putty die Daten nicht schnell genug empfangen, so 
dass der Empfangspuffer überläuft. Probiere mal, die Daten direkt in 
eine Datei zu schrieben, anstatt auf den Bildschirm. Zur Not mit einem 
anderen Programm (gibt ja sogar Kommandozeilen-Tools dafür.

von Norbert (Gast)


Lesenswert?

Tom schrieb:
> Hat vielleicht jemand eine Idee, weshalb Linux gewisse Bytes fallen
> lassen könnte?

Du musst die Schnittstelle unbedingt auf raw Modus konfigurieren wenn du 
alle Bytes von 0x00…0xff übertragen willst.

›man stty‹ wird dir Hilfe geben.

von Tiramisu (Gast)


Lesenswert?

Verwendest Du HW-technisch RTS/CTS Handshake (also CTS Eingang am 
TMS320)
und den RTS am PC 
(https://documentation.help/PuTTY/config-serial-flow.html)? Nein -> 
Designproblem.

Lass mal parallel ein Video am Windows-PC laufen, ob dann da nicht
derselbe "Verlust-Effekt" auftritt :-)

Wie üblich: ein paar Versionsinfos, HW-Infos, Serielle via 16550 oder 
USB waeren schon interessant... Windowsmaschine==Linuxmaschine 
("Dualboot"?)

von Jester (Gast)


Lesenswert?

Tom schrieb:

> Messwerte werden je alle 1ms übertragen, UART Baudrate ist 460800

460800 bits/s (über RS-232?) finde ich schon ziemlich ambitioniert ...

https://en.wikipedia.org/wiki/RS-232:
"The standard does not define bit rates for transmission, except that it 
says it is intended for bit rates lower than 20,000 bits per second."

von Falk B. (falk)


Lesenswert?

Tom schrieb:
> Zudem benutze ich das selbe Python Skript um den
> Datenstream zu postprozessieren.

Soso, postprozessieren. Früher (tm) nannte man das in den hiesigen 
Landen "bearbeiten" oder "weiter verarbeiten".

> Ich habe die Rohdaten schon auf dem Speicher des Mikrocontrollers
> angeschaut, da scheint auch alles in Ordnung zu sein. Das Problem
> scheint also beim Auslesen der UART Daten auf Linux mit Putty
> aufzutreten.
>
> Hat vielleicht jemand eine Idee, weshalb Linux gewisse Bytes fallen
> lassen könnte?

Linux sicher nicht, eher Putty oder dein Script.
Um 7 Bytes mit 1kHz dauerhaft senden zu können, braucht man keine 
400kBaud, dafür reichen etwas mehr als 7*10*1kHz = 70kBaud. Versuchs mal 
mit den üblichen 115k2.

von Falk B. (falk)


Lesenswert?

Jester schrieb:
> 460800 bits/s (über RS-232?) finde ich schon ziemlich ambitioniert ...

Es ist vermutlich keine echter UART sondern ein virtueller über USB.

von Mario M. (thelonging)


Lesenswert?

Tom schrieb:
> Error:     bytearray(b'UU\xfd\xff\x00\xf6\xffU')  <---- hier wurden nur
> 5 Bytes empfangen

Welches Zeichen fehlt denn? Bei mir macht Putty standardmäßig XON/XOFF, 
stelle mal Handshaking auf 'none'.

von Norbert (Gast)


Lesenswert?

Iss ja alles gut und schön, aber ich sehe in den empfangenen Daten zB. 
kein 0x0d.
Mag es wohl damit zu tun haben das das Device sich noch im ›cooked‹ 
Modus befindet und automatisch Konvertierungen crlf -> lf durchführt?

Wollt's ja nur noch mal erwähnen.

Aber sucht ruhig weiter… ;-)

von Tom (Gast)


Lesenswert?

Hallo miteinander

Ich konnte das Problem in der Zwischenzeit lösen durch Benutzung eines 
Python-Skripts zum Auslesen der Daten, das funktioniert auch auf Linux 
ohne Probleme. Das Problem schien also eine Einstellung in putty zu 
sein.

Evtl. finde ich den Fehler in Putty doch noch heraus.

von Jester (Gast)


Lesenswert?

Tom schrieb:
> Evtl. finde ich den Fehler in Putty doch noch heraus.

Lesen lernen - "raw" vs. "cooked"?

vgl. Beitrag "Re: Bytes gehen in uC UART Ausgang zu Linux-Rechner "verloren"" bzw. 
Beitrag "Re: Bytes gehen in uC UART Ausgang zu Linux-Rechner "verloren""

von Bauform B. (bauformb)


Lesenswert?

Traditionell überträgt man in so einem Fall nur Klartext in 7-Bit ASCII, 
keine Binärdaten. Dazu zwecks Framing ein new line und evt. ein carriage 
return, und alles funktioniert ganz ohne Tricks und Einstellungen, per 
Script oder mit putty oder picocom...

: Bearbeitet durch User
von Jens M. (schuchkleisser)


Lesenswert?

Interessant finde ich in diesem Zusammenhang, das niemand gesehen hat, 
das in der falschen Zeile durchaus alle Daten korrekt empfangen wurden, 
nur das das Datenbyte eben dem Framingbyte entspricht und daher am Ende 
ebenso wie dieses als U angezeigt wurde, was dessen ASCII-Code 
entspricht.

von Olaf (Gast)


Lesenswert?

> Interessant finde ich in diesem Zusammenhang, das niemand gesehen hat,

Wir sind halt alles erfahrene Entwickler, soll heissen unsere Hirne
funktionieren ausschliesslich in Hex! Die Darstellung ist aber auch 
schon
ziemlich bloed. QED!

Olaf

von Norbert (Gast)


Lesenswert?

Jens M. schrieb:
> Interessant finde ich in diesem Zusammenhang, das niemand gesehen
> hat,
> das in der falschen Zeile durchaus alle Daten korrekt empfangen wurden,
> nur das das Datenbyte eben dem Framingbyte entspricht und daher am Ende
> ebenso wie dieses als U angezeigt wurde, was dessen ASCII-Code
> entspricht.

Sehe ich etwas anders. Hier mal ein lesbarer formatiertes Packet:
1
U U \x04 \x00 \x01 \x00 \xf7 \xff
2
U U \x01 \x00 \x03 \x00 \xf4 \xff
3
U U \xfd \xff \x06 \x00 \xf2 \xff
4
U U \xfb \xff \n   \x00 \xf4 \xff
5
U U \xfa \xff \x10 \x00 \xf4 \xff
6
                        
7
U U \xfd \xff ____ \x00 \xf6 \xff U   :FEHLER
8
                        
9
U U \x05 \x00 \x10 \x00 \xf8 \xff
10
U U \x08 \x00 \t   \x00 \xf7 \xff
11
U U \x06 \x00 \x05 \x00 \xf7 \xff
12
U U \x03 \x00 \x02 \x00 \xf7 \xff
13
U U \xfd \xff \x03 \x00 \xf8 \xff
14
U U \xfa \xff \x06 \x00 \xf7 \xff

In der fraglichen Zeile wurde mit großer Wahrscheinlichkeit ein Byte 
weggefiltert. Da aber stumpf 8 Bytes gelesen werden, taucht das nächste 
U auch noch auf. Der folgende Frame geht dann vermutlich verloren (nur 
noch ein U zur sync) und danach sieht's wieder normal aus.

von Norbert (Gast)


Lesenswert?

Ich schließe mich aber Olaf an, gerade bei der Fehlersuche ist 
Lesbarkeit der Daten wichtig:
1
#!python
2
' '.join(['{:02x}'.format(b) for b in dein_bytearray])
3
# '55 55 fb ff 0a 00 f4 ff'

von Jens M. (schuchkleisser)


Lesenswert?

Norbert schrieb:
> Da aber stumpf 8 Bytes gelesen werden, taucht das nächste
> U auch noch auf. Der folgende Frame geht dann vermutlich verloren (nur
> noch ein U zur sync) und danach sieht's wieder normal aus.

Das kann natürlich auch sein, das weiß nur der Absender.
Eine Sequenznummer ist ja leider nicht dabei...

Norbert schrieb:
> Ich schließe mich aber Olaf an, gerade bei der Fehlersuche ist
> Lesbarkeit der Daten wichtig:

Das ist auch korrekt.
Wobei ich mir beinah sicher bin das ein Wert von "U" (spätestens "UU") 
die Synchronisation durcheinander bringt. Da müsste m.E. eine Codierung 
rein, die entweder das Sync-Zeichen escapet (d.h. mit einem Signalbyte 
ankündigt, also ESC-ESC heißt ESC, ESC-U heißt U, U heißt Sync) oder die 
Daten umkodiert, z.B. mit Base64 o.ä.
Oder der Sender ist limitiert und dieser Wert tritt normal nie auf.

von bronko (Gast)


Lesenswert?

Hi.

Tom schrieb:
> Die drei Messwerte (16bit) sende ich
> mittels UART an einen PC mit einer Frequenz von 1kHz (d.h. Messwerte
> werden je alle 1ms übertragen, UART Baudrate ist 460800)

1 KHz scheint mir etwas grenzwertig zu sein. Sind die beiden PCs 
(Linux/Windows) die gleichen Modelle? Vlt. könntest du die Sendefrequenz 
drosseln und die Paketgröße vergrößern?

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.