Hallo, ich stehe vor folgendem Problem: Ich habe eine Windowsanwendung, die über einen COM Port Befehle an ein Steuergerät schickt und über den selben COM Port daraufhin eine Antwort erhält. Die Befehle bestehen im Schnitt aus 10-12 Bytes. Bei der eingestellten Geschwindigkeit von 115200 Baud sollte also ein Befehl in ziemlich genau 1ms über die Leitung rauschen. Es gibt 3 Möglichkeiten das Steuergerät zu verbinden: 1) direkt den nativen COM Port des PC mit dem USART (über Pegelwandler) des Steuergerätes verbinden 2) mangels nativem COM Port ein USB-auf-Seriell Kabel verwenden (virtueller COM Port) 3) über Bluetooth (SPP), ebenfalls virtueller COM Port In allen 3 Fällen sieht die Windows Anwendung nur einen COM Port und weiß ja nicht, was sich dahinter befindet. Nun mein Problem: Bei Lösung 1) geschieht die Übertragung auch wirklich in ca. 1ms. Bei Lösung 2) brauchen die 11 Bytes schon immerhin 10ms. Zwischen jedem Byte ist eine Pause von fast 1ms! Und bei Lösung 3) dauert der Vorgang schon 30-40ms! Rießige Pausen zwischen den Bytes... Gemessen wurde das mit einem Logiktester (Intronix Logicport). Normalerweise würde ich jetzt die Schuld auf die Treiber schieben, die der Anwendung den COM Port vorgaukeln. Allerdings hab ich einen Gegenversuch mit HTerm gemacht, indem ich den Befehl per Hand eintippe und abschicke. In allen 3 Fällen dauert die Übertragung 1ms. Also kanns der Treiber ja doch irgendwie... Wisst ihr vielleicht ob man da was dagegen tun kann? Gibt es alternative Treiber für Bluetooth Dongles und USB-Seriell Adapter? Oder kann man im System irgendwas konfigurieren? Immerhin klappts ja bei HTerm... Ist bisl ärgerlich soviel Zeit für den Request zu verbraten wenn die Verarbeitung in der ECU und die Antwort zusammen nur ca. 3-4ms benötigen... Viele Grüße, Karlo
Ich denke das liegt am FIFO den die meisten USB-UART-Adapter standardmäßig nutzen. Die senden dann erst nach einem Timeout die Daten aus dem Fifo wenn sie längere Zeit keine weiteren Daten bekommen. Geht mal auf den USB-UART im Gerätemanager und stell unter Erweitert den Fifo mal um.
Bluetooth müsste ich nachlesen, bei USB sieht das eher danach aus das die Anwendung nicht ein ganzes Paket, sondern mehrere schickt. Falls da ein FTDI USB->Seriell-Wandler drin hängt: http://www.ftdichip.com/Support/Documents/AppNotes/AN232B-04_DataLatencyFlow.pdf (Latenz ist sowohl über die FTD2XX, als auch über den Gerätemanager einstellbar)
Welche Sprache/ Bibliothek wird verwendet? Werden die Befehle zeichenweise gesendet? Sinnvoll ist blockweise Übertragung (Win32Api: WriteFile(), evtl. OVERLAPPED)
Sieht dann z.B. so aus im im Bild (Anschlusseinstellungen => Erweitert). Das dürfte bei virtuellen Bluetooth COM-Port genauso sein.
Hallo, Danke für die Antworten erstmal. Welche Lib genutzt wird kann ich nicht sagen, ich habe die Anwendug bereits fertig erhalten und hab auch keinen Quellcode dazu. Werd mal der Reihe nach eure Vorschläge abarbeiten :-) Mich wunderts halt nur, dass HTerm das ganze komplett auf einmal raus schicken kann, die Anwendung aber nicht... Viele Grüße, Karlo
Rumspielen mit den Werten des Buffers oder deaktivieren des Buffers ändert leider garnichts am Timing. Es ist kein Unterschied zu erkennen, sowohl bei dem Adapter als auch beim USB Dongle. Hat noch jemand ne Idee wie sich die Anwendung bewegen lässt, sich so wie HTerm zu verhalten? Viele Grüße, Karlo
>Hat noch jemand ne Idee wie sich die Anwendung bewegen lässt, sich so >wie HTerm zu verhalten? offensichtlich ist das Programm selber ja "schlecht" programmiert warum wendest du dich nicht an den Entwickler?
Wie bereits vermutet, wird die Anwendung die Befehle als einzelne Schreibzugriffe auf dem Port ausgeben. Ohne Zugriff auf den Entwickler/ Quelltext könntest Du nur eine Adapter-Anwendung schreiben, die über einen virtuellen Com-Port (z.B. http://com0com.sourceforge.net/) die Daten eines kpl. Befehls einliest und dann sinnvoll über den gewünschten Port ausgibt. Daß es bei sinnvoller Ausgabetechnik funktioniert, hast Du ja mit hterm getestet.
Hallo Karlo, das liegt wohl an Deinem Treiber. Bei einem virtuellen COM-Port versucht man ja eine möglichst hohe Übertragungsrate zu erreichen. Das aber ist nur möglich, wenn volle Pakete (entsprechend Deiner Endpunkt-Puffer) versendet werden. Angenommen Deine Endpunkte sind 64 Byte groß, dann muss der PC Treiber immer auf 64 Byte warten, um sicherzustellen, dass er auch alles entgegennimmt (ReadFile(a,b,c,64) o.ä.). Wenn Deine Anwendung also nur 10 Bytes versendet, dann wartet der Treiber theoretisch ewig, was aber dadurch vermieden wird, indem nach z.B. 10 ms die Daten vom Treiber weitergegeben werden - und zwar egal wieviele es sind. Man könnte den Treiber auch so erstellen, dass er die Daten Byte-weise entgegen nimmt (ReadFile(a,b,c,1)). Was aber eher selten passiert, denn dann hat man das Problem, dass die ganze Geschichte wesentlich verlangsamt wird. Darum nutzen viele Treiber die Lösung mit vollem Puffer (64 Byte) und dem Timeout. Gruß Potter
Das heißt, die Anwendung wird (wahrscheinlich) nicht einen 11 Byte langen Frame an den Treiber weiterreichen sondern immer nur 1 Byte, d.h. der "Senden" Befehl wird 11 mal ausgeführt? Dann hab ich wohl wirklich ohne Quelltext keinen Einfluss auf das Verhalten... Die Lösung mit dem com0com hört sich gut an, wär aber ein wenig Overkill. So schlimm ist das mit dem Timing auch nicht, sind eher so Feinheiten (die sich aber bekanntlich aufsummieren können :-)). Ich habe mal den Support angeschrieben, falls noch jemanden was einfällt, gerne her damit :-) Viele Grüße, Karlo
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.