Forum: PC-Programmierung Qextserialport und QTextEdit


von Stefan R (Gast)


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

von Jörg B. (jbernau)


Lesenswert?

Stefan R schrieb:
> ui->recvEdit->insertPlainText(QByteArray("some text:"));

ui->recvEdit->insertPlainText("some text:");

Weshalb nicht gleich QString verwenden? Sonst wird aus QBytrAtrray 
später QString ...


Grüßle

von Rolf M. (rmagnus)


Lesenswert?

Hast du mal versucht, zwischen den beiden Ausgaben den Cursor nochmal 
explizit ans Ende zu setzen?

von Stefan R. (lenox)


Lesenswert?

Hallo Jörg, hallo Rolf,

beides habe ich expiziet probiert, ohne Erfolg. Gleiches Fehlerbild.

Gruß Stefan

von hans (Gast)


Lesenswert?

versuch mal
1
void Dialog::onReadyRead()
2
{
3
    if (port->bytesAvailable())
4
    {
5
        QString buffer;
6
        buffer.append("some Text:");
7
        buffer.append(QString::fromLatin1(port->readAll());
8
        ui->recvEdit->append(buffer);
9
    }
10
}
insertPlainText

von Rolf M. (rmagnus)


Lesenswert?

hans schrieb:
>         QString buffer;
>         buffer.append("some Text:");
>         buffer.append(QString::fromLatin1(port->readAll());
>         ui->recvEdit->append(buffer);

oder auch gleich:
1
        ui->recvEdit->append("some Text:" + QString::fromLatin1(port->readAll());

von M. K. (avr-frickler) Benutzerseite


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.

von Rolf M. (rmagnus)


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.

von M. K. (avr-frickler) Benutzerseite


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

von Rolf M. (rmagnus)


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.

von Michael J. (jogibaer)


Lesenswert?

Hallo,

ich benutze auch Qextserialport.

Allerdings mache ich es per Signal/Slot.

Daten hole so ab:
QByteArray data = Port->readAll();

Dabei sind die Daten in einem Protokoll eingebettet.


Jogibär

von Stefan R (Gast)


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
]

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.