Forum: PC-Programmierung Daten in Blöcken senden


von Benedikt (Gast)


Lesenswert?

USB ist eine feine Sache, wenn da nicht die Sache mit der blockweisen
Übertragung wäre.
Ich habe eine alte Schaltung von RS232 mit einem FT232 auf USB
umgerüstet.
Allerdings habe ich jetzt das Problem, dass nur noch ziemlich 1kByte/s
übertragen werden, obwohl die Baudrate bei 115,2kbaud liegt.
Anscheinend wird pro USB Frame nur 1 Byte übertragen.
Um das zu umgehen muss man immer ganze Datenblöcke auf einmal an den
COM Port übergeben.
Hier ist aber mein Problem:
Die Daten werden zur Laufzeit des Programms erstellt, und es handelt
sich dabei meist um Befehle.
Manchmal wird minutenlang nichts gesendet, dann wieder mal mehrere
100kByte auf einmal.
Daher meine Idee zwischen den Senderoutine und dem Programm einen
Puffer einzubauen, der die Daten ansammelt bis z.b. 100Bytes im Puffer
sind und diese dann auf einmal überträgt.
Allerdings kann es dann passieren, das einige Daten minutenlang nicht
gesendet werden, wenn die 100Bytes noch nicht voll sind.
Daher wäre eine Zeitbeschränkung sinnvoll. Also wenn z.B. 100ms lang
nichts gesendet wurde, wird der Puffer übertragen.
Auf einem uC würde ich dazu einen Timer Interrupt verwenden, wie macht
man sowas auf einem PC in C++ ?

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Timer sind OS-Abhängig vondaher nichts direkt verwendbares:
Das ganze läßt sich ähnlich wie mit Timer-Interrupt machen. Ein Zähler,
der regelmässig hochgezählt wird und von der Sende-Routine wieder auf 0
gesetzt wird. Automatisches Senden bei einem bestimmten Zählerwert.
Oder wenn du manuell sendest, killst du den aktuellen Timer und
startest ihn neu. Unter welchen System soll das ganze denn laufen.

von Benedikt (Gast)


Lesenswert?

Ich möchte das ganze mit Visual C++ schreiben.
Es gibt doch irgendeine Möglichkeit eine Funktion einzubauen, die in
festen Zeitabständen augerufen wird, ähnlich einem Timer Interrupt auf
einem uC ? Zumindest meine ich sowas mal irgendwo gesehen zu haben.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Wenn es eine GUI-Anwendung ist, dann kannst Du den
Windows-Nachrichtentimer verwenden, der Deiner Fensterprozedur zyklisch
eine Nachricht schickt.

Wenn es keine GUI-Anwendung ist oder aber der serielle Code in einem
Hintergrundthread läuft, dann kann der Sendethread mit
WaitForSingleObject auf ein Eventhandle warten.
Dieses Event wird bei jedem Eintragen eines Zeichens in den Sendepuffer
gesetzt (geschieht mit SetEvent), der Sendethread "wacht auf", kann
den Füllstand des Puffers  überprüfen und gegebenenfalls absenden.
Als Wartezeit für WaitForSingleObject wird Dein gewünschtes Timeout
angegeben, WaitForSingleObject kehrt mit WAIT_TIMEOUT zurück, wenn das
Event nicht signalisiert wurde. Wurde das Event signalisiert, ist der
Rückgabewert WAIT_OBJECT_0.

von Benedikt (Gast)


Lesenswert?

Die Idee mit den Nachrichten war genau die richtige.
Ich lasse mir jetzt alle 100ms eine Nachricht schicken.
So spare ich mir die ganze Thread Geschichte und kann meinen aus einem
C Programm übernommenen Code unverändert weiterverwenden.

von Wolfram (Gast)


Lesenswert?

Deinen Puffer gibt es schon im Treiber!
es gibt eine einstellbare Wartezeit und eine Puffergroesse von 62
Byte.
Ein Puffer wird rausgesendet wenn entweder die Wartezeit überschritten
wird oder die Puffergroesse.
Standardwartezeit ist 16ms. Wenn du nicht mit blöcken arbeitest sondern
jedes Byte einzeln per Handshake abholst kanst du noch glücklich sein
wenn 1Kbyte /s erreicht wird.
siehe Applikation Note...

von Benedikt (Gast)


Lesenswert?

Wo kan man die Wartezeit für den Sendepuffer und dessen Größe einstellen
?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das geht mit den Win32-API-Funktionen SetCommTimeouts und SetupComm

von Wolfram (Gast)


Lesenswert?

Einstellbar ist die Wartezeit im Gerätemanager unter Latency Time.
(ftdi)
SetupComm und SetCommTimeouts arbeiten eine Ebene höher.(serielle
Schnittstelle)
Die Ebene von der wir hier sprechen ist die Paketierung der Daten in
ein USB Paket.

von Benedikt (Gast)


Lesenswert?

SetCommTimeouts bezieht sich doch auf die Zeit die für ein Sendevorgang
benötigt werden darf, ehe die Übertragung abebrochen wird, oder ?

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Würde ich auch sagen.

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.