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:
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.
Code : Sélectionner tout - Visualiser dans une fenêtre à part connect(m_serialPort, SIGNAL(readyRead()), SLOT(readData()));
mainwindow.cpp
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
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(); } } }
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!)
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(); } }
Voilà le projet complet: serial_reader_async_test.zip
Partager