QSerialport in multithread
Hi guys..
Previously i'm using external library for accessing RS232 serial port. Now i want to try to use Qserialport in Qt5.1.
however, i have some problems as i'm using multithreading program (Qthread).
Main thread
Code:
void MainWindow::on_plotButton_clicked()
{
//Initialize thread for acc
Sensors* Acc = new Sensors();
Acc->moveToThread(Thread_Acc);
connect(Thread_Acc, SIGNAL(started()), Acc, SLOT(FetchData_AW()));
connect(Acc, SIGNAL(finished()), Thread_Acc, SLOT(quit()));
connect(Acc, SIGNAL(finished()), Acc, SLOT(deleteLater()));
connect(Thread_Acc, SIGNAL(finished()), Thread_Acc, SLOT(deleteLater()));}
Worker thread
Code:
void Sensors::FetchData_AW()
{
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
qDebug() << "Name : " << info.portName();
qDebug() << "Description : " << info.description();
qDebug() << "Manufacturer: " << info.manufacturer();
if(info.portName() == "COM24")
{
cport_nr_Acc.setPort(info);
cport_nr_Acc.close();
{
cport_nr_Acc.setBaudRate(57600);
cport_nr_Acc.setDataBits(QSerialPort::Data8);
cport_nr_Acc.setParity(QSerialPort::NoParity);
cport_nr_Acc.setStopBits(QSerialPort::OneStop);
cport_nr_Acc.setFlowControl(QSerialPort::NoFlowControl);
}else
return;
break;
}
}
Fetch_ACC
= new QTimer (this);
connect(Fetch_ACC,SIGNAL(timeout()),this,SLOT(Loop_DataAW()));
Fetch_ACC->start(55);
}
the program can run but it display warning as below and the input from the device is also not as expected (value not stabilize) comparing if i use external rs232 library.
Code:
QObject: Cannot create children
for a parent that is in a different thread.
(Parent is QSerialPort(0x127bac98), parent's thread is QThread(0x10b40ed0), current thread is QThread(0x128967f0)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QSerialPort(0x127bac98), parent's thread is
QThread(0x10b40ed0
), current thread is
QThread(0x128967f0
) QObject: Cannot create children
for a parent that is in a different thread.
(Parent is QSerialPort(0x127bac98), parent's thread is QThread(0x10b40ed0), current thread is QThread(0x128967f0)
is there any interruption of the port if I'm using it from other than main thread?
i already make the Qserialport as the variable in worker-thread class instead of global variable.
what can i do to solve this issues because i really want to use readyRead signal.
Thanks in advance... =)
Re: QSerialport in multithread
Where to you create your QSerialPort instances?
Maybe accidentally as non-pointer members of Sensors or in Sensors' constructor?
Cheers,
_
Re: QSerialport in multithread
Code:
{
Q_OBJECT
public:
Sensors();
QSerialPort cport_nr_Acc;
..... }
should i used pointer instead??
Added after 1 45 minutes:
SOLVE!!
Thanks anda_skoa.. =)
I'm using pointer for the qserialport and for the value, i'm not using the proper method to assigned the value from the QBytearray.
Code below for others reference.. =)
Code:
Sensors::Sensors()
{
cport_nr_Acc = new QSerialPort (this);
}
void Sensors::FetchData_AW()
{
cport_nr_Acc->setPortName("COM24");
cport_nr_Acc->close();
if (cport_nr_Acc
->open
(QIODevice::ReadWrite)) {
cport_nr_Acc->setBaudRate(57600);
cport_nr_Acc->setDataBits(QSerialPort::Data8);
cport_nr_Acc->setParity(QSerialPort::NoParity);
cport_nr_Acc->setStopBits(QSerialPort::OneStop);
cport_nr_Acc->setFlowControl(QSerialPort::NoFlowControl);
}else
return;
Fetch_ACC
= new QTimer (this);
connect(Fetch_ACC,SIGNAL(timeout()),this,SLOT(Loop_DataAW()));
Fetch_ACC->start(25);
}
void Sensors::Loop_DataAW()
{
if(!EN_A)
{
Fetch_ACC->stop();
cport_nr_Acc->close();
emit finished();
return;
}
// expected to get 14 byte of input from device
for(int y = 0;y<14;y++)
{
cport_nr_Acc->waitForReadyRead(50);
nA = cport_nr_Acc->bytesAvailable();
if(nA>=14)
break;
Sleep(1);
}
if(nA == 14)
{
inacc = cport_nr_Acc->readAll();
inacc[nA] = 0; // put a "null" at the end of a string!
char *p = inacc.data();
// input buffer .xxyyzzxxyyzz. --> direct value
dataAx = (static_cast<unsigned char>(p[1])<<8)|static_cast<unsigned char>(p[2]);
dataAy = (static_cast<unsigned char>(p[3])<<8)|static_cast<unsigned char>(p[4]);
dataAz = (static_cast<unsigned char>(p[5])<<8)|static_cast<unsigned char>(p[6]);
dataWx = (static_cast<unsigned char>(p[7])<<8)|static_cast<unsigned char>(p[8]);
dataWy = (static_cast<unsigned char>(p[9])<<8)|static_cast<unsigned char>(p[10]);
dataWz = (static_cast<unsigned char>(p[11])<<8)|static_cast<unsigned char>(p[12]);
}else
{
qDebug() << "Polling fail " << nA;
return;
}
but why pointer should be use?? doesn't it still in the same thread if the variable is class variable??
Re: QSerialport in multithread
Quote:
Originally Posted by
snow_starzz
but why pointer should be use?? doesn't it still in the same thread if the variable is class variable??
The difference is that you now have a parent.
Basically in your original situation the QSerialPort object was created by the main thread, as part of creating the Sensors object. At this point both "belonged" to the main thread.
You then correctly moved the Sensors object to the new thread, however the QSerialPort instance was not.
Now you have QSerialPort as a child of Sensors, it is being moved alongside its parent.
Another option would have been to create it in the new thread's context, like you do with the QTimer.
Cheers,
_