1 pièce(s) jointe(s)
[QSerialPort] Lecture asynchrone de données
Salut,
Je suis parti de l'exemple Command Line Reader Async Example pour lire de façon asynchrone des données port série (un Arduino dans mon cas).
L'exemple fonctionne mais j'ai tenté d'encapsuler les fonctions de lecture dans une classe et ça coince.
J'ai créé une classe SerialPortReader qui se contente de lire de manière asynchrone les messages qui lui arrivent et de les afficher via qDebug (dans un premier temps).
Mon problème est que le signal readyRead() n'est jamais émis:
Code:
connect(m_serialPort, SIGNAL(readyRead()), SLOT(readData()));
Je ne comprends pas pourquoi le signal est émis quand je le connecte depuis la classe MainWindow et pourquoi il n'est pas émis depuis la classe SerialPortReader.
mainwindow.cpp
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| #include "mainwindow.h"
#include "ui_mainwindow.h"
#include "arduino/serialportreader.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
serialPort (new QSerialPort)
{
ui->setupUi(this);
serialPort->setPortName("ttyUSB0");
serialPort->setBaudRate(115200);
if (!serialPort->open(QIODevice::ReadOnly)) {
qDebug() << "MainWindow: Failed to open port " << serialPort->portName() << "error: " << serialPort->errorString();
while (1) {};
}
// Option 1: directly connect serialPort readyRead() to MainWindow::readData()
// Works fine
connect(serialPort, SIGNAL(readyRead()), SLOT(readData()));
// Option 2: use a SerialPortReader that internally connects readyRead to SerialPortReader::readData()
// readyRead() is never triggered (and thus readData() never executed)
//SerialPortReader reader (serialPort); // FIXME: Retrieve messages from the serial port
}
MainWindow::~MainWindow()
{
delete ui;
serialPort->close();
}
void
MainWindow::readData()
{
if (serialPort->canReadLine())
m_readData.append(serialPort->readAll());
else
{
if (!m_readData.isEmpty())
{
ui->label->setText(m_readData);
qDebug () << m_readData;
m_readData.clear();
}
}
} |
serialportreader.cpp
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| #include "serialportreader.h"
#include <QDebug>
QT_USE_NAMESPACE
SerialPortReader::SerialPortReader(QSerialPort *serialPort, QObject *parent):
QObject(parent),
m_serialPort(serialPort)
{
connect(m_serialPort, SIGNAL(readyRead()), SLOT(readData()));
connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError)));
}
SerialPortReader::~SerialPortReader()
{
}
void SerialPortReader::readData()
{
qDebug () << "readData";
if (m_serialPort->canReadLine())
m_readData.append(m_serialPort->readAll());
else
{
if (!m_readData.isEmpty())
{
qDebug () << m_readData;
m_readData.clear();
}
}
}
void SerialPortReader::handleError(QSerialPort::SerialPortError serialPortError)
{
if (serialPortError == QSerialPort::ReadError)
{
qDebug () << "An I/O error occurred while reading the data from port" << m_serialPort->portName() << ", error:" << m_serialPort->errorString();
}
} |
Pourquoi le signal readyRead() n'est jamais émis dans la classe SerialPortReader ? (note: j'ai testé qu'il y avait bien des données à lire sur le port série!)
Voilà le projet complet: Pièce jointe 184235