[SOLVED]Possible? Multiple QSerialPort Threads Simultaneously Independently
-
Hi,
I am a newbie working on multi-sensors control, with each sensor passing data to one Serial Port independently.
The aim is to retrieve data as fast as possible, which means I want to control multi-Sensors through multi-SerialPorts simultaneously and independently, instead of merging data into one Serial Port or processing the serial communications in only one loop.Here is my Question: is that possible in Qt to do multiple serial-threads simultaneously and independently?
It keeps telling me
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
whenever I tried to open or close a QSerialPort if it happens in a new thread, and of course data are not received successfully.There must be one micro-controller between COM and sensor, while one MCU controlling multi-sensors will definitely slow down the communication speed; the best way is to realize multi-SerialPort control in Qt.
Could anyone give me some ideas about my problem?
-
Hi,
How are you creating your QSerialPort objects ?
Do you haven on sensor per physical serial port ? -
@SGaist
Hi,Here is my QObject for QSerialPort control, with openSerial, closeSerial, and algorithm to control how to read data.
When I put SenSerialControlAlgorithmObject into a thread, it keeps telling me
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
whenever it comes to the openSerial or closeSerial command, and the serial communication doesn't work.One Serial Port connects with one MCU to control one sensor.
#include <QObject> #include <QtSerialPort/QSerialPort> #include <QTime> #include <QElapsedTimer> class SenSerialControlAlgorithmObject : public QObject { Q_OBJECT public: explicit SenSerialControlAlgorithmObject(QObject *parent = 0); QSerialPort *mySerialPort; QByteArray SenMotionByteArray; bool motionReadBegun; QElapsedTimer *myElapsedTimer; signals: void emitSerialCloseSetting(); void emitSerialOpenedSetting(); void emitSerialDataToConsole(QByteArray); void emitMotionTrackingStart(); void emitMotionTrackingStop(qint64); void emitMotionUpdateSignal(QByteArray SenMotionByteArray, int); public slots: void openSerialPort(Settings mySettingInfo); void closeSerialPort(); void readData(); void handleError(QSerialPort::SerialPortError error); private: int motionReadBytes, delta_X, delta_Y; }; #endif // SENSERIALCONTROLALGORITHMOBJECT_H
-
How are you putting SenSerialControlAlgorithmObject in a QThread ?
-
@SGaist
MainWindow:#include <QMainWindow> #include <QtSerialPort/QSerialPort> #include "SenConsole.h" #include "SenSettingsDialog.h" #include "SenSerialControlAlgorithmObject.h" class SenOpticalFlowSensorsMainWindow : public QMainWindow { private slots: void writeData(const QByteArray &data); void showDataInConsole(QByteArray data); signals: void emitOpenSerialOrder(SenSettingsDialog::Settings); private: Ui::SenOpticalFlowSensorsMainWindow *myMainWindow_ui; SenConsole *mySenConsole; SenSettingsDialog *mySenSettingsDialog; SenSettingsDialog::Settings mySettingInfo; SenSerialControlAlgorithmObject *myDefaulSerialObject; QThread *mySerialThread; };
Constructor:
SenOpticalFlowSensorsMainWindow::SenOpticalFlowSensorsMainWindow(QWidget *parent) : QMainWindow(parent), myMainWindow_ui(new Ui::SenOpticalFlowSensorsMainWindow) { myMainWindow_ui->setupUi(this); mySenConsole = new SenConsole; setCentralWidget(mySenConsole); //// myDefaulSerialObject = new SenSerialControlAlgorithmObject(); //// mySenSettingsDialog = new SenSettingsDialog; initActionsConnections(); mySerialThread = new QThread(); // myDefaulSerialObject ->moveToThread(mySerialThread ); mySerialThread ->start(); }
-
Just do not use the threads if you don't know how to do it.
-
No it's not impossible, however thread programming is a complex matter where it's very very very easy to shoot yourself in the foot.
One guess: your actual QSerialPort doesn't have a parent, so when your move myDefaultSerialObject, the serial port itself is not moved.
-
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
I appreciate your guessing, however the application output reminder is telling something failed in another thread, which means the command of
if (mySerialPort->open(QIODevice::ReadWrite)) {//Here is when the hint comes out emit emitSerialOpenedSetting(); syncNumMotionsCount = 0; SenMotionByteArray.clear(); debugError = false; } else { emit emitSerialOpenErrorSetting(mySerialPort->errorString()); }
failed in another thread instead of main thread.
-
Although it is not allowed to open/close QSerialPort in a new thread,
It is not true. There are no differences in from what a thread to do open/close. A main things is that the QSerialPort should be moved into another thread before than opened/closed/read/write on it and so on. Besides, this should be called in that thread to which the QSerialPort was moved (not from the main thread or any others).
And I do not understand what is reason to use a more than one thread.. Because you can handle a data from the several serial ports (sensors) from the one main thread "simultaneous".
-
That is also what I do not understand.
What do you don't understand?
I once again will repeat: simply don't use the threads, if no reason for this! (in your case there are is no any reason)
QWinEventNotifier: Event notifiers cannot be enabled or disabled from another thread
Obviously, you do something wrong: all methods of QSerialPort shall be called from the same thread in which an QSerialPort lives.
It seems that, there is no way to push the Object, which contains QSerialPort, back to main thread and then close QSerialPort.
WTF?
-
@kuzulis
I don't understand what's wrong with my codes; it doesn't work anyway to open/close QSerialPort in a new thread.I made it in main thread, no problem without putting the Serial Communication Control in a new thread; however, is that possible to do multiple serial threads?
Two reasons to do threads:
- To make it as fast as possible;
- Learn my bug in programming: I do not want to encounter the same bug again.
-
Threads are not always the way to make a program go faster. In some cases performance can be worse with threads. Qt's asynchronous nature allows to avoid usage of thread for most of the cases and generally serial port can be handled in the GUI thread without problem.