www.mikrocontroller.net

Forum: PC-Programmierung Daten mittels QextSerialPort senden


Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include "com.h"
#include <QDebug>

com::com()
{
    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";
    }

    QObject::connect(port, SIGNAL(readyRead()), this, SLOT(handleData()));
}


void com::handleData()
{
    if(sender() == port)
    {
        const QByteArray result = port->readAll();
        uchar tmp = 0;

        QList<int> data;

        for(int i = 0; i < result.size(); ++i)
        {
            const uchar val = result.at(i);
            if(i % 2 == 0)
            {
                tmp = val;
            }
            else
            {
                data << (tmp + val);
            }
        }

        qDebug()<<data;
    }
}


void com::sendData(QByteArray& data)
{
    QMutex m;
    m.lock();
    int i;
    if(!(i = port->write(data)))
    {
        qDebug()<<port->errorString();
    }
    m.unlock();

    qDebug("trasmitted : %d", i);
}

Wenn ich
port = new QextSerialPort("COM2", QextSerialPort::EventDriven);
durch
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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/qextserialpo...

Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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/de...
>> 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"

Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht 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))
#include "com.h"
#include <QDebug>


com::com()
{
    port = new QextSerialPort("COM2", QextSerialPort::EventDriven);

    port->setPortName("COM2");
    port->setQueryMode(QextSerialPort::EventDriven);

    QObject::connect(port, SIGNAL(readyRead()), this, SLOT(handleData()) );

    openPort();
}


void com::handleData()
{
    qDebug()<<"in handleData";

    if(sender() == port)
    {
        const QByteArray result = port->readAll();
        uchar tmp = 0;

        QList<int> data;

        for(int i = 0; i < result.size(); ++i)
        {
            const uchar val = result.at(i);
            if(i % 2 == 0)
            {
                tmp = val;
            }
            else
            {
                data << (tmp + val);
            }
        }

        qDebug()<<data;
    }
}


void com::sendData(const char* data)
{
    QMutex m;
    m.lock();
    port->flush();
    const char tmp = 255;
    int i = port->write((const char*) &tmp, 1);
    qDebug()<<"transmitted: "<<i;
    m.unlock();
}


void com::openPort()
{
        port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
        qDebug("is open: %d", port->isOpen());
        port->setBaudRate(BAUD9600);
        port->setFlowControl(FLOW_OFF);
        port->setParity(PAR_NONE);
        port->setDataBits(DATA_8);
        port->setStopBits(STOP_1);
}

bool com::isPortOpen()
{
    return port->isOpen();
}


Autor: Eric P. (red_roxxor)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleiner Fehler noch im Code

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

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.