Forum: PC-Programmierung Daten mittels QextSerialPort senden


von Eric P. (red_roxxor)


Lesenswert?

Hi,
Hab mal wieder ein kleines Problem und find selbst keine Lösung dafür, 
vielleicht könnt ihr mir helfen.

Das Empfangen von Daten funktioniert eig. einwandfrei, aber das senden 
will einfach nicht funktionieren.

Hier mal der Code:
1
#include "com.h"
2
#include <QDebug>
3
4
com::com()
5
{
6
    port = new QextSerialPort("COM2", QextSerialPort::EventDriven);
7
    port->setBaudRate(BAUD9600);
8
    port->setFlowControl(FLOW_OFF);
9
    port->setParity(PAR_NONE);
10
    port->setDataBits(DATA_8);
11
    port->setStopBits(STOP_1);
12
13
    if(port->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
14
    {
15
        qDebug()<<"port opened";
16
    }
17
18
    QObject::connect(port, SIGNAL(readyRead()), this, SLOT(handleData()));
19
}
20
21
22
void com::handleData()
23
{
24
    if(sender() == port)
25
    {
26
        const QByteArray result = port->readAll();
27
        uchar tmp = 0;
28
29
        QList<int> data;
30
31
        for(int i = 0; i < result.size(); ++i)
32
        {
33
            const uchar val = result.at(i);
34
            if(i % 2 == 0)
35
            {
36
                tmp = val;
37
            }
38
            else
39
            {
40
                data << (tmp + val);
41
            }
42
        }
43
44
        qDebug()<<data;
45
    }
46
}
47
48
49
void com::sendData(QByteArray& data)
50
{
51
    QMutex m;
52
    m.lock();
53
    int i;
54
    if(!(i = port->write(data)))
55
    {
56
        qDebug()<<port->errorString();
57
    }
58
    m.unlock();
59
60
    qDebug("trasmitted : %d", i);
61
}

Wenn ich
1
port = new QextSerialPort("COM2", QextSerialPort::EventDriven);
durch
1
port = new QextSerialPort("COM2");
 ersetze funktioniert das senden(ob diese jedoch richtig sind kann ich 
nicht sagen da ich nict mehr empfangen kann) jedoch nicht mehr das 
Empfangen (readyRead() wir nicht mehr erkannt).

Finde leider nicht wirklich was in der Doku oder in anderen Beispielen.

Hoffe ihr könnt mir bald helfen brauchs für die Schule und muss es bald 
abgeben.
lg Eric

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Und wenn du in sendData() mit write() die writeData() (Für Windows und 
Posix) benutzt? Der Hauptunterschied zwischen deiner Eigenvariante und 
den  writeData() Implementierungen ist ein fflush(), welches bei deiner 
Variante fehlt. Möglicherweise gehen deshalb keine Zeichen raus...

Wenn du auf writeData() wechselst, kannst du die MUTEX Geschichte 
weglassen bzw, das handelt die Funktion selbst. Wenn selbst die 
writeData() (aka sendData) implementierst, dann schau dir die Windows 
und Posix Implementierungen an.

http://qextserialport.sourceforge.net/qextserialport-1.1.x/classQextSerialBase.html#39a3aaff93640b767fd44dd7ce705e01

von Eric P. (red_roxxor)


Lesenswert?

Danke für die schnelle Antwort.
writeData() is leider protected und ich möcht eig. nicht von 
QextSerialPort erben.
Kennt sich vielleicht jemand mit dem Konstruktor aus? Was genau bewirkt 
das EventDriven und was wären andere Möglichkeiten? Die serialport Doku 
macht mich fertig fin einfach gar nix.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dein Code ist vielleicht "Out of Sequence":

    port = new QextSerialPort("COM2", QextSerialPort::EventDriven);
    port->setBaudRate(BAUD9600);
    port->setFlowControl(FLOW_OFF);
    port->setParity(PAR_NONE);
    port->setDataBits(DATA_8);
    port->setStopBits(STOP_1);

    if(port->open(QIODevice::ReadWrite | QIODevice::Unbuffered))
    {
        qDebug()<<"port opened";
    }

https://code.google.com/p/qextserialport/issues/detail?id=58#c3
>> I FINALLY figured this one out. Apparently, setting the port settings
>> has no effect until the port is open. It seems like a library bug. Here
>> is my working code...

Wenn das so ist, könnte z.B. diese Beobachtung zuschlagen:
Beitrag "Re: Beispielprogramm RS232 mit Qt (win)"
>> Was bei mir dazu geführt hat, dass nichts ausgegeben wurde, war, dass
>> standardmäßig FlowControl eingeschalten ist. Ich habs in meinen
>> Standardeinstellungen dann ausgeschalten.

> Was genau bewirkt das EventDriven und was wären andere Möglichkeiten?

Die andere Möglichkeit kennst du doch :) Polling
Beitrag "Serielle Schnittstelle mittels QextSerialPort ansprechen"

von Eric P. (red_roxxor)


Lesenswert?

Danke für die Antwort

Hab mir mal 2 Testprogramme mit beiden Möglichkeiten geschriebn kanns 
leider erst morgen testen da mein Diplomarbeitspartner das Ftdi-Kabel 
hat.

Ja Polling aber was ist der unterschied zu EventDriven und gibts 
vielleicht noch andere Möglichkeiten?

von Eric P. (red_roxxor)


Lesenswert?

Ok habs ausgiebig getest(writeData(...), write(...), Port-Settings erst 
nach öffnen setzen...) und ich bekomme nur Errors.

Hat niemand ein funktionierendes QextSerialPort Programm das senden kann 
und übers readyRead() Signal einliest?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Warst du schon im qtforum.de gewesen? Dort sind IMHO die Chancen Infos 
zu finden höher.

Ich habe mir eben QT3 auf Debian Linux installiert, weil ich ins Thema 
QT einsteigen will. QT3 statt QT4 weil ich da ein Buch in der 
Stadtbücherei gefunden habe und QT3 noch auf meinem älteren Windows PC 
lauffähig ist. Mittelfristig geht es mir sogar um QT2 für einen älteren 
Linux PDA :)

> Hat niemand ein funktionierendes QextSerialPort Programm das senden kann
> und übers readyRead() Signal einliest?

Vielleicht hilft dies:
http://qtforum.de/forum/viewtopic.php?t=5978

> kanns leider erst morgen testen da mein Diplomarbeitspartner das
> Ftdi-Kabel hat.

[zitat http://qtforum.de/forum/viewtopic.php?t=9202]
Ich hab nämlich grad ein ähnliches Problem.
Ein echter ComPort und ein virtueller ComPort.
Der echte kann event-gesteuert betrieben werden, der virtuelle nicht.
[/zitat]

Wenn du ein gutes Beispiel findest, melde dich bitte nochmal.

Vielleicht auch mal den Ersatz von QextSerialPort überlegen (wenn GPL 
nicht stört)

QSerialDevice v 0.2.0
http://qtforum.de/forum/viewtopic.php?t=11072
http://qtforum.de/forum/viewtopic.php?t=11295

von Eric P. (red_roxxor)


Lesenswert?

Erstmal vielen Dank für die Hilfe.

Hab mein Problem gelöst und schreib mal den Lösungsweg:

1. write() funktioniert mit QueryMode: QextSerialPort::EventDriven und 
QextSerialPort::Polling, aber auch bei nicht setzten funktionierts.
Problem ist nur bei EventDriven ist der Rückgabewert von write() immer 
-1, was soviel wie Fehler heißt, trozdem funktioniert es => auf den 
Error pfeifen!

2. Port settings erst nach dem öffnen des Ports setzen! Da sonst die 
Möglichkeit besteht, dass bei Windows-Systemen am Anfang falsche Werte 
eingelesen werden.

3. Eingelesene Daten mit (uchar) casten da sonst -> Hieroglyphen, 
Falsche Werte, Leerzeichen...

4. Mit dem FTDI Kabel hab ich auch einen virtuellen Port, es 
funktionieren beide QueryModes.

5. In Windows heißen COM-Ports ab COM10 anders!!

Hier das .cpp File (in handleData() addiere ich immer 2 Werte da ich vom 
µC 10Bit Werte bekomme die in 2 Byte gesendet werden (zb.: 00000011 
11111111))
1
#include "com.h"
2
#include <QDebug>
3
4
5
com::com()
6
{
7
    port = new QextSerialPort("COM2", QextSerialPort::EventDriven);
8
9
    port->setPortName("COM2");
10
    port->setQueryMode(QextSerialPort::EventDriven);
11
12
    QObject::connect(port, SIGNAL(readyRead()), this, SLOT(handleData()) );
13
14
    openPort();
15
}
16
17
18
void com::handleData()
19
{
20
    qDebug()<<"in handleData";
21
22
    if(sender() == port)
23
    {
24
        const QByteArray result = port->readAll();
25
        uchar tmp = 0;
26
27
        QList<int> data;
28
29
        for(int i = 0; i < result.size(); ++i)
30
        {
31
            const uchar val = result.at(i);
32
            if(i % 2 == 0)
33
            {
34
                tmp = val;
35
            }
36
            else
37
            {
38
                data << (tmp + val);
39
            }
40
        }
41
42
        qDebug()<<data;
43
    }
44
}
45
46
47
void com::sendData(const char* data)
48
{
49
    QMutex m;
50
    m.lock();
51
    port->flush();
52
    const char tmp = 255;
53
    int i = port->write((const char*) &tmp, 1);
54
    qDebug()<<"transmitted: "<<i;
55
    m.unlock();
56
}
57
58
59
void com::openPort()
60
{
61
        port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
62
        qDebug("is open: %d", port->isOpen());
63
        port->setBaudRate(BAUD9600);
64
        port->setFlowControl(FLOW_OFF);
65
        port->setParity(PAR_NONE);
66
        port->setDataBits(DATA_8);
67
        port->setStopBits(STOP_1);
68
}
69
70
bool com::isPortOpen()
71
{
72
    return port->isOpen();
73
}

von Eric P. (red_roxxor)


Lesenswert?

Kleiner Fehler noch im Code

sendData() braucht bei dem Test natürlich keine Übergabeparameter.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sehr schön! Wenn ich an die Stelle komme, bin ich bestimmt froh, dass es 
diesen Beitrag gibt. Im Moment backe ich noch kleinere Brötchen :)

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.