PDA

View Full Version : How to make QT automatically connect to correct COM Port



GunkutA
8th April 2020, 10:00
I am trying to make QT automatically connect to my ST32 MCU by serial. MCU is keep sending data for each second. So I thought I can read all the available COM Ports and when the line is not null, I will detect that COM Port is MCU. But All COM Ports are null. Here is related piece of code I am using in QT:


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtSerialPort>
#include <QDebug>
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial = new QSerialPort(this);
foreach(QSerialPortInfo port, QSerialPortInfo::availablePorts())
{
serial->setPortName(port.portName());
serial->setBaudRate(QSerialPort::Baud115200);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->open(QIODevice::ReadOnly);

if(!(serial->readLine().isNull()))
{
qDebug()<<port.portName()<<"is opened";
}

}
}

I believe 1 second is not enough for QT to detect that. Maybe I should use timeout in QT. Any idea how can I solve this problem?

Lesiok
8th April 2020, 12:39
First of all, one should check if open() was successful. If not, check the current error code. Secondly, you should do clearError() before open(). You operate all the time on the same object.

ChrisW67
9th April 2020, 05:55
QSerialDevice is almost certainly going to require a running Qt event loop, which is not available inside your foreach() loop. Even if it was, the likelihood of data being in the buffer for readLine() to return inside this tight loop is not that high.

You need to defer all this reading activity until the main event loop is running. You can then implement a timeout in parallel with attempting a readLine(). You should also consider the number of bytes returned by readLine(), which may be zero or an indicator of an error.

Lesiok
9th April 2020, 07:06
Or use QSerialPort::waitForReadyRead. Something like this :
foreach(QSerialPortInfo port, QSerialPortInfo::availablePorts())
{
serial->setPortName(port.portName());
serial->setBaudRate(QSerialPort::Baud115200);
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->open(QIODevice::ReadOnly);

if(serial->waitForReadyRead(1500))
{
qDebug()<<port.portName()<<"is opened";
}

}