PDA

View Full Version : UI hangs when either QThread or QTimer invoked



saman_artorious
17th April 2013, 11:25
My program continuously reads from serial port. Firstly, I used QTimer and set the interval to 300 mlscnd, this makes UI interaction very slow. I though of converting QTimer to QThread, as QTimer runs in the UI Thread, so, I added QThread class and used msleep() inside the while() loop to control the trigger.
Unfortunately, the program is still slow, I can clearly understand this when I enter digits in the UI. My last guess of where the speed reduction might have come from is emit, as you see below:



void PlcTimer::run(){
while(1)
{
qDebug() << "updateJack()";

const char str[]={UPDATE_m};
#if DEBUG
QByteArray built(str, 3);
qDebug() << built.toHex();
#endif
emit m_sendToRS((char* )str, 3);
this->msleep(500);
//sleep(300);
}
}


emit is a UI object, so whatever it is I am suspicious of its interconnection over the UI. do you have any idea how I can resolve the low speed?

wysota
17th April 2013, 11:28
First of all emitting a pointer to a local variable to a different thread is not safe. Second of all, show how you use the thread.

saman_artorious
17th April 2013, 11:39
in the MainWindow, I use a new instance of the Object, new PlcTimer() and connect the it to the serial SLOT, then I call the start() me

wysota
17th April 2013, 11:41
Show relevant code please. What is the signal connected to?

saman_artorious
17th April 2013, 11:49
inside MainWindow:


plcTimer = new PlcTimer();
connect(plcTimer, SIGNAL(jack_sendToRS(char*,int)), rs_plc, SLOT(rs_plcDataAqustn(char*,int)));
plcTimer->start();
rs_plc->rs_plcOpenPort((char *)"/dev/ttyS0"); /*/dev/ttyS3*/


QThread signal or QTimer signal connects to serial SLOT which write n reads packet to and from serial port:


bool RS::rs_plcDataAqustn(char* data, int len)
{
QByteArray rd15Bytes;

// QByteArray built((char*)data, 6) ;
// qDebug() << built.toHex();


if(!rs_serialWrite(data, len))
{
qDebug() << "Failure:( rs_dataqustn: rs_plcWrite(data, len)";
emit plc_port_dscntd();
return false;
}

if(len == 3)
{
qDebug() << "len = 3";

rs_delay();

if(rs_plcRead(&rd15Bytes))
{
qDebug() << rd15Bytes.length();
//qDebug() << "->" << rd15Bytes.toHex();

if(rd15Bytes.isEmpty())
{
emit logMessage("Failure:( rs_dataAqustn, if(rd15Bytes.isEmpty())");
}
else
{
if(!rs_plcCheckChecksum(&rd15Bytes))
emit logMessage("Failure:( rs_dataAqustn, if(!rs_plcCheckChecksum(&rd15Bytes))");
else
{
emit rs_plcSendRdPacket(rd15Bytes);

if(!rs_serialWrite((char* )"0x06", 1))
{
qDebug() << "Failure:( rs_dataqustn: rs_plcWrite(PLC_ACK, 1)";
}
}
}
}
else
{
emit plc_hmiBoard_dscntd();
}
}

return true;
}




Read from Plc:


bool RS::rs_plcRead(QByteArray *data)
{
unsigned char buff[128];
int len, tries;

tries = 0;

while(tries < 13)
{
len = read(fd, buff, PLC_READ_BYTE);

if((buff[0] == PLC_HEADER) && (len == PLC_READ_BYTE))
{
data->append((char *)buff, PLC_READ_BYTE);
//qDebug() << data->toHex();
return true;
}
else
{
tries++;
qDebug() << "retry";
}
}

return false;
}



should you need more info, please note it.

wysota
17th April 2013, 12:20
You really have to provide more code or better yet a minimal compilable example reproducing the problem, I'm not a seer. Currently I'd have to ask about each and every vaguely named variable in your code.

saman_artorious
17th April 2013, 14:40
WYSOTA!
I found out what was lowering down system speed. emit n signals are handled by UI, the main program Thread. Connecting object to serial port class as you see above is not a good idea, as these all are handled by UI Thread. Hence, reducing UI interaction speed. I changed Serial class slot to a static function and called the function directly without using emit. Now, two threads are running every 300 milscnd in the background, without using emit and without conflicting UI user interaction!

wysota
17th April 2013, 17:16
Emitting signals doesn't slow down things. If it did in your case then your code had to be incorrect.

kuzulis
17th April 2013, 18:33
saman_artorious,

Why to you not to use ready libraries for operation with the serial ports and do not bother QThread and QTimer?
Or you have any weighty reasons to use the himself serial port implementation with such perversions?