QSerialPort's read buffer is always empty while running another func.
-
How did you declare
proc
? -
@Gokhan
Sadly, Signal finished is overloaded in this class. To connect to this one using the function pointer syntax, you must specify the signal type in a static cast:connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), [=](int exitCode, QProcess::ExitStatus exitStatus){ /* ... */ });
-
@J-Hilk It should be connected below to compile successfully, so it's static cast. I did it and it can compile and connect now without an issue. However, I haven't solved this problem yet, it isn't still giving the finished event. Can it be a bug with qprocess ? Should I write a bug report?
QObject::connect(proc, (void (QProcess::*)(int,QProcess::ExitStatus))&QProcess::finished, this, &image_down_dialog::finished); -
You should rather use qOverload. In the case you can't, use a static_cast like @J-Hilk shown, not a C-Style cast.
As for never finishing, maybe because cmd.exe is still running. You are passing the
/k
parameter to cmd.exe which AFAIK meansrun the command and return to the CMD prompt
. Shouldn't you be using/C
? -
@SGaist thank you. The problem was solved when changed "/k" with "/c". However, the problem which I have mentioned in the title hasn't been solved yet. I'm still missing some data during communication with MCU through the serial port. The missing data are around 3K while sending 300K.
Also, I able to read max 512 byte in the readyRead signal, Is it writing to its read buffer during making another process like filling a table? If yes, how can I read the all buffer without missing any data?
-
Do you have any protocol established for the communication ?
-
@SGaist I have just solved this problem. it was caused by debugging mode. After it was realesed and run .exe, it normally ran, until the application window is moved. Yes, I have a new problem :). It's lagging and missing data during moving or resizing the application window. I just tried to up to real time priority for windows on task manager, but it's still missing.
-
@J-Hilk I have already connected to a function and read it in this function. I don't make anything other this, it only reads the serial port and converts the data. Until moving the window, I tried it for around an hour, it never misses data. Actually, not only moving, it also has this problem during two-clicking the window's border.
-
@Gokhan
never the less you should seperate your QSerialPort interaction from your GUI-Stuff. If a rather empty GUI-Resize causes you to lose data, imagine what will happen if your programm eventually becomes more complex.From your description its is critical that no informations are lost. So make a workerclass for your SerialPort interaction and run it in its own thread. Eventually raise that thread priority too.
And you should be fine. Its easy enough to do with qt.
-
@J-Hilk OK. I have to use a Qthread and read buffer with it. So, how should I read the buffer? Which registers do I check before reading? How do I able to read periodically? For example, I'm using the following codes, but it can't connect the serial port.
The process function is the same with the link.QThread* thread = new QThread; serialPort.moveToThread(thread); connect(&serialPort, SIGNAL (error(QString)), this, SLOT (errorString(QString))); connect(thread, SIGNAL (started()), &serialPort, SLOT (process())); connect(&serialPort, SIGNAL (finished()), thread, SLOT (quit())); connect(&serialPort, SIGNAL (finished()), &serialPort, SLOT (deleteLater())); connect(thread, SIGNAL (finished()), thread, SLOT (deleteLater())); thread->start();
void serial_port::process() { for(;;) { if(serial->isOpen()) { msleep(100); if (serial->waitForReadyRead(100)) { // read request newdata.append(serial->readAll()); while (serial->waitForReadyRead(10)) newdata.append(serial->readAll()); } } } }
-
ok,
same basic info.
The constructor, of your serial port class, should be empty. Everything necessery should be initialized after the thread is started. That includes creating the instance of the QSerialPort as well as all connections://serialPort class void serialPort::init(){ serial = new QSerialPort(); connect(serial, &QSerialPort::readyRead, this, serialPort::newData); } void serialPort::newData{ QByteArray bArray = serial->readAll(); //do Stuff .... emit finishedData(data); }
QSerialPort should emit the readyRead Signal when ever it has new data to be processed. Just connect to signal to a slot and handle the data there. -> The Thread will be more or less idle - only running its event loop- but still react as soon as new data is available.
the thread handling in your MainClass seems good enough:
QThread* thread = new QThread; serialPort *mySerialPort = new serialPort(); mySerialPort -> moveToThread(thread); connect(mySerialPort , SIGNAL (error(QString)), this, SLOT (errorString(QString))); connect(mySerialPort , SIGNAL (finishedData(QVariant)), this, SLOT (displayData(QVariant))); connect(thread, SIGNAL (started()), mySerialPort , SLOT (init())); connect(mySerialPort , SIGNAL (finished()), thread, SLOT (quit())); connect(mySerialPort , SIGNAL (finished()), &serialPort, SLOT (deleteLater())); connect(thread, SIGNAL (finished()), thread, SLOT (deleteLater())); thread->start();