Forum: PC-Programmierung Datenkurve am PC anzeigen ist zu langsam


von Deepdiver99 (Gast)


Lesenswert?

Ich übertrage von einem STM32F4 per FTDI USB-Kabel Daten an den PC. 
Diese werden am PC „sortiert“ und als Kurve ausgegeben. Mir ist aber die 
Anzeige auf dem PC zu langsam. Vielleicht könnt ihr mir helfen wie man 
da üblicher Weise vorgeht. Hier mal eine kurze Beschreibung wie ich es 
gelöst haben.
Die es werden vom STM32F4 Datenblöcke von 18 Byte Größe mit folgendem 
Aufbau verschickt:
BYTE 1 :  Anfang Erkennung „0xff“
BYTE 2:  Größe+“Art“ der Daten
BYTE 3-14: Daten
BYTE 15-18: CRC32 Prüfsumme

Am PC gibt es 4 Threads:
Thread 1: Mainthread für die Oberfläche
Thread 2: FTDI empfangen per “FTD2XX.dll”
Thread 3: Datenpakete raus sortieren und CRC32 prüfen
Thread 4: Daten verarbeiten und an Mainthread für Anzeige übergeben

Am PC programmiere ich mit VS2008 C++/CLI. Mein PC ist schnell genug.

VG Deepdiver99

von npn (Gast)


Lesenswert?

Deepdiver99 schrieb:
> Mein PC ist schnell genug.

Die RS232-Datenrate auch?

von Bernd K. (prof7bit)


Lesenswert?

Hast Du ein CPU-Problem oder ein IO-Problem?

von qwerty (Gast)


Lesenswert?

Naja, zuerst sollte man mal überprüfen, was wie lange dauert um 
rauszufinden was zu langsam ist ... Erst dann kann man beginnen zu 
optimieren

von Deepdiver99 (Gast)


Lesenswert?

Die Baudrate ist auf 3.000.000 eingestellt.

Sobald vom STM32F4 mehr Datenblöcke geschickt werden fängt die Ausgabe 
der Kurve auf dem Bildschirm an zu stocken. Teilweise dauert es einige 
Sekunden bis es weiter geht. Dann aber alles auf einmal. Also am Empfang 
liegt es nicht. Meine CPU ist super schnell und 16GB RAM sollten auch 
reichen. Vermute mal das die Verarbeitung zwischen dem empfangen und der 
Ausgabe nicht effektiv ist. Wie wird sowas sonst in der Praxis gelöst? 
Bei anderen Systemen werden doch teilweise viel mehr Daten verarbeitet.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du wirst wohl ein Problem in Deiner Threadsynchronisation haben.

von npn (Gast)


Lesenswert?

Deepdiver99 schrieb:
> Vermute mal das die Verarbeitung zwischen dem empfangen und der
> Ausgabe nicht effektiv ist.

Ich vermute, daß sich die Threads gegenseitig behindern, so wie du das 
beschreibst. Der Empfangsthread muß die Daten in einen Buffer schreiben 
können und parallel dazu muß ein anderer Thread unabhängig davon die 
Daten aus dem Puffer holen, sie verarbeiten und dann darstellen. Und 
wenn du sagst, daß während des Datenempfanges keine Aktualisierung der 
Darstellung erfolgt, dann wird dein Empfangsthread die anderen Threads 
blockieren.

von deep d. (deepdiver99)


Lesenswert?

Sowas dachte ich mir schon. Aber die Vorgehensweise ist erst mal so 
richtig?

von Bernd K. (prof7bit)


Lesenswert?

Deepdiver99 schrieb:
> Sobald vom STM32F4 mehr Datenblöcke geschickt werden fängt die Ausgabe
> der Kurve auf dem Bildschirm an zu stocken. Teilweise dauert es einige
> Sekunden bis es weiter geht.

Hatte ich auch mal, als ich die Bytes von der Seriellen byteweise 
abgeholt habe (also zuerst auf EV_RXCHAR gewartet und dann aber immer 
nur Länge 1 im ReadFile()-Aufruf. Das ging dann mit manchen 
rs232-Adaptern immer noch problemlos (z.B. ein Arduino-Uno ging 
problemlos, sogar mit hohem Durchsatz) aber bei nem FTDI-basierten 
Adapter begann es plötzlich im Sekundentakt zu stottern sobald das 
Datenvolumen größer wurde, er hing dann jedesmal im 
WaitForSingleObject() fest obwohl längst neue Daten hätten da sein 
sollen, kurz danach kamen sie dann alle auf einmal, bis zum Nächsten 
Hänger.

Dann baute ich das um, so daß jedesmal soviele Daten gelesen werden wie 
da sind, lese sie in meinen eigenen Puffer und entnehme sie später von 
dort byteweise so wie ich sie brauche. Seitdem erreiche ich den vollen 
Datendurchsatz ohne Probleme.

Also Kurzfassung: Niemals die Bytes einzeln mit ReadFile() lesen, immer 
in großen Blöcken soviel lesen bis nichts mehr kommt, erst dann erneut 
warten lassen.

: Bearbeitet durch User
von Georg (Gast)


Lesenswert?

Hallo,

wenn du Daten darstellst z.B. mit 1024 x 768 Pixeln, dann ist ein 
Bildschirm mit 1k x 16 bit vollgeschrieben, und da weder dein Auge noch 
dein Verstand mehr als 10 Bilder pro Sekunde erfassen kann, ist dafür 
eine Datenrate von 20 kB / s ausreichend, warum also überträgst du 300 
kB / s?

Es kann durchaus sein, dass die Empfangsinterrupts deine CPU-Leistung 
auffressen, besonders wenn der Treiber schlecht programmiert ist und 
z.B. für jedes Zeichen einen Interrupt auslöst. Ich halte es daher für 
möglich, dass die Sache mit niedrigerer Datenrate besser funktioniert, 
Baudraten sind nicht nach dem Prinzip viel hilft viel festzulegen, 
sondern das Gesamtsystem sollte ausgewogen sein. Jedenfalls kannst du 
das mal probieren. Am besten wäre es natürlich, wenn du zuerst mal 
messen würdest, welcher Thread wieviel CPU-Zeit verbraucht.

Du kannst natürlich auch mit Prioritäten spielen, aber das verdeckt eher 
ein bestehendes Problem als dass es gelöst wird.

Georg

von Heini (Gast)


Lesenswert?

10 fps könnten u.U. ruckelig wirken, mehr als 30 sind aber für diesen 
Zweck Rechenzeit- und Energieverschwendung. Um eine Begrenzung 
umzusetzen, muss man natürlich die Ausgabe vom Einlesen der Daten 
komplett entkoppeln und auch den Bildschirminhalt korrekt 
synchronisieren. Eine einfache Strategie wäre, die neuesten Daten 
anzuzeigen, die vorhanden sind (falls zwischen den Frames nicht genug 
reinkommt, um das Bild zu füllen, muss ein Teil der "alten" Daten 
verwendet werden, so dass das Bild scrollt). Alternativ könnte man alle 
Daten zeigen, ohne etwas zu überspringen; dann hinkt die Anzeige immer 
weiter hinterher. Irgendwann ist dann allerdings Schluss, weil der 
Buffer nicht beliebig groß sein kann.

> "Diese werden am PC „sortiert“ und als Kurve ausgegeben."

Bei einer hohen Datenrate muss man für eine sinnvolle Anzeige u.U. 
"richtig" synchronisieren - ähnlich wie bei einem Oszilloskop - was das 
Ganze natürlich komplexer macht.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Benutz doch einfach das Programm von Alfred.

von npn (Gast)


Lesenswert?

Abdul K. schrieb:
> Benutz doch einfach das Programm von Alfred.

Alfred wer ?

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Der aus Mönchengladbach. Wirste hier finden.

von Albert (Gast)


Lesenswert?

Alfred war knapp daneben :)

Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle"

Neueste Version 0.48e

von npn (Gast)


Lesenswert?

Abdul K. schrieb:
> Der aus Mönchengladbach. Wirste hier finden.

Du kannst einen vielleicht in die Irre führen! Mann.... :-))

von npn (Gast)


Lesenswert?

Albert schrieb:
> Alfred war knapp daneben :)
>
> Beitrag "Projekt: Virtuelle Instrumente an serielle Schnittstelle"
>
> Neueste Version 0.48e

Danke für den Link, Albert! Sieht sehr interessant aus, den Thread muß 
ich mir mal in Ruhe zu Gemüte führen...

von Pandur S. (jetztnicht)


Lesenswert?

Beim anzeigen kann man auch noch Fehler machen. zB

-mach pixel hin -refresh -mach pixel hin -refresh -mach pixel hin
-refresh -mach pixel hin -refresh
..
oder
alloziere neues pixel, alles malen, nochmals ein pixel, alles malen, 
nochmals ein pixel, alles malen

Mach dir Gedanken wie die Daten zu so einem Bild gespeichert, so ein 
Bild aufgebaut und ge-refresht wird.

von Bernd K. (prof7bit)


Lesenswert?

Deepdiver99 schrieb:
> Teilweise dauert es einige
> Sekunden bis es weiter geht. Dann aber alles auf einmal.

Das deutet nicht wie die anderen Schreiber hier irreführenderweise 
vermuten wollen auf einen CPU-Engpass hin, das deutet eher deutlich auf 
ein Synchronisationsproblem und verpasste EV_RXCHAR Events, also das was 
ich bereits weiter oben schrieb. Wie hoch ist Deine CPU-Auslastung 
(damit ist ruckzuck geklärt wo man weitersuchen muss).

Was sagt der Profiler, wo wird die meiste Zeit verbracht? Könnte man 
vielleicht mal systematisch vorgehen?

Wenn Du keinen Sampling-Profiler hast und zu faul bist Dir endlich einen 
zu installieren dann geht auch poor-man's profiling: Drück im Debugger 
auf Pause, schau in den Callstack und schreib Dir auf in welcher 
Funktion (und wenn Du es ganz genau haben willst in welcher Zeile) jeder 
Thread gerade war. Mach das 10 bis 100 mal, mach ne Strichliste und Du 
weißt wo welcher Prozentsatz der Zeit verbraten wird.

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.