Setup QSerialPort in a different thread with a timer
-
Hello everyone,
I've been working to set my QSerial port in a separated thread so that my main program to keep it isolated from the GUI processing delay.
Here is the link to the stackoverflow post i made with my code :
https://stackoverflow.com/questions/53341179/setup-qthread-with-qtimer-and-qserial
I tried to put exec() in my ValidationCommunication::run(), put it did not behaved as i expected.. I saw in Qt doc that it is supposed to start event loop, but once started it never go back to my run().
Is this the right way to handle a QSerialPort ?
I've been learning Qt by my own so maybe there is some concepts that I misunderstood.
Thanks !
-
I saw your code in StackOverflow. Did you consider QSerialPort class for this purpose. Which function to be executed in thread ? You are calling start function same thread object again and again. Why are you calling it so many times ?
-
@dheerendra Thanks for your answer.
Yes I've considered QSerialPort but when I tried my GUI was very slow so I thought it could be good to use a different thread. And actually, I don't really know how this is usually done so i tried this way.
The function to execute in the thread are reception/transmission of data on ComPort. I'm calling the start function multiple times because it is the only way I've managed to make it run forever in a non-blocking way. -
Just start experimenting now with SerialPort communication in thread. Sub class Thread and reimplement the run method. Try to open the serial Port functions through run() methods. Let me know how it goes.
-
@Clarck_D said in Setup QSerialPort in a different thread with a timer:
es I've considered QSerialPort but when I tried my GUI was very slow so I thought it could be good to use a different thread.
QtSerialPort is asynchronous, so if your GUI got slow you did something wrong, like using the
waitForReadyXxx
methods. It is possible to do the communication in a thread, but I don't think it's needed. Threading has it's own implications, so I'm not sure you're taking the easier way now.Regards
-
-
bool Validation_Board::sendValid(FrameFormat frame) { QByteArray txFrame; bool ackReceptionStatus, eventReceptionStatus, resultsStatus, cmdStatus; /* Clear before sending command */ _comPort->clear(); /* Get command name */ _curCmdName = dataCheck.getCmdName(frame.chipId, frame.msgId); /* Add command name to text printed in console */ _testText->append("Command name : \n" + _curCmdName.toUpper() + "\n" ); /* List number of events for this command */ _listEvents.clear(); listCmdEvents(); _nbEvent = _listEvents.size(); /* Set Timeout value */ _timeout = frame.timeout; /* Check if there is commands to send */ if (frame.commandToSend) { /* Sending command */ txFrame = convertFrameToArray(frame); sendCommand(txFrame); /* Receive command Ack */ // ackReceptionStatus = receiveAck(txFrame); } /* Clear before sending next command */ _comPort->clear(); } void Validation_Board::openSerialPort(QString comPort, int portSpeed) { _comPort = new ComPort(comPort, portSpeed); _comPort->openSerialPort(); connect(_comPort, SIGNAL(dataReceived(QByteArray)), this, SLOT(receptionValid(QByteArray))); connect(this, SIGNAL(writeValid(QByteArray)), _comPort, SLOT(write(QByteArray))); } void Validation_Board::closeSerialPort() { _comPort->closeSerialPort(); } void ComPort::closeSerialPort() { qDebug() << "CLOSE :" << _portName; if (_serialPort && _serialPort->isOpen()) { _serialPort->clear(); _serialPort->close(); } _isOpen = false; } void ComPort::openSerialPort() { _serialPort = new QSerialPort(this); connect(_serialPort, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(_serialPort, &QSerialPort::bytesWritten, this, &ComPort::handleBytesWritten); connect(_serialPort, &QSerialPort::errorOccurred, this, &ComPort::handleError); _serialPort->setPortName(_portName); _serialPort->setBaudRate(_baudRate); _serialPort->setDataBits(QSerialPort::Data8); _serialPort->setParity(QSerialPort::NoParity); _serialPort->setStopBits(QSerialPort::OneStop); _serialPort->setFlowControl(QSerialPort::NoFlowControl); if (_serialPort->open(QIODevice::ReadWrite)) { qDebug() << "Connected :" << _portName; _isOpen = true; } else { qWarning() << "Error while opening" << _portName <<":" << _serialPort->errorString(); closeSerialPort(); } } void ComPort::handleBytesWritten(qint64 bytes) { qDebug() << "Bytes_written"; m_bytesWritten += bytes; if (m_bytesWritten == m_writeData.size()) { m_bytesWritten = 0; qDebug() << "Data successfully sent to port" << _serialPort->portName(); // qDebug() << m_standardOutput; // QCoreApplication::quit(); } } void ComPort::handleError(QSerialPort::SerialPortError serialPortError) { qDebug() << "Error : " << serialPortError; if (serialPortError == QSerialPort::WriteError) { qDebug() << "An I/O error occurred while writing the data to port" << _serialPort->portName() << "error: " << _serialPort->errorString(); // qDebug() << m_standardOutput; // QCoreApplication::exit(1); } } void ComPort::write(QByteArray data) { if (_serialPort) { qCritical() << "TEST"; qint64 res = _serialPort->write(data.data(), data.length()); _serialPort->flush(); if (res <= 0) qDebug() << _serialPort->errorString(); } }