Qextserialport und QTextEdit

Gast #3185125
Lesenswert?

Original funktion:
1
void Dialog::onReadyRead()
2
{
3
    if (port->bytesAvailable()) {
4
        ui->recvEdit->moveCursor(QTextCursor::End);
5
        ui->recvEdit->insertPlainText(QString::fromLatin1(port->readAll()));
6
    }
7
}

Fehlerfreie Ausgabe in QTextEdit (Projektspezifische Variable mit 
Wert..):
1
azimut_145
2
azimut_145
3
azimut_145
4
<usw ..>

Geänderte funktion:
1
void Dialog::onReadyRead()
2
{
3
    if (port->bytesAvailable()) {
4
        ui->recvEdit->moveCursor(QTextCursor::End);
5
        ui->recvEdit->insertPlainText(QByteArray("some text:"));
6
        ui->recvEdit->insertPlainText(QString::fromLatin1(port->readAll()));
7
    }
8
}

Fehlerbehaftete Ausgabe in QTextEdit:
1
some text:azimut_145
2
some text:azimut_145
3
some text:azimut_145
4
some text:azimut_145
5
some text:azimut_145some text:
6
some text:azimut_some text:145
7
some text:azimusome text:t_145
8
some text:azsome text:imut_145
9
some text:azimut_145
10
some text:azimut_145
11
<usw ..>

Die Ausgabe erfolgt also verschachtelt und zufällig! Meine Vermutung: 
Irgendwelche Threads werden parallel abgearbeitet.

Lösungsvorschläge?

Programminfos:
Qextserialport 1.2 beta
qt 5.0.1 unter qt creator 2.6.2

Gruß Stefan
Persönliche Seite #3187680
Lesenswert?

Stefan R schrieb:
> Die Ausgabe erfolgt also verschachtelt und zufällig! Meine Vermutung:
> Irgendwelche Threads werden parallel abgearbeitet.

Nö das Programm macht schon genau das was es soll, nur ist es nicht das 
was du möchtest!

> Lösungsvorschläge?
1. Mach dir mal Gedanken was die beiden Methoden bytesAvailable() und 
readAll() machen könnten.

2. Informiere dich mal über Zeilenabchlusszeichen.
#3188090
Lesenswert?

M. K. schrieb:
> Stefan R schrieb:
>> Die Ausgabe erfolgt also verschachtelt und zufällig! Meine Vermutung:
>> Irgendwelche Threads werden parallel abgearbeitet.
>
> Nö das Programm macht schon genau das was es soll, nur ist es nicht das
> was du möchtest!

Also mir würde da jetzt kein Grund einfallen, warum sich das Programm so 
verhalten sollte.
Persönliche Seite #3188222
Lesenswert?

Das Problem was Stefan R hat ist, dass die PC-Software und der Sender 
nicht synchronisiert sind.

Er fragt einfach nach ob Daten im Puffer sind:
 ja   : "some text:" ausgeben und eingelesenes anhängen
 nein : na dann versuche ich es so schnell wie möglich noch einmal

Jetzt passiert folgendes:
Die ersten male passt die Zeitspanne von bytesAvailable() bis readAll() 
und die Daten werden sauber ausgegeben.

Beim nächsten mal war der PC aber mit readAll() schneller fertig als der 
Sender den Puffer füllen konnte und schon haben wir den Salat.

Dank Präemptiven Multitasking [1] kann man kaum vorhersagen wie viel 
Zeit zwischen den Aufrufen von bytesAvailable() und readAll() 
verstreichen.

Außerdem ist überhaupt nicht sicher zu welchem Zeitpunkt die Methode 
bytesAvailable() aufgerufen wird, dass kann schon nach dem ersten Byte 
sein oder auch wenn der Sender bereits alles losgeworden ist. Die 
Methode bytesAvailable() sagt zwar wie viele Bytes sich im Puffer 
befinden, dies wird hier aber überhaupt nicht ausgewertet.

[1] 
http://de.wikipedia.org/wiki/Multitasking#Pr.C3.A4emptives_Multitasking
#3188301
Lesenswert?

Ja, du hast natürlich recht. Daß Daten da sind bedeutet nicht 
automatisch, daß es sich dabei um genau eine komplette Zeile handelt.
Wenn er das will, sollte er sich evtl. mal die Funktionen canReadLine() 
und readLine() statt bytesAvailable() und readAll() anschauen.

M. K. schrieb:
> Dank Präemptiven Multitasking [1] kann man kaum vorhersagen wie viel
> Zeit zwischen den Aufrufen von bytesAvailable() und readAll()
> verstreichen.

Das ist aber auch relativ egal. Wenn Bytes verfügbar sind, sind sie das 
auch später noch, sofern sie zwischendurch niemand anders ausliest.

M. K. schrieb:
> Er fragt einfach nach ob Daten im Puffer sind:
>  ja   : "some text:" ausgeben und eingelesenes anhängen
>  nein : na dann versuche ich es so schnell wie möglich noch einmal

Ich vermute, daß "onReadyRead()" ein Slot ist, der automatisch 
aufgerufen wird, wenn sich was an der Schnittstelle getan hat. Damit 
wird es nicht so schnell wie möglich versucht, sondern erst wenn das 
nächste Mal Daten zur Abholung bereit stehen.
Gast #3189040
Lesenswert?

Vielen Dank für eure Hilfe, dass Problem ist nun gelöst.

Hier die Zusammenfassung der Änderungen zum original Code:
1
port = new QextSerialPort(ui->portBox->currentText(), settings, QextSerialPort::EventDriven);
2

3
connect(port, SIGNAL(readyRead()), SLOT(onReadyRead()));
4

5
void Dialog::onReadyRead()
6
{
7
    if (port->canReadLine())
8
    {
9
        ui->recvEdit->appendPlainText("uC> " + QString::fromLatin1(port->readLine()));
10
    }
11
]

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren