Ports parallel abfragen
Ports parallel abfragen
Hallo Qt-Gemeinde,
ich habe ein Terminalprogramm geschrieben. Ich stelle den Comport und Baudrate ein und mit "V" meldet sich mein Gerät.
Nun wollte ich es automatisieren und an alle Com-Ports ein V senden und schauen welcher sich meldet.
Dies habe ich in einer Schleife gelöst:
1. Port öffnen
2. "V" senden
3. Auf eine Antwort warten
4. Port schließen
5. Nächsten Port öffnen
Das klappt auch alles. Allerdings nutze ich auch Bluetooth und da werden gerne mal 10 oder mehr Ports angelegt die abgefragt werden müssen. Da dauert es wirklich sehr lange.
Es sollte aber doch möglich sein alle Ports gleichzeitig zu öffnen und schauen welcher Port sich zurück meldet.
Ich habe es mit Objekten versucht. Dafür erstelle ich z.B 10 Comport Objekte und weise jedem Objekt einen eigenen Port zu. Leider habe ich dadurch keine Geschwindigkeitsverbesserung erziehlt.
Wären Threads eine Lösung? Ich habe allerdings von Threads gar keine Ahnung und weiß nicht, was diese überhaupt leisten können.
Vielen Dank
ich habe ein Terminalprogramm geschrieben. Ich stelle den Comport und Baudrate ein und mit "V" meldet sich mein Gerät.
Nun wollte ich es automatisieren und an alle Com-Ports ein V senden und schauen welcher sich meldet.
Dies habe ich in einer Schleife gelöst:
1. Port öffnen
2. "V" senden
3. Auf eine Antwort warten
4. Port schließen
5. Nächsten Port öffnen
Das klappt auch alles. Allerdings nutze ich auch Bluetooth und da werden gerne mal 10 oder mehr Ports angelegt die abgefragt werden müssen. Da dauert es wirklich sehr lange.
Es sollte aber doch möglich sein alle Ports gleichzeitig zu öffnen und schauen welcher Port sich zurück meldet.
Ich habe es mit Objekten versucht. Dafür erstelle ich z.B 10 Comport Objekte und weise jedem Objekt einen eigenen Port zu. Leider habe ich dadurch keine Geschwindigkeitsverbesserung erziehlt.
Wären Threads eine Lösung? Ich habe allerdings von Threads gar keine Ahnung und weiß nicht, was diese überhaupt leisten können.
Vielen Dank
Ich erstelle comport Objekte und weise den Objekten jeweils einen vorhandenen Comport zu. Die Objekte speichere ich einer einer QHash. Welche Comports wirklich existieren habe ich vorher abgefragt und in einer QStringlist comliste gespeichert.
Die comliste gibt dann einen String in der Form "COM1" usw zurück.
In der Klasse Comports findet die Abfrage statt.
Wenn ein Objekt erstellt wurde, dauert es doch recht lange bis das Nächste erstellt wird.
Ich würde gerne alle Objekte "gleichzeitig" erstellen und z.B nach 5Sek abfragen, ob sich auf einem Port etwas auf "V" gemeldet hat.
Ich hatte mit einen Gschwindigkeitsgewinn durch die Erstellung von Objekten in der for-Schleife erhofft, aber leider half es nichts
Die comliste gibt dann einen String in der Form "COM1" usw zurück.
Code: Alles auswählen
QHash<int, Comports*> porthash;
for(int i=0; i<=9; i++)
{
porthash[i] = new Comports(comliste.at(i));
}
Code: Alles auswählen
Comports::Comports(QString com)
{
comport = com;
verbinde();
qDebug() << "Erstelle Port";
}
Code: Alles auswählen
void Comports::verbinde()
{
portIni(comport); //ComPort wird inistalisiert
// Sende ein V und warte schaue ob sich etwas am Port zurück meldet
WriteFile(hCom,"V",1,&dwBytesWritten,0);
qWait(100); //Warte 100ms
ReadFile(hCom,&output,1000,&dwBytesRead,0);
if(dwBytesRead != 0)
{
//Es gab eine Antort auf "V". Mein Gerät wurde gefunden
}
CloseHandle(hCom);
}
Ich würde gerne alle Objekte "gleichzeitig" erstellen und z.B nach 5Sek abfragen, ob sich auf einem Port etwas auf "V" gemeldet hat.
Ich hatte mit einen Gschwindigkeitsgewinn durch die Erstellung von Objekten in der for-Schleife erhofft, aber leider half es nichts
Ohne ein vollständiges Pflichtenheft sind Tipps zum Aufbau einer Software immer schwierig (bis sogar gefährlich..). Aber das, was du bisher gezeigt hast, könnte man schon als Thread-Anwendung implementieren.
Es gibt immer viele Möglichkeiten, eine (Thread-)Anwendung zu implementieren, aber ich zeig mal ein paar Schlüsselstellen zu einer möglichen Lösung:
Initialisierung:
Methode testPort:
Die Grundlagen zu den Threads musst du dir natürlich selbst erarbeiten.
hth..
Es gibt immer viele Möglichkeiten, eine (Thread-)Anwendung zu implementieren, aber ich zeig mal ein paar Schlüsselstellen zu einer möglichen Lösung:
Initialisierung:
Code: Alles auswählen
QThread *context1 = new QThread();
Comports *comPort = new Comports();
// Startet den Auftrag, sobald der Thread läuft
connect(context1,SIGNAL(started()),
comPort, SLOT(testPort()));
// Liefert das Ergebnis
connect(comPort,SIGNAL(deviceDetected(QString,bool)),
this, SLOT(portResult(QString,bool)));
comPort->moveToThread(context1 );
context1->start();
Methode testPort:
Code: Alles auswählen
void Comports::testPort()
{
portIni(comport); //ComPort wird inistalisiert
// Sende ein V und warte schaue ob sich etwas am Port zurück meldet
WriteFile(hCom,"V",1,&dwBytesWritten,0);
qWait(100);
ReadFile(hCom,&output,1000,&dwBytesRead,0);
if(dwBytesRead != 0)
emit deviceDetected(comport,true);
else
emit deviceDetected(comport,false);
CloseHandle(hCom);
} hth..
Für lese und schreibe operationen auf ressourcen bietet windows eh die "assynchronen Ports" an ...
Man kann also den lesevorgang starten lassen und hinterlegt eine routine, die gefeuert wird wenn die daten vollstaendig gelesen wurden.
Das ist so ziemlich das effektivste unter windows fuer assynchrones lesen. Braucht man keine threads zu (macht das BS).
Da hier effektivitaet ned im Vordergrundsteht, kann man das threaden auch selbst uebernehmen und weiterhin blockierende aufrufe verwenden ... Ist IMHO etwas intuitiver zu programmieren. mit den Overlapped und callbacks kriegt man noch mehr Kopfschmerzen auf Dauer als wie mit threading
Wobei es schon miteinander verwand ist
"Pollen" macht IMHO wenig Sinn bei threads + blockierenden zugriffen.
mann kann die timouts fuer read und write so stellen, das die dinger "ewig auf daten warten" ... warum dann pollen ?
Ciao ...
Man kann also den lesevorgang starten lassen und hinterlegt eine routine, die gefeuert wird wenn die daten vollstaendig gelesen wurden.
Das ist so ziemlich das effektivste unter windows fuer assynchrones lesen. Braucht man keine threads zu (macht das BS).
Da hier effektivitaet ned im Vordergrundsteht, kann man das threaden auch selbst uebernehmen und weiterhin blockierende aufrufe verwenden ... Ist IMHO etwas intuitiver zu programmieren. mit den Overlapped und callbacks kriegt man noch mehr Kopfschmerzen auf Dauer als wie mit threading
"Pollen" macht IMHO wenig Sinn bei threads + blockierenden zugriffen.
mann kann die timouts fuer read und write so stellen, das die dinger "ewig auf daten warten" ... warum dann pollen ?
Ciao ...
Ich habe ein einfaches QThread-Beispiel im Internet gefunden und auf mein Program übertragen.
Es läuft jetzt so ab:
Und im Hauptprogram
Dadurch hat sich die "Abfragegeschwindigkeit" mehr als verdoppelt.
Dies ist bestimmt nicht der Königsweg, aber schon ein großer Fortschritt für mich
Es läuft jetzt so ab:
Code: Alles auswählen
void Comports::run()
{
qDebug() << "run() läuft";
portIni(comport); //ComPort wird inistalisiert
// Sende ein V und warte schaue ob sich etwas am Port zurück meldet
WriteFile(hCom,"V",1,&dwBytesWritten,0);
qWait(100); //Warte 100ms
ReadFile(hCom,&output,1000,&dwBytesRead,0);
if(dwBytesRead != 0)
{
//Es gab eine Antort auf "V". Mein Gerät wurde gefunden
}
CloseHandle(hCom);
}
Code: Alles auswählen
for(int i=0; i<=9; i++)
{
porthash[i] = new Comports(comliste.at(i));
}
for(int i=0; i<=9; i++)
porthash[i]->start();
Dies ist bestimmt nicht der Königsweg, aber schon ein großer Fortschritt für mich