problem with writing on serial port
-
@nanor You could keep your loop and call https://doc.qt.io/qt-5/qcoreapplication.html#processEvents inside the loop. But warning: this is dirty work-around and probably not what the teacher wants to see :-)
-
@nanor You could keep your loop and call https://doc.qt.io/qt-5/qcoreapplication.html#processEvents inside the loop. But warning: this is dirty work-around and probably not what the teacher wants to see :-)
@jsulm Thank you. You mentioned that if I want to do write my code in a while loop, I have to use thread. I have read about qthread class, but I don't know how to use this class in my project. Could you please give suggestions about the steps I have to take?
The question is:
read data continuously and byte by byte from a serial port and if data equals to something special that is defined in code (like"hi"), then write to serial port something.
I would appreciate if you guide me how to use threads in solving this question -
@jsulm Thank you. You mentioned that if I want to do write my code in a while loop, I have to use thread. I have read about qthread class, but I don't know how to use this class in my project. Could you please give suggestions about the steps I have to take?
The question is:
read data continuously and byte by byte from a serial port and if data equals to something special that is defined in code (like"hi"), then write to serial port something.
I would appreciate if you guide me how to use threads in solving this question@nanor This example does exactly what you need: https://doc.qt.io/qt-5/qtserialport-blockingmaster-example.html
It uses blocking QSerialPort API in a worker thread.
Take a look. -
@nanor This example does exactly what you need: https://doc.qt.io/qt-5/qtserialport-blockingmaster-example.html
It uses blocking QSerialPort API in a worker thread.
Take a look.@jsulm Thank you so much.
For the firt step (I want to continuesly read data byte by byte) I have written the following code. But it crashes. Could you please guide me how to fix this?mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QtSerialPort/QSerialPort> #include "mythread.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); QSerialPort *serial; QThread *myThread; private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hmythread.h:
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QThread> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); void run(); QSerialPort *serial; signals: public slots: }; #endif // MYTHREAD_Hmainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); myThread->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { qDebug() << "salam"; }mythread.cpp:
#include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { serial = new QSerialPort(this); serial->setPortName("COM1"); for(const auto &serialPortInfo : QSerialPortInfo::availablePorts()) { qDebug() << "find serial port: " << serialPortInfo.portName() ; } serial->open(QIODevice::ReadWrite); if(serial->isOpen()) { serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); while(1) { serial->read(1); } } else { qDebug() << "can't open the port"; } }the error:
10:33:50: Starting C:\Users\nanor\OneDrive\Desktop\qt codes\build-serialportreading3-Desktop_Qt_5_12_2_MinGW_32_bit-Debug\debug\serialportreading3.exe...
ASSERT: "timeout >= 0" in file thread\qmutex.cpp, line 582
10:33:52: The program has unexpectedly finished.
10:33:52: The process was ended forcefully.
10:33:52: C:/Users/nanor/OneDrive/Desktop/qt codes/build-serialportreading3-Desktop_Qt_5_12_2_MinGW_32_bit-Debug/debug/serialportreading3.exe crashed. -
@jsulm Thank you so much.
For the firt step (I want to continuesly read data byte by byte) I have written the following code. But it crashes. Could you please guide me how to fix this?mainwindow.h:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QtSerialPort/QSerialPort> #include "mythread.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); QSerialPort *serial; QThread *myThread; private slots: void on_pushButton_clicked(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_Hmythread.h:
#ifndef MYTHREAD_H #define MYTHREAD_H #include <QObject> #include <QThread> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> class MyThread : public QThread { Q_OBJECT public: explicit MyThread(QObject *parent = nullptr); void run(); QSerialPort *serial; signals: public slots: }; #endif // MYTHREAD_Hmainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); myThread->start(); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { qDebug() << "salam"; }mythread.cpp:
#include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { serial = new QSerialPort(this); serial->setPortName("COM1"); for(const auto &serialPortInfo : QSerialPortInfo::availablePorts()) { qDebug() << "find serial port: " << serialPortInfo.portName() ; } serial->open(QIODevice::ReadWrite); if(serial->isOpen()) { serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); while(1) { serial->read(1); } } else { qDebug() << "can't open the port"; } }the error:
10:33:50: Starting C:\Users\nanor\OneDrive\Desktop\qt codes\build-serialportreading3-Desktop_Qt_5_12_2_MinGW_32_bit-Debug\debug\serialportreading3.exe...
ASSERT: "timeout >= 0" in file thread\qmutex.cpp, line 582
10:33:52: The program has unexpectedly finished.
10:33:52: The process was ended forcefully.
10:33:52: C:/Users/nanor/OneDrive/Desktop/qt codes/build-serialportreading3-Desktop_Qt_5_12_2_MinGW_32_bit-Debug/debug/serialportreading3.exe crashed.@nanor said in problem with writing on serial port:
serial = new QSerialPort(this);
Remove "this".
If it is still crashing then please use the debugger to see where exactly and post the stack trace after crash. -
@nanor said in problem with writing on serial port:
serial = new QSerialPort(this);
Remove "this".
If it is still crashing then please use the debugger to see where exactly and post the stack trace after crash. -
@nanor Please post the stack trace (as text). It's in the middle of your screen-shot, in "Debugger" section.
-
@nanor Please post what is in level 2 and 3, else I'm out of this thread as I do not want to guess what is wrong...
It is your job to find out where your app is crashing. -
@nanor Please post what is in level 2 and 3, else I'm out of this thread as I do not want to guess what is wrong...
It is your job to find out where your app is crashing.@jsulm Sorry again. I have another question. inside the while loop, I have to constantly read data from the port and store them inside an array adn then debug them . I have written the following line. but nothing is printed
while(1) { QByteArray data = serial->read(1); for(int i=0; i<data.size(); i++) { qDebug() << data[i]; } } -
@jsulm Sorry again. I have another question. inside the while loop, I have to constantly read data from the port and store them inside an array adn then debug them . I have written the following line. but nothing is printed
while(1) { QByteArray data = serial->read(1); for(int i=0; i<data.size(); i++) { qDebug() << data[i]; } } -
@nanor
Absolutely not! Since it'swhile(1)how is it ever going to exit the loop??while (1)is "always" wrong in Qt....You have now changed your code...
but nothing is printed
So either it never enters the loop, or it never has anything to read.
@JonB I removed the while loop and mythread.cpp is now:
#include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { serial = new QSerialPort(); serial->setPortName("COM1"); for(const auto &serialPortInfo : QSerialPortInfo::availablePorts()) { qDebug() << "find serial port: " << serialPortInfo.portName() ; } serial->open(QIODevice::ReadWrite); if(serial->isOpen()) { serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); QByteArray data = serial->read(1); for(int i=0; i<data.size(); i++) { qDebug() << data[i]; } } else { qDebug() << "can't open the port"; } }But still I can't get the messages. I send data from hercules.
-
@JonB I removed the while loop and mythread.cpp is now:
#include "mythread.h" MyThread::MyThread(QObject *parent) : QThread(parent) { } void MyThread::run() { serial = new QSerialPort(); serial->setPortName("COM1"); for(const auto &serialPortInfo : QSerialPortInfo::availablePorts()) { qDebug() << "find serial port: " << serialPortInfo.portName() ; } serial->open(QIODevice::ReadWrite); if(serial->isOpen()) { serial->setBaudRate(QSerialPort::Baud9600); serial->setDataBits(QSerialPort::Data8); serial->setParity(QSerialPort::NoParity); serial->setStopBits(QSerialPort::OneStop); serial->setFlowControl(QSerialPort::NoFlowControl); QByteArray data = serial->read(1); for(int i=0; i<data.size(); i++) { qDebug() << data[i]; } } else { qDebug() << "can't open the port"; } }But still I can't get the messages. I send data from hercules.
@nanor
Start by putting inqDebug()statements to see for yourself where you are actually getting to, plus more error checking.I don't know if any serial data is available to read at the instant you open the port. And you only try to read one byte once.
-
@nanor
Start by putting inqDebug()statements to see for yourself where you are actually getting to, plus more error checking.I don't know if any serial data is available to read at the instant you open the port. And you only try to read one byte once.
@JonB Thank you for mentioning using debug. I added the line qDebug() << "inside the run function"; inside the run function, but after running, this message isn't shown. But I have started the thread inside the mainwindow class. I can't understand why this is happened!
-
@JonB Thank you for mentioning using debug. I added the line qDebug() << "inside the run function"; inside the run function, but after running, this message isn't shown. But I have started the thread inside the mainwindow class. I can't understand why this is happened!
-
@JonB Thank you for mentioning using debug. I added the line qDebug() << "inside the run function"; inside the run function, but after running, this message isn't shown. But I have started the thread inside the mainwindow class. I can't understand why this is happened!
@nanor I gave you a link to an example which uses the synchronous API. Apparently you did not really read it carefully, did you? In your loop you should use waitForReadyRead(...) as is done in the example. This makes sure that the event loop can actually do its job.
if (serial.waitForReadyRead(currentWaitTimeout)) { QByteArray responseData = serial.readAll(); -
@nanor
My own view, often times expressed, is why are you going anywhere nearQThreadat all? Every time it causes posters problems. Qt framework is asynchronous, so why do you need any threads when you have signals?