Hi everyone , i'm newbie to QT. Just struggled with QT about 2 months but i got basic informations about my project. I tried to explain my issue in the best way. Sorry for writing errors.
Here is the deal. I'm trying to get sensor values from T.I instruments' Hercules Board which have TMS570LS1227 microcontroller. Main purpose is getting the desired packages from sensor which is connected to board and log it to text file. I managed sending or receiving , logging tasks. But i read so much about QSerialPort losing data and etc. topics. I couldn't figure it out.
For testing the data i'm getting from board i'm only sending 5 byte short number. 1st byte is TypeCheck ( float,decimal and bla bla) for parsing the received package. 2nd and 3rd byte is the short value ( have a union struct no error about it) and the other 2 bytes is CRC(Cyclic Redundancy Check) value of the package.
This was just an information about what i'm trying to do.
I'm sending an counter variable to QT. Sending frequency have to be 10kHz. Means that 10000*5(bytes)*8(bit) = 400000 bit baudrate i should have. I searched forums about QT and it's saying that baudrate 600000 is available in QT. So i set my serial port according to that.
The struggle is that : When i'm getting data from board, first package is not coming like just "5 bytes to read". Incoming bytes in internal serial read buffer showing sometimes 10, sometimes 35, sometimes 500, it depends on how fast i'm doing the job on QT. I managed it with using a Circular Buffer to keep data without losing any of it. E.g: With debugging i saw that; when first package came to QT i'm getting let's say 50 bytes. I'm checking the values of the buffer and it's true.( in this case 50/5=10; last sended number i have to receive is 10). But then second package is coming and i'm checking the received buffer and first 5 byte didn't equal to "11". It can be "45". Then it follows "45,46,47.." .
This means i'm losing data. Why i'm struggling with that ? Is QT doesn't support higher baudrate in QSerialPort ?
I wanted to give the codes as well. You guys can check anything about it. Feel free to critisize my coding as well i wanted my skills to developed .
ReadyRead Signal is connected to the slot like that.
serial = new QSerialPort(this);
connect(serial,SIGNAL(readyRead()),this,SLOT(toReadThePort()),Qt::QueuedConnection);
serial = new QSerialPort(this);
connect(serial,SIGNAL(readyRead()),this,SLOT(toReadThePort()),Qt::QueuedConnection);
To copy to clipboard, switch view to plain text mode
Initializing Serial Port code:
void MyObject::InitSerialPort()
{
/*Circular Buffer Initializing*/
CircularBufferManager_ApiInit(&SerialCircularBufferManager_s,
&SerialBuffer[0],
1,
3000);
//Configure Port Settings;
static bool PortIsOpen;
serial->setPortName("COM7");
serial->setBaudRate(600000); // 460800
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setReadBufferSize(400);
if(!serial->isOpen())
{
PortIsOpen
= serial
->open
(QIODevice::ReadWrite);
// Open the Port; if(PortIsOpen == 1)
qDebug()<<"Port Has Opened !";
}
serial->clear(QSerialPort::AllDirections);
LogData(GonnaBeWrittenFile,StrBuffer); // Just for writing Header part of the log text.
}
void MyObject::InitSerialPort()
{
/*Circular Buffer Initializing*/
CircularBufferManager_ApiInit(&SerialCircularBufferManager_s,
&SerialBuffer[0],
1,
3000);
//Configure Port Settings;
static bool PortIsOpen;
serial->setPortName("COM7");
serial->setBaudRate(600000); // 460800
serial->setDataBits(QSerialPort::Data8);
serial->setParity(QSerialPort::NoParity);
serial->setStopBits(QSerialPort::OneStop);
serial->setFlowControl(QSerialPort::NoFlowControl);
serial->setReadBufferSize(400);
if(!serial->isOpen())
{
PortIsOpen = serial->open(QIODevice::ReadWrite); // Open the Port;
if(PortIsOpen == 1)
qDebug()<<"Port Has Opened !";
}
serial->clear(QSerialPort::AllDirections);
LogData(GonnaBeWrittenFile,StrBuffer); // Just for writing Header part of the log text.
}
To copy to clipboard, switch view to plain text mode
Here is the ReadyRead Signal's connected slot code:
void MyObject::toReadThePort()
{
static uint8 testData[400];
static int counter=0;
NumberOfBytesToRead = serial->bytesAvailable();
if(NumberOfBytesToRead > 0 && serial->isReadable())
{
ArrayBuffer.clear();
ArrayBuffer = serial->readAll();
remain = (NumberOfBytesToRead % ExpectedPacketLength);
memcpy(testData,ArrayBuffer,(NumberOfBytesToRead-remain));
for(counter=0; counter < (NumberOfBytesToRead-remain); counter++)
{
CircularBufferManager_ApiPush(&SerialCircularBufferManager_s,(void*)&testData[counter]);
}
procCounter += (NumberOfBytesToRead-remain);
serial->clear(QSerialPort::AllDirections); // Clear Serial Write and Read Internal Buffers
receiveData();
}
}
void MyObject::toReadThePort()
{
static uint8 testData[400];
static int counter=0;
NumberOfBytesToRead = serial->bytesAvailable();
if(NumberOfBytesToRead > 0 && serial->isReadable())
{
ArrayBuffer.clear();
ArrayBuffer = serial->readAll();
remain = (NumberOfBytesToRead % ExpectedPacketLength);
memcpy(testData,ArrayBuffer,(NumberOfBytesToRead-remain));
for(counter=0; counter < (NumberOfBytesToRead-remain); counter++)
{
CircularBufferManager_ApiPush(&SerialCircularBufferManager_s,(void*)&testData[counter]);
}
procCounter += (NumberOfBytesToRead-remain);
serial->clear(QSerialPort::AllDirections); // Clear Serial Write and Read Internal Buffers
receiveData();
}
}
To copy to clipboard, switch view to plain text mode
For last concern receivedata() function is that just the concerned part :
while(pulledData !='s')
{
CircularBufferManager_ApiPull(&SerialCircularBufferManager_s,&pulledData);
qCnt++;
}
for(qCnt=0; qCnt<(NumberOfBytesToRead-remain); qCnt += ExpectedPacketLength)
// for(qCnt; qCnt<procCounter; qCnt+= ExpectedPacketLength)
{
dummy=0;
if(!(((NumberOfBytesToRead-remain)-qCnt) < ExpectedPacketLength))
{
for(dummyCounter=0;dummyCounter<ExpectedPacketLength;dummyCounter++)
{
dummyArray[dummyCounter] = pulledData;
shortArray[dummyCounter] = pulledData;
CircularBufferManager_ApiPull(&SerialCircularBufferManager_s,&pulledData);
}
}
while(pulledData !='s')
{
CircularBufferManager_ApiPull(&SerialCircularBufferManager_s,&pulledData);
qCnt++;
}
for(qCnt=0; qCnt<(NumberOfBytesToRead-remain); qCnt += ExpectedPacketLength)
// for(qCnt; qCnt<procCounter; qCnt+= ExpectedPacketLength)
{
dummy=0;
if(!(((NumberOfBytesToRead-remain)-qCnt) < ExpectedPacketLength))
{
for(dummyCounter=0;dummyCounter<ExpectedPacketLength;dummyCounter++)
{
dummyArray[dummyCounter] = pulledData;
shortArray[dummyCounter] = pulledData;
CircularBufferManager_ApiPull(&SerialCircularBufferManager_s,&pulledData);
}
}
To copy to clipboard, switch view to plain text mode
Note: remain variable is required for circular buffer to don't getting the wrong package data.
Note: ExpectedPacketLength is define variable which can vary but in this code its "5".
Bookmarks