QextSerialPort::readLine() Problem

Verschiedenes zu Qt
Antworten
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

QextSerialPort::readLine() Problem

Beitrag von Muckl »

Hallo,

Ich beginne mal ein neues Thema, da mein altes "QSerialDevice Problem" nicht mehr ganz aktuell ist.
Ich lesen mit QExtserialPort Daten von einer Seriellen Schnittstelle. Ich habe ein Timer der alle 100ms die readLine() Funktion ausführt. Danach parse ich die Daten. Mein Problem ist, dass readLine() entweder eine ganze Zeile einliest, oder so viel bis die maximale Schriftzeichenanzahl erreicht ist oder bis keine Daten mehr vorhanden sind. Das letzte ist genau mein Problem, gelegtenlich wird nicht die ganze Zeile eingelesen, sodern der Rest der Zeile erst im nächsten Zeitschritt. Dies führt dazu, dass mein Parser auf einen Index (QStringList[Index]) zugreifen will, der nicht vorhanden ist, da die Zeile ja abgeschnitten wurde. Ist es möglich, dass readLine so lange einliest, bis die Zeile wirklich voll ist und nicht vorher aufhört, da keine Daten mehr vorhanden sind? Oder hat jemand eine andere Idee?

Gruß,
Muckl
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Daten zwischenspeichern und das nächste Mal parsen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

Beitrag von Muckl »

moin,

ja, das problem ist, dass die Zeilen nciht alle gleich lang sind. Dann müsste ich ja vorher prüfen, um welche Zeile es sich handelt, dann ob die komplette länge eingelesen wurde und dann einen parser für das parsen der ganzen Zeile und einen variablen parser zum parsen von Bruchstücken erstellen.
Habe das jetzt so gemacht, dass er jeden Charakter einzeln einliest und so lange an einen QString ranhängt, bis "\n" kommt. Die Zeilen werden nun komplett eingelesen, jedoch muss ich ja vorher abfragen, ob überhaupt daten vorhanden sind und so lange keine vorhanden sind, sitzt er für die zeit in einer Dauerschleife. Was dann für ein paar ms das Einfrieren der GUI zur folge hat. (merkt man nur beim verschieben der GUI). Aber vielleicht kann man das mit einem kurzen Timeout für z.B. 50ms beheben.

Ein anderes Problem ist noch, dass die Schnittstelle, ( wenn man mal keine Daten ausliest), bis zu 4096 Zeichen abspeichert. Starte ich dann das auslesen wieder, muss er erstmal diese daten auslesen, bis er an die aktuellen Daten kommt. Kann man diesen Puffer deaktivieren. Ich habe schon viel Gegoogle, jedoch keine wirklich gute Dokumentation von QEXTSerialPort gefunden.
http://qextserialport.sourceforge.net/ hier sind zwar alle Klassen und Methoden angegeben, jedoch wird nciht gesagt, was sie bewirken.

gruß,

Muckl
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ein Stream ist nunmal ein Stream der kein Anfang und Ende hat. Diesen muss man sich über geeignete Start/Endemarkierungen selbst holen. Ist aber kein serial-spezifisches Problem sondern ein allgemeines.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
bronko
Beiträge: 40
Registriert: 19. Mai 2009 15:49

Beitrag von bronko »

evtl. hilft dir das SLIP Protokoll oder etwas änliches
Ritchie
Beiträge: 86
Registriert: 29. Januar 2007 19:41

Beitrag von Ritchie »

Hallo Muckl,

warum liest Du die Daten von der seriellen Schnittstelle nicht in einem
parallelen Thread ein und übergibst Deinem Hauptprogramm ein Flag,
welches kennzeichnet, das ein Datenpaket korrekt eingelesen wurde ?

Gruss R.
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

Beitrag von Muckl »

Hallo bronko und Ritchie,
vielen Dank für die Antwort.
So wie du vorgeschlagen hast, mach ich das jetzt Multithreaded. Dies ist mal wieder Neuland für mich, aber mit QT scheint das nciht sonderlich schwer zu sein.

Gruß,

Muckl
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

Beitrag von Muckl »

Hallo,

es läuft nun mit zwei Threads. Das Hauptfenster ist der MainThread und dieser erstellt dann den zweiten Thread, der den Port öffnet und die Daten list. Nun muss man ja, um den Port zu öffnen, bzw. die Daten zu lesen, Portsettings eingeben. Diese möchte ich über ein zweitest QWidget eingeben. Um kurz meine Klassen und DateiStruktur zu erklären: Ich habe eine "Main", eine MainWindow.cpp sowie MainWindow.h die zur Erzeugung des Hauptfensters benötigt werden und eine SerialPort.cpp und SerialPort.h die als zweiter Thread zum lesen der Daten da sind. Ich habe mir nun mit dem Designer ein Widget erstellt und in der SerialPort.h eine Instanz dieses Widget erstellt. Nun müsste ich doch mit der show() Methode innerhalb von Mainwindow.cpp dieses Widget öffnen können.
Meine Frage ist nun, ob dies überhaupt der richtige Weg ist, um ein zusätzliches Fenster zu öffnen ? Ich Poste mal etwas Quellcode, wie ich mir das vorstelle. Hier ist alles für den Thread und das Hauptfenster weggelassen. Diese Sachen laufen ja.

SerialPort.h



Code: Alles auswählen


#include "ui_SerialPort.h"

class SerialPort : public QThread, public QWidget
{

Q_OBJECT

public:
	SerialPort();


private:
        Ui::SerialPort settings;

};


SerialPort.cpp

Code: Alles auswählen

#include SerialPort.h

SerialPort::SerialPort()
{

}


Mainwindow.cpp

Code: Alles auswählen


MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
      : QMainWindow(parent, flags)
{

      MyPort.show();

}



MainWindow.h

Code: Alles auswählen


class MainWindow : public QMainWindow
{
	Q_OBJECT

public:
	MainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
	~MainWindow();


private:
        SerialPort MyPort;

};



Zusätzliche Frage ist: Warum kann ich mit MyPort.show() das Fenster öffnen? Eigentlich müsste es doch MyPort.Settings.show() sein. Jedoch wird es beim öffnen des Hauptfensters auch so gemacht, ohne die Instanz mit anzugeben. Also, wenn ich das so laufen lasse, offnet er nicht das von mir erstellte Widget, sondern einfach ein leeres!?!?!

Besten Dank,

gruß,
Muckl
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Vergiss die Threads. Das ganze geht auch ohne. Und wenn Du wirklich Threads verwenden willst dann LIES DIE DOKU zu QThread und schmeiss nicht einfach alles zusammen was Du gerade so findest. Nur weil man von QThread ableitet läuft es nicht automatisch in einem anderen Thread. Ganz zu schweigen dass GUI-Objekte und Operationen nur im Hauptthread ausgeführt werden dürfen. Das ganze funktioniert prima ohne Threads... :roll:
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

Beitrag von Muckl »

Moin,

also, dass mti den Threads fuktioniert eigentlich super. Ich glaube, ich werde auch nicht drum herum kommen, da später evtl auch noch daten von anderen Schnittstellen zeitgleich eingelesen werden sollen. Und sämtliche daten auch noch verarbeitet werden müssen. Das mit den Threads habe ich mir auch schon angeguckt. Ich habe jetzt nur den ganzen Threadkram nciht mit in den obigen Code reingetan, da es mir darum garnciht mehr geht. Was du sagtest, von wegen, GUI darf nur im Hauptthread. wenn das so ist, dann funktioniert dass wohl so wie ich das dachte nicht. Dann muss ich mir wohl was anderes überlegen, die Schnittstelle modularisiert hin zu bekommen. Wie ist denn das, kann man zwei gleichwertige Threads erzeugen, die dann beide GUI Objekte beinhalten dürfen?
Gruß,
Muckl
Willi2793
Beiträge: 147
Registriert: 29. September 2008 10:59
Kontaktdaten:

Beitrag von Willi2793 »

Nähern wir uns der Frage dochmal mit einer Gegenfrage an: Wenn Du 2 gleichwertige Threads hättest, welcher davon wäre denn der erwähnte Hauptthread?
Muckl
Beiträge: 23
Registriert: 12. April 2011 15:21

Beitrag von Muckl »

jo, stimmt schon. Bei mir habe ich bis jetzt einen Hauptthread. Jedoch habe ich weiter oben den Tipp bekommen zwei parallele Threads zu nehmen. Dadrunter würde ich verstehen, dass es zwei gleichwertige sind. Aber deiner Frage entnehme ich, dass es wohl nciht geht.
Willi2793
Beiträge: 147
Registriert: 29. September 2008 10:59
Kontaktdaten:

Beitrag von Willi2793 »

Parallel laufend heißt nicht gleichberechtigt
Antworten