Forum: Mikrocontroller und Digitale Elektronik Kommunikation mit USB-Bridge in QextSerialPort


von jax (Gast)


Lesenswert?

Hi,
ich würde gerne Daten von einem µC(bzw einer USB-Bridge) in einem 
Qt-Programm verarbeiten; bis jetzt habe ich immer hTerm genutzt. Nach 
etwas googeln bin ich dann auf QextSerialPort gestoßen und habs mal 
ausprobiert. Allerdings läuft es nicht und ich weiß auch nicht warum . 
Zum Test hab ich den TXD-Pin der Bridge auf den RXD-Pin gelegt, nun 
sollte alles was gesendet wird wieder zurück kommen... Es passiert aber 
nichts.
Meine Vermutung: die Verbindung zur Bridge schlägt fehl, da die 
SLOT-Methode onDataAvailable() nicht aufgerufen wird (port sendet nicht 
readyRead())
Hier mal mein Beispiel-Code:
///mainwindow.cpp
1
#include "mainwindow.h"
2
#include "ui_mainwindow.h"
3
4
MainWindow::MainWindow(QWidget *parent) :
5
    QMainWindow(parent),
6
    ui(new Ui::MainWindow)
7
{
8
    ui->setupUi(this);
9
    this->setFixedSize(1200,650);
10
    port = new QextSerialPort("COM18", QextSerialPort::EventDriven);
11
    port->setPortName("COM18"); /// habe ich aus hTerm übernommen; da war mein Gerät immer "COM18"
12
    port->setQueryMode(QextSerialPort::EventDriven);
13
    connect(port, SIGNAL(readyRead()), this, SLOT(onDataAvailable()));
14
    connect(this, SIGNAL(output(QList<int>)), this, SLOT(onOutput(QList<int>)));
15
    port->open(QIODevice::ReadWrite | QIODevice::Unbuffered);
16
    port->setBaudRate(BAUD9600);
17
    port->setFlowControl(FLOW_OFF);
18
    port->setParity(PAR_NONE);
19
    port->setDataBits(DATA_8);
20
    port->setStopBits(STOP_1);
21
    text = new QTextBrowser(this);
22
    text->resize(width(), height());
23
    sendData();
24
}
25
26
void MainWindow::onDataAvialable()
27
{
28
    QByteArray result = port->readAll();
29
            uchar tmp = 0;
30
31
            QList<int> data;
32
33
            for(int i = 0; i < result.size(); ++i)
34
            {
35
                const uchar val = result.at(i);
36
                if(i % 2 == 0)
37
                {
38
                    tmp = val;
39
                }
40
                else
41
                {
42
                    data << (tmp + val);
43
                }
44
            }
45
            output(data);
46
}
47
48
void MainWindow::sendData()
49
{
50
    QMutex m;
51
    m.lock();
52
    port->flush();
53
    const char tmp = 255;
54
    int i = port->write((const char*) &tmp, 1);
55
    m.unlock();
56
}
57
58
void MainWindow::onOutput(QList<int> src)
59
{
60
    for(int i=0;i<src.size();++i)
61
    {
62
        QString num;
63
        num.setNum(src.at(i));
64
        str.append(num);
65
        str.append("\n");
66
    }
67
    text->setText(str);
68
}
69
70
MainWindow::~MainWindow()
71
{
72
    delete ui;
73
}

MainWindow.h
1
#ifndef MAINWINDOW_H
2
#define MAINWINDOW_H
3
4
#include <QMainWindow>
5
#include "qextserialport.h"
6
#include <QMutex>
7
#include <QLabel>
8
#include <QTextBrowser>
9
#include <QGridLayout>
10
11
namespace Ui {
12
class MainWindow;
13
}
14
15
class MainWindow : public QMainWindow
16
{
17
    Q_OBJECT
18
    
19
public:
20
    explicit MainWindow(QWidget *parent = 0);
21
    ~MainWindow();
22
    void sendData();
23
signals:
24
    void output(QList<int> str);
25
public slots:
26
    void onDataAvialable( );
27
    void onOutput(QList<int> str);
28
private:
29
    QTextBrowser *text;
30
    Ui::MainWindow *ui;
31
    QextSerialPort *port;
32
    QString str;
33
};
34
35
#endif // MAINWINDOW_H

von Oliver J. (skriptkiddy)


Lesenswert?

http://www.qtcentre.org/threads/2375-QExtSerialPort-with-com-ports-above-com9

PS. Warum wertest du den Rückgabewert von port->open([...]) nicht aus?

Gruß Oliver

von jax (Gast)


Lesenswert?

Hmm oke, der Link hat schon mal geholfen.
port->open(..) ergibt nur true wenn das Gerät angeschlossen ist und der 
Name auf "\\\\.\\com18" steht. Nur wird onDataAvailable() immer noch 
nicht aufgerufen...

von Oliver J. (skriptkiddy)


Lesenswert?

Ruf mal port->open([...]) am Ende der Initialisierung von port auf.
Ich hab das bei mir so gemacht.

Gruß Oliver

von jax (Gast)


Lesenswert?

Nein, das hilft leider auch nicht. Ein Fehler war allerdings ein 
"Rechtschreibfehler" bei der Methode onDataAvailable(). Die war als 
onDataAvialable() deklariert und implementiert-> die in der 
Connect-Anweisung als Slot aufgeführte Methode gab es also gar nicht. 
Frage mich nur warum das nicht als Fehler angezeigt wurde. Na jedenfalls 
ist dieser Fehler behoben, hat allerdings null Auswirkung gezeigt. Das 
Problem muss also noch von irgendwas anderem verursacht werden...

von Oliver J. (skriptkiddy)


Lesenswert?

jax schrieb:
> Die war als
> onDataAvialable() deklariert und implementiert-> die in der
> Connect-Anweisung als Slot aufgeführte Methode gab es also gar nicht.

Das wird beim Ausführen auf der Konsole angezeigt.

Gruß Oliver

von jax (Gast)


Lesenswert?

Oliver J. schrieb:
> jax schrieb:
>> Die war als
>> onDataAvialable() deklariert und implementiert-> die in der
>> Connect-Anweisung als Slot aufgeführte Methode gab es also gar nicht.
>
> Das wird beim Ausführen auf der Konsole angezeigt.
>
> Gruß Oliver

Wie meinst du das, auf der Konsole ausführen...?

von jax (Gast)


Lesenswert?

Ahhhhh.....:
OnDataAvailable() wird nur dann aufgerufen, wenn Daten gesendet wurden. 
Und da ich in meiner Testschaltung (RXD on TXD) ja keine Daten senden 
kann, muss erst vom PC aus etwas gesendet werden.

von jax (Gast)


Lesenswert?

Eine Frage hätte ich allerdings noch...
Warum empfange ich auf dem PC nur Daten vom µC wenn der ISP-Programmer 
eingesteckt ist?

von Martin B. (martin_b97)


Lesenswert?

Hi,

leider musste ich die Erfahrung machen, dass alle QT Implementierungen 
für serielle Ports nicht wirklich gut funktionieren (sei es auf Linux 
oder Windows).

Für Linux habe ich eine gut funktionierende Lösung mit
http://sourceforge.net/projects/libserial
gefunden.

Grüße,
Martin

von Martin B. (martin_b97)


Lesenswert?

jax schrieb:
> Oliver J. schrieb:
>> jax schrieb:
>>> Die war als
>>> onDataAvialable() deklariert und implementiert-> die in der
>>> Connect-Anweisung als Slot aufgeführte Methode gab es also gar nicht.
>>
>> Das wird beim Ausführen auf der Konsole angezeigt.
>>
>> Gruß Oliver
>
> Wie meinst du das, auf der Konsole ausführen...?

Oliver meinte wohl, daß es eine Runtime-Meldung geben sollte, wenn ein 
Signal einen nicht vorhandenen Slot aufruft. Das sollte entweder in 
deiner Entwicklungsumgebung oder eben auf der Konsole angezeigt werden.

Martin

von Oliver J. (skriptkiddy)


Lesenswert?

Martin B. schrieb:
> leider musste ich die Erfahrung machen, dass alle QT Implementierungen
> für serielle Ports nicht wirklich gut funktionieren (sei es auf Linux
> oder Windows).
Bei mir funktioniert es auf allen 5 Linux-Rechnern perfekt.

Gruß Oliver

von Oliver J. (skriptkiddy)


Lesenswert?

jax schrieb:
> Eine Frage hätte ich allerdings noch...
> Warum empfange ich auf dem PC nur Daten vom µC wenn der ISP-Programmer
> eingesteckt ist?
Fehlt eventuell die Masseverbindung?

Gruß Oliver

von jax (Gast)


Angehängte Dateien:

Lesenswert?

Ne ne, die ist da. Ich hatte das Problem schon früher mal mit dem selben 
µC und der selben Versorgungsschaltung (die aus dem AVR-Tutorial hier). 
Damals ging das LCD nur wenn der ISB-Programmer eingesteckt war. Ich 
benutze den "mySmartUSB light". Könnte das was damit zu tun haben?
Ansonsten habe ich den Eindruck dass der Pc ne Menge Schrabbel empfängt. 
Ich denke allerdings dass das von der Software verursacht wird. Weil oft 
einfach vollkomen falsche Daten ausgegeben werden. Ich lade das Projekt 
mal hoch, wäre toll wenn jemand mal drüber gucken könnte.
Zum Projekt:
Der µC sendet in einer Dauerschleife drei Werte aus gewonnenen 
Messungen(10Bit). Ein Wert wird in zwei Bytes übertragen, wobei das 
erste Byte die unteren 8Bit der Messung sind und die zwei 
niederwertigsten Bits des zweiten übertragenen Bytes, die 
höchstwertigsten der Messung(Bit 8 und 9).
Auf dem Pc soll aus je zwei Bytes die ursprüngliche 10Bit Messung als 
Zahl rekonstruiert werden(evtl noch in Volt umrechnen). Dann werden 50 
Messungen gemittelt und ausgegeben. Das ganze halt für jede der drei 
Messwerte.

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.