Forum: Mikrocontroller und Digitale Elektronik Uart - Daten + Steuersignale trennen?


von Jan K. (jan_k)


Lesenswert?

Hallo liebe Leute,

ich muss schon wieder euer Wissen in Anspruch nehmen :-/

Es geht um folgendes:

ein uC misst alle 500us einen Wert. Dieser wird noch einigen 
Berechnungen unterworfen und dann per UART in einem größeren Block (500 
Bytes) verschickt.
Die Daten werden dauerhaft gesendet, sobald der Befehl dazu gegeben 
wurde. Einfach deswegen, weil ich sonst dauerhaft die Daten anfordern 
müsste und ich eventuell Datenblöcke verlieren könnte.
Alle Befehle werden durch den uC bestätigt um eventuelle Fehler 
auszuschließen. Bisher wurde das über die selbe Schnittstelle gemacht, 
die auch die Datensätze verschickt. Auf dem PC, der den uC ansteuert 
läuft matlab, die Kommunikation sieht in etwa so aus:
1
s = serial('/dev/ttyUSB1','BaudRate',115200,'DataBits',8,'StopBits',1,'TimeOut',2,'InputBufferSize',4096);
2
fopen(s);
3
fwrite(s,Befehl);
4
answer = fread(s,16);  
5
fclose(s)

Ich denke das Prinzip wird klar - Ich schicke den Befehl und empfange 
danach direkt, um die Antwort zu erhalten.

Dieses Prinzip funktioniert aber nicht mehr, wenn ich die Datenblöcke 
"parallel" verschicke. Zwar wird in einer ISR der Rx Buffer gefüllt und 
eine Flag gesetzt, die ausgelesen wird, bevor die Datensätze geschickt 
werden (beides in der main), aber da der Zeitpunkt, an dem ein neuer 
Befehl gesendet wird, nicht konstant ist kann ich z.B. den unglücklichen 
Moment treffen, dass gerade Daten geschickt werden (gar nicht so 
unwahrscheinlich..). Damit "rupfe" ich also 16 Byte aus meinen 
eigentlichen Daten heraus, obwohl ich nur die Antwort auf meinen Befehl 
checken möchte.

Wie kann ich dieses Problem beheben, wie kann ich sicher sein, dass die 
eingehenden 16 Bytes die Antwort ist? Kann ich vermutlich gar nicht.
Welche anderen Möglichkeiten gibt es hier, außer einer zweiten UART?

Ps, sowohl die Datenblöcke, als auch die Befehle sind in einem Frame 
(inkl Checksum) eingebettet. Aber einen großen Puffer zu nehmen, alle zu 
empfangenen Daten da reinzuschreiben und hinterher (möglichst schnell, 
also möglichst "Echtzeit") zu filtern ist recht mühselig.

Habt ihr andere Ideen?

Vielen lieben Dank :)

von Michael A. (Gast)


Lesenswert?

Jan K. schrieb:
> Welche anderen Möglichkeiten gibt es hier, außer einer zweiten UART?

Ein Datenprotokoll, beim dem die Blöcke nach ihrem Typ (Daten, Quittung) 
gekennzeichnet sind. Eine Quittung muß warten, bis ein Datenblock 
beendet ist - mach die Datenblöcke also nicht zu lang.

von einmal (Gast)


Lesenswert?

das Uart wird einmal geoeffnet, underst am Schluss wieder geschlossen, 
nicht nach jedem Block. Und blockierend sollte man auch nicht arbeiten.

von spontan (Gast)


Lesenswert?

>wenn ich die Datenblöcke "parallel" verschicke

Unglücklich ausgedrückt. Du meinst, daß die Befehlsübermittlung in die 
Datenübermittlung reintrifft?

Du brauchst, wie oben schon angedeutet, ein kleines Protokoll, daß für 
den empfangenden PC unterscheidbar macht, was gerade gesendet wird, wann 
ein gesendeter Datensatz oder eine gesendete Befehlsresponse beginnen 
und zu Ende sind.

Überleg Dir einfach wie eine menschliche Kommunikation ablaufen könnte, 
das hilft.

von Jan K. (jan_k)


Lesenswert?

Danke für eure Antworten!

Der Reihe nach:

Michael  A. schrieb:
> Ein Datenprotokoll, beim dem die Blöcke nach ihrem Typ (Daten, Quittung)
> gekennzeichnet sind. Eine Quittung muß warten, bis ein Datenblock
> beendet ist - mach die Datenblöcke also nicht zu lang.

Ich kann ja die Blöcke unterscheiden zwischen Daten + Quittung. Im 
Controller ist die Reihenfolge korrekt. Das Problem ist wohl eher auf PC 
Seite zu suchen, weil dort in nicht definierten Zeiten neue Befehle 
geschickt werden können..

einmal schrieb:
> das Uart wird einmal geoeffnet, underst am Schluss wieder geschlossen,
> nicht nach jedem Block. Und blockierend sollte man auch nicht arbeiten.

So mache ich es auch, ich schließe die uart nicht nach jedem 
Schreiben/Lesen, da hab' ich mich wohl falsch ausgedrückt sorry.

Die Uart wird geöffnet, ein Befehl wird geschrieben (z.B. Logging an), 
der wird, falls er verstanden wird quittiert:
1
...
2
fwrite(s,Befehl);
3
answer = fread(s,16)
4
...

Jetzt ist also der Logging Modus an und schickt dauerhaft 500 Byte (+16 
Byte Header bzw Frame) Daten raus.
Die empfange ich z.b so:
1
data = [];
2
for i=0:1:9
3
  data = [data; fread(s,516)]
4
end
5
...

Das funktioniert auch wunderbar. Aber möchte ich jetzt den Logging Modus 
wieder ausschalten, schreibe ich
1
...
2
fwrite(s,LogOff)
3
answer = fread(s,16)
4
...

. Das funktioniert, wenn nicht in diesem Moment noch Daten kommen. Das 
passiert aber häufig. Da liegt ja der Hund begraben ..

Jetzt am Ende wird die UART erst wieder geschlossen.
1
...
2
fclose(s)
3
delete(s)

spontan schrieb:
> Unglücklich ausgedrückt. Du meinst, daß die Befehlsübermittlung in die
> Datenübermittlung reintrifft?
>
Ja parallel geht natürlich nicht wirklich.
> Du brauchst, wie oben schon angedeutet, ein kleines Protokoll, daß für
> den empfangenden PC unterscheidbar macht, was gerade gesendet wird, wann
> ein gesendeter Datensatz oder eine gesendete Befehlsresponse beginnen
> und zu Ende sind.
Habe ich ja.
> Überleg Dir einfach wie eine menschliche Kommunikation ablaufen könnte,
> das hilft.

Ich frage jmd etwas, ob ich was haben kann. Er sagt ja und fängt an zu 
plappern. Dann sage ich irgendwann "stop". Er plappert aber 
möglicherweise noch weiter, weil er es noch nicht gehört hat (oder noch 
nicht "verarbeitet" hat). Ich warte aber nur noch auf "ok ich höre auf 
zu plappern", weiß aber nicht wann das kommt und müsste so die ganze 
Zeit darauf warten. Genau das letzte bereitet nunmal Probleme ;)

von Peter D. (peda)


Lesenswert?

Eine Quittung kann erst nach einem 500Byte-Paket kommen.
Wenn Dir das zu lange dauert, mache eben die Pakete kürzer.

Bei CAN ist z.B. die maximale Paketlänge 8 Byte.
Dadurch ist es echtzeitfähig.


Peter

von Uwe (Gast)


Lesenswert?

Den Befehl "fwrite(s,LogOff)" nur schicken wenn ein komplettes Paket 
bzw. Frame Vollständig ist. Du mußt halt in LabView auch das Protokol 
implementieren wie im µC.

von Uwe (Gast)


Lesenswert?

> Uart - Daten + Steuersignale trennen?
Dafür ist ja das Protokoll da !

von Spontan (Gast)


Lesenswert?

Jan schrieb:
>Habe ich ja.

Das Protokoll war gemeint.


Dann muß ich sagen, daß das Protokoll nix taugt, es erfüllt ja die 
Aufgabe nicht.

Wenn ein Befehl des PC in die Datenübertragung reintrifft, was soll dann 
passieren? Was macht das Protokoll wirklich?


Deine letzten Sätze hab ich so verstanden, daß der µC die 
Datenübertragung abbrechen soll und auf den PC-Befehl antworten soll.

Dann muß das das Protokoll auch machen (bzw. die Software natürlich). 
Macht sie das auch?

Denke nein. Sonst gäbs die Probleme ja nicht.


Also verbessere das Protokoll, Software-Handshake, wie immer Du die 
Prozedur zum Datenaustausch nennst. Sonst gehts nicht.

von Jan K. (jan_k)


Lesenswert?

@ Uwe + Peter

Da werde ich ansetzen, dann lese ich halt noch ein komplettes Paket à 
500 Bytes ein.
Das dauert mir nicht zu lange, hab' gerade mal nachgerechnet, es kommt 
nicht auf jede Millisekunde an.

Danke!

Uwe schrieb:
>> Uart - Daten + Steuersignale trennen?
> Dafür ist ja das Protokoll da !

Hehe ja. Man muss es halt "nur" am PC auch vernünftig umsetzen..

@ Spontan:
Nein, der uC soll nicht zwischendrin die Übertragung abbrechen, dazu 
müsste ja in der ISR auch schon der einkommende Befehl ausgewertet 
werden. Die Übertragung soll ausgeschaltet werden, ja das stimmt. Aber 
erst, wenn alle 500 Bytes verschickt wurden.

Und nein, das Protokoll taugt halt noch nichts, deswegen frage ich ja 
hier nach ;) Möchte es ja verbessern.

Danke + schöne Grüße

von Reinhard Kern (Gast)


Lesenswert?

spontan schrieb:
> Überleg Dir einfach wie eine menschliche Kommunikation ablaufen könnte,
> das hilft.

Nicht wirklich, dazu musst du bloss die üblichen Talkshows sehen wie 
Anne Will usw. Es reden immer mehrere gleichzeitig und keiner antwortet 
auf die letzte Frage. Wie bei der beschriebenen Software.

Gruss Reinhard

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.