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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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: serial_reader_async_test.zip