Daten auf USB Virtuellen COM Port senden zu langsam



  • Ich versuche Daten an einen USB Virtuellen COM Port zu senden. Hierzu richte ich den COM Port mit WinAPI Funtkionen ein (man findet das ja zu hauf im Netz).
    In einer for Schleife sende ich mit TransmitCommChar bis zu 40 Bytes an den virtuellen COM Port und ein Mikrocontroller blinkt bei jedem empfangendne Byte auf und sendet es zurück. Alles funtioniert wunderbar.
    Wenn ich aber mit dem Oszilloskop Messe, dann braucht ein Byte 1ms. Ich habe im Netz recherchirt hier sollten viel höhere Datenraten möglich sein. Die Bitrate im COM Treiber sollte egal sein weil es über USB geht. Ich habe das aber auch mit anderen Einstellungen versucht.
    Ich habe PC Seitig einen Treiber von ST verwendet und auch den Standarttreiber von Windows. Beide male das gleiche Ergebnis
    Ich verwende den Borland C++ Builder Enterprice Version 6 und das ganze läuft unter Windows 10.
    Hat da jemand eine Idee was das sein könnte.
    Vielen Dank

    Hier noch mein Code (Nachtrag das ist nur die Initialisierung des Ports gesendet wird in einer anderen Funktion mit der WINAPI Funktion TransmitCommChar() )

    void CCom::InitComPort(char * ocp_ComPort)
    {
       DCB myCom;      // Struktur definieren
       // Com - Port öffnen
       hSerial = CreateFile(  ocp_ComPort,
                                   GENERIC_READ | GENERIC_WRITE,
                                   0,
                                   0,
                                   OPEN_EXISTING,
                                   0,
                                   0 );
        if ( (hSerial == NULL)|(hSerial ==INVALID_HANDLE_VALUE ))  // Fehlerabfrage
        {
           Application->MessageBox( "Serielle Schnittstelle konnte nicht geöffnet werden",
                                    "Fehler: Schnittstelle",MB_ICONERROR || MB_OK );
        }
        // Timeout bearbeiten
        GetCommTimeouts( hSerial, &TOutAlt );   // Alte Einstellung speichern
        TOutNeu.ReadTotalTimeoutConstant   = 1; // Angabe ms
        TOutNeu.ReadTotalTimeoutMultiplier = 1;   // Lese Multiplikator in ms
        TOutNeu.WriteTotalTimeoutMultiplier = 1;  // Schreibe Multiplikator
        TOutNeu.WriteTotalTimeoutConstant   = 1;
        SetCommTimeouts( hSerial, &TOutNeu );   // Neue Werte setzen
    
        myCom.DCBlength = sizeof(DCB);          // Speicherplatz schaffen
        GetCommState( hSerial, &myCom );        // Aktuelle Einstellung laden
        BuildCommDCB("115200,N,8,2", &myCom );    // Neue Werte einstellen
    
        SetCommState( hSerial, &myCom );        // Werte setzen
    }
    


  • Wenn ich es richtig verstehe, verwendest Du ein USB-RS232 Kabel.
    Ich habe mit diesen Kabeln bisher mehrfach die Erfahrung gemacht, das die Übertragung langsamer ist als reine RS232. Dies liegt angeblich daran, daß USB Paketorientiert arbeitet.

    Wie misst Du denn die Übertagung eines Bytes, und wie kommst Du auf 1ms?

    MfG Stephan

    P.S. Außerdem stelle ich mir noch die Frage, ob es überhaupt noch Sinn macht mit dem Builder V6 zu arbeiten.



  • Ich habe ein Evaluation Board da ist eine USB Schnittstelle drauf (ST32F4 Discovery). Auf dem Board habe ich eine Softwaretreiber der mir die USB Nachrichten entgegen nimmt. Ich habe den Source im Internet runtergeladen. Laut Aussage des Programmierers erreicht er damit sehr hohe Datenraten.
    Ich messe das Blinken der LED mit dem Oszilloskop. Dann weis ich in welchem Abstand die Bytes eintrudeln.



  • Na ja, also wenn Du schon Kontakt mit dem Firmwareentwickler hast, dann kann dieser Sicher auch ein einfaches Windows Programm zum Test bereitstellen.
    So wie ich das sehe kann der Fehler im:
    - Windows Programm
    - Windows USB Treiber
    - uC Firmware
    liegen.

    Eventuell sogar an irgendeiner PC Einstellung (hab hier schon alles erlebt).
    Ohne deinen Code jetzt bis ins letzte überprüft zu haben, es wird hier nirgends etwas gesendet.
    Eventuell mußt Du nach dem WinApi-Senden den Buffer flushen (FlushFileBuffers), damit der USB-Treiber die Daten auch sofort auf die Leitung schickt.

    Also ich habe zum Senden immer WriteFile() verwendet, außerdem habe ich beim öffnen noch ein FILE_FLAG_NO_BUFFERING verwendet. Von diesem Flag würde ich mir jetzt mal einiges versprechen.

    MfG Stephan



  • Ich habe kein direkten Kontakt zum Entwickler. Das Schreibt er auf seiner Hompage.

    Das mit WriteFile() war aber gut.
    Die Funtkion TransmitCommChar() zwingt offensichtlich den Treiber dazu das er in jeden USB Frame nur ein char versendet. Daher kommt es dann wohl das nur ein Byte in jeder ms ankommt.
    Jetzt habe ich WriteFile() verwendet. Nun rumpeln die Bytes in 2us ins Haus.
    Vielen Dank für den Tip.


Anmelden zum Antworten