problem with writing on serial port
-
@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? -
@jsulm said in problem with writing on serial port:
I asked already why threads. Seems to be an exercise.
possibly, but the OP only states the while loop as a task. Not threads specifically.
@nanor can you word exactly, what you want to do ?
-
@jsulm said in problem with writing on serial port:
I asked already why threads. Seems to be an exercise.
possibly, but the OP only states the while loop as a task. Not threads specifically.
@nanor can you word exactly, what you want to do ?
@J-Hilk Hi
I have a button that when a user pushes it, "salam" is printed. At the same time, I want to constantly read from and write to a port (I want to read byte by byte and print them(debug them)). Now I know that I have to declare a class inheritted from qThread class and inside its run function, read and write. But I don't know if I have to declare while loop inside the run function in order to read constantly or not. In the code I posted, I have:QByteArray data = serial->read(1); for(int i=0; i<data.size(); i++) { qDebug() << data[i]; }Is this part reading the datas byte by byte and store them inside an array and print the datas?