An annoying problem about QSerialPort usage
-
When I use serialPort->readData(), I got a error from Compiler, it told me this function is protected.Thus, I use serialPort->read(), it would still happened same thing I mentioned before.Is this really a bug??Or I forget something??I have double-checked my code, I didn't find anything would change my memory.......
-
Hi guys. I'm here. :)
Ivan,
- What OS is used?
- What serial chip/model is used?
- Please give the minimum console example which reproduces this problem.
- Still I don't recommend to use waitForXX() methods. Use non-blocking approach instead of the blocking.
- Mr. Koahning mean use just read() method instead of readAll(). Try and let know about results.
-
Ivan,
- Check that you allocate memory for DataReceive with safe size:
char* DataReceive = new char(maxsize);
- Check for building object serialPort befor using it.
good luck
-
Hello, Thanks for reply
1)My OS is Windows 7
- It's a USB Serial Port
3)Following is my code that error always happened here
@
serialPort->clear();
ReceiveData.clear();
serialPort->write(requestData);
serialPort->flush();
if( requestCmd == MemoryAccess)
{
for( i =0; i< 70; i++)
{
while(serialPort->waitForReadyRead(30))
{
DataReceive = serialPort->read(50)
ReceiveData.append(DataReceive);
}
if(ReceiveData.length() !=0)
break;
}
}
@4)Because I found document on Qt website, It showed this method that I could use.Does non-blocking mean like following code
@
connect(serialPort,readyRead(),&myobject,receiveData())
@5)Yes, I tried. But I got same result that sometime fault would be occured.
-
Hi, mehrdadsilver
"DataReceive" is QByteArray, I didn't use pointer, so It absolutely is initialized and had enough place."serialPort" is initialized in the constructor of my class, so I believed It was used after I initialized it.The strangest thing is sometimes my application run correctly and got correct result, but sometime I would get error message like "segmentation fault". -
Please provide an minimal separate console project (with an simple read/write operations) which reproduces this problem. Instead of a piece of a code from your current project. Because you can have a error somewhere in a your code of your project.
-
I don't know what "minimal separate console project" means..., I could e-mail the project to you.
-
I require the minimal console project (without GUI) with source files, which I can recompile and run on the my side.
Project should contain an pro file, and *.h, *cpp files with a class with your I/O.
Should be used a methods: serialPort->clear(), serialPort->write(), serialPort->flush(), serialPort->waitForReadyRead(), serialPort->read(). That's all.
If you by means of this "console project" successfully to reproduce SEGFAILT, then a problem in QtSerialPort. If it isn't possible to reproduce - that a problem somewhere at your code of your main project.
-
I thought if i step by step to read or write data through QtSerialPort, that would no error happen. I proved it before. My project is for company, because we want to flash memory of product through comport, it would frequently in a short time to write or read data massively.And sometime it is successful, sometime it's failed.If you don't have related product, even though I gave you the sample code, you still can't have same situation like mine.
-
Please provide an minimal project with I/O. That's it.
-
[quote author="kuzulis" date="1378888607"]Hi guys. I'm here. :)
Ivan,
- What OS is used?
- What serial chip/model is used?
- Please give the minimum console example which reproduces this problem.
- Still I don't recommend to use waitForXX() methods. Use non-blocking approach instead of the blocking.
- Mr. Koahning mean use just read() method instead of readAll(). Try and let know about results. [/quote]
Thanks a lot for picking up the discussion.
Using SerialPort in the title line seems to work very quick ;-)
Sorry, that I could not remember your name. -
Ivan, Can you e-mail for me your project?
-
Sure, but i need your e-mail address.
-
Hi, I simplify my code like following, please check:
pro file
@
QT += core serialportQT -= gui
TARGET = QSerialPortDebug
CONFIG += console
CONFIG -= app_bundleTEMPLATE = app
SOURCES += main.cpp
worker.cppHEADERS +=
worker.h@
worker.h
@
#ifndef WORKER_H
#define WORKER_H#include <QObject>
#include <QFile>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>class worker : public QObject
{
Q_OBJECT
public:
explicit worker(QObject *parent = 0);
QFile file;
QSerialPort *serialPort;
QList<QSerialPortInfo> SerialInfo;
QByteArray readData;
QByteArray ReceiveData;
QString sendData;
void InitialComport();signals:
public slots:
};
#endif // WORKER_H
@worker.cpp
@
#include "worker.h"worker::worker(QObject *parent) :
QObject(parent)
{
serialPort = new QSerialPort();
InitialComport();
file.setFileName("Image.hex");
}
void worker::InitialComport()
{
SerialInfo = QSerialPortInfo::availablePorts();
serialPort->setPort(SerialInfo[0]);
serialPort->open(QSerialPort::ReadWrite);
serialPort->setBaudRate(QSerialPort::Baud38400);
serialPort->setDataBits(QSerialPort::Data8);
serialPort->setStopBits(QSerialPort::OneStop);
serialPort->setParity(QSerialPort::NoParity);
}@
main.cpp
@
#include <QCoreApplication>
#include <QThread>
#include <worker.h>
#include <QTextStream>
#include <QDebug>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
worker WORKER;
WORKER.file.open(QIODevice::ReadWrite);
QTextStream Image(&WORKER.file);
while (Image.atEnd()) {
WORKER.sendData = Image.readLine();
WORKER.serialPort->write(WORKER.sendData.toLocal8Bit());
for(int i = 0; i <30; i++)
{
while(WORKER.serialPort->waitForReadyRead(35))
{
WORKER.ReceiveData = WORKER.serialPort->read(50);
}
if(WORKER.ReceiveData.length() != 0)
break;
}
qDebug() << QString(WORKER.ReceiveData);
WORKER.ReceiveData.clear();
}
WORKER.serialPort->close();
return a.exec();
}@
-
I'm sorry, but your example is incorrect.
I used the yourself a loopback example with use "Com0Com":http://sourceforge.net/projects/com0com/
Emulation of baud rate in Com0Com has to be enabled.
I used two Flasher and Eeprom applications to your I/O emulation.
Flasher:
(main.cpp)
[code]
#include <QCoreApplication>
#include <QFile>
#include <QElapsedTimer>
#include <QDebug>
#include <qserialport.h>int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);QSerialPort serialPort; serialPort.setPortName("COM4"); bool ret = serialPort.open(QSerialPort::ReadWrite) && serialPort.setBaudRate(QSerialPort::Baud38400) && serialPort.setDataBits(QSerialPort::Data8) && serialPort.setStopBits(QSerialPort::OneStop) && serialPort.setParity(QSerialPort::NoParity); qDebug() << "serial port: " << ret; QFile sourceHexImage("path/to/source/image/src.hex"); ret = sourceHexImage.open(QIODevice::ReadOnly); qDebug() << "source image ret: " << ret; QFile destinationHexImage("path/to/destination/image/dst.hex"); ret = destinationHexImage.open(QIODevice::WriteOnly | QIODevice::Truncate); qDebug() << "destination image ret: " << ret; QElapsedTimer timer; timer.start(); const int ioChunkSize = 25; // bytes const int waitTimeout = 35; // msec while (!sourceHexImage.atEnd()) { QByteArray chunk = sourceHexImage.read(ioChunkSize); serialPort.write(chunk); ret = serialPort.flush(); while (serialPort.waitForReadyRead(waitTimeout)) { if (serialPort.bytesAvailable() == ioChunkSize) break; } chunk = serialPort.read(ioChunkSize); destinationHexImage.write(chunk); } serialPort.close(); sourceHexImage.close(); destinationHexImage.close(); qDebug() << timer.elapsed() << "msec, done..."; return a.exec();
}
[/code]Eeprom emulator - Echo application
(main.cpp)
[code]
#include <QCoreApplication>#include "echo.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Echo echo;
echo.init();
return a.exec();
}
[/code](echo.h)
[code]
#ifndef ECHO_H
#define ECHO_H#include <QDebug>
#include <qserialport.h>class Echo : public QObject
{
Q_OBJECT
public:
explicit Echo(QObject *parent = 0 ) : QObject(parent) {
connect(&serialPort, SIGNAL(readyRead()), this, SLOT(onEcho()));
}bool init() { serialPort.setPortName("COM5"); bool ret = serialPort.open(QSerialPort::ReadWrite) && serialPort.setBaudRate(QSerialPort::Baud38400) && serialPort.setDataBits(QSerialPort::Data8) && serialPort.setStopBits(QSerialPort::OneStop) && serialPort.setParity(QSerialPort::NoParity); return ret; }
private slots:
void onEcho() {
const QByteArray data = serialPort.readAll();
qDebug() << data;
serialPort.write(data);
}private:
QSerialPort serialPort;
};#endif // ECHO_H
[/code]I have no SEGFAULT.
-
Thanks for your test.But actually when I receive packet from Comport, I need to collect complete packet that my program then could parse correctly, so I can't give the constant number that used on serialport->read().My original program for serialPort is run on another thread I created, because I want to show information on GUI. Does it make my program fail......, why sometimes my program could work, sometimes would crashed....., they run on same code.....
-
bq. But actually when I receive packet from Comport, I need to collect complete packet that my program then could parse correctly, so I can’t give the constant number that used on serialport->read().
I'm too collect data up to 25 bytes. (ioChunkSize = 25).. And in principle, it makes no difference...
bq. My original program for serialPort is run on another thread I created, because I want to show information on GUI.
To avoid of potential errors - just use an non-blocking approach, it will be simple and more safely.
-
"non-blocking method" is you mentioned on "Eeprom emulator – Echo application" ??
bq. I’m too collect data up to 25 bytes. (ioChunkSize = 25).. And in principle, it makes no difference…
I mean I don't know how many bytes I should receive until I don't receive any data from serialPort.
-
bq. “non-blocking method” is you mentioned on “Eeprom emulator – Echo application” ??
Yes.
bq. I mean I don’t know how many bytes I should receive until I don’t receive any data from serialPort.
I know that you mean. In an example which I gave, 25 bytes it is simple an example. My example is used for trying to detect of crash in case of the intensive I/O.
-
I still think there is a problem inside, could you try using QtserialPort with a Qthread??