/ / Korrekte Möglichkeit zum Schließen eines seriellen Ports QT - Windows, QT, Serial-Port, Ftdi

Richtige Methode zum Schließen einer seriellen Schnittstelle QT - Windows, qt, serielle Schnittstelle, ftdi

Ich habe eine Schnittstelle zu einem seriellen Hardwaregerät mitF: Ich habe meine Anwendung grob auf das Terminal-Beispiel ausgerichtet, aber da die Kommunikation sehr synchron sein muss, befindet sich der serielle Handler in einem anderen Thread. Die Verbindung erfolgt über einen 2xRS232-zu-USB-Adapter mit einem FTDI-Chipsatz.

Die seriellen Verbindungen sind in Ordnung, ich kann eine Verbindung herstellen, Befehle senden usw. Wenn ich die Anwendung jedoch beende und neu lade, scheint die serielle Schnittstelle blockiert zu sein.

Sei COM1 das angeschlossene Gerät, COM2 ist nicht angeschlossen.

Wenn ich das Programm starte, rede ich ein bisschen mit demHardware und beenden, ich kann mich nicht mehr mit COM1 verbinden, wenn ich das nächste Mal das Programm starte (die Daten-LEDs am Adapter blinken nicht), es sei denn, ich versuche zuerst, eine Verbindung mit COM2 herzustellen zu COM1 wie gewohnt. Dieses Verhalten wird im Referenzdienstprogramm für die Hardware nicht angezeigt und muss auf eine Art und Weise zurückgeführt werden, in der ich mit dem Port umgehe.

Mein Abschlusscode lautet:

void mydevice::closeSerialPort()
{
this->stop();
serial->close();
emit serialClosed();
emit log("Serial port closed.");
}

serial ist ein QTSerialPort. Zuerst wird ein Stoppbefehl gesendet, um die Hardware auszuschalten (nicht relevant für das Problem, es ist nur eine Annehmlichkeit), und dann sende ich einen Schließbefehl an die serielle Schnittstelle.

Ich habe ein untergeordnetes QWidget für mein Hauptfenster, das diesen Befehl beim Beenden aufruft:

/* In the constructor */
connect(this, SIGNAL(WindowClosed()), mydevice, SLOT(closeSerialPort()));


void mainwindow::closeEvent(QCloseEvent *event)
{
emit WindowClosed();
event->accept();
}

Gibt es einen Grund für dieses Verhalten? Ich gehe davon aus, dass ich den Port irgendwie blockiere, aber es würde sich sicherlich beschweren, dass er bereits offen ist.

Ein weiteres seltsames Problem ist, dass das Gerät eingeschaltet istCOM1 und ich öffne es in meiner Anwendung, COM1 reagiert im anderen Dienstprogramm nicht und das Gerät wird auf COM2 angezeigt. Wenn ich jedoch zu meinem Programm zurückschalte und ein wenig fummle, wird das Gerät wieder auf COM1 angezeigt (in der anderen Anwendung jedoch immer in COM2).

Antworten:

1 für die Antwort № 1

Es scheint also eine ziemlich einfache Lösung zu geben, obwohl ich nicht genau verstehe, was das Problem verursacht hat.

Ich habe zwei Threads, die jeweils einen anderen steuernserielles Gerät. Der Zugriff auf die serielle Konfiguration erfolgt über einen Dialog, den ich aus einem QT-Beispiel (dem Terminal) gestohlen habe. Jeder Thread hat eine Instanz dieses Einstellungsdialogs. Bei der Auswahl des Ports scheint etwas schief zu gehen - zum Beispiel zeigen alle Auswahlen im Dialogfeld tatsächlich auf denselben COM-Port, wenn sie in einem Debugger aktiviert sind.

Wie auch immer, ich habe das auf nicht-thread-sicheren Code gebrachtund das Programm geändert, um nur nach dem Namen der seriellen Schnittstelle zu fragen, da die Datenraten, Stoppbits, Parität usw. von der Hardware behoben werden und sich nicht ändern werden. Dies hat das Problem behoben.


0 für die Antwort № 2

Ich denke, es gibt zwei mögliche Antworten:

  1. Ihr Prozess wird nicht beendet, obwohl Sie das Hauptfenster geschlossen haben. Wie haben Sie sichergestellt, dass der Prozess tatsächlich beendet wurde?

  2. Ihre Verwendung des seriellen Port-Moduls von qt legt einen Fehler im FTDI-Treiber offen. Das ist nicht undenkbar, aber ich würde es im Moment eine entfernte Möglichkeit nennen.

Persönlich sehe ich keine Verwendung für die SeriennummerDie Port-Emulation des FTDI-Treibers fügt ohne guten Grund eine zusätzliche Ebene hinzu. Die D2XX-Schnittstelle ist der Weg, dies zu tun, wenn Sie so etwas nicht verwenden möchten libftdi. Unter Windows habe ich festgestellt, dass D2XX und libftdi die einzigen Alternativen sind, bei denen libftdi auf virtuellen Maschinen viel besser funktioniert als D2XX.


0 für die Antwort № 3

Ich weiß nicht, ob dies nützlich sein könnte.

Ich habe ein ähnliches Problem (aber nicht dasselbe) mit einemproduktives pl2303. In meinem Fall, wenn ich den Port schließe (oder sogar beim Start, bevor ich ihn öffne!), Werden die Daten irgendwie empfangen und sofort angezeigt, wenn ich den Port öffne.

Dies geschieht nur mit einem USB-RS232-Adapter. Wenn ich den TtyS0 (physische serielle Schnittstelle) verwende, tritt das Problem nicht auf.

Die Lösung für mich war, QSerialPort :: clear () zu zwingen, die Puffer direkt nach QSerialPort :: open () zu löschen. Dadurch wird vermieden, dass das Signal readyRead gesendet und somit unerwünschte Daten empfangen werden.