Serial data received
-
then, I work on an IMU sensor.
the received data are in hexadecimal form.
the size of the received data is 37 bytes.
I checked this to validate each data
Serial received "555541321e7ff3029f61da00000000ffff00d2fffa0cbe24b124b124b1007b13d00000f4d8"
headdd "5555"
Serial received ""
"data size is: " 37 bytes
"Header is Ok"
"the type of packet is ok"
"data size is Ok"however I also receive data of 0 bytes, which are empty and this quite frequently, and I would like to receive only the data with 37 bytes, that is to say to regulate that my sensor receives only the good bytes
Serial received "" "data size is
"data size is: " 0 bytes
"Header is not Ok , Ignore the packet
"the type of packet is not ok , Ignore the packet"
"Data size is not ok , Ignore the packet"@J-Hilk yes I tested with an accumulation of data and without
@jsulm no I don't want to convert anything, just get the full data at each data receptionBasically if my bytes are less than 0 then I don't receive valid data
but I would like to make sure that I don't receive themI would like to receive each time the data in full form
-
@manel-sam said in Serial data received:
however I also receive data of 0 bytes, which are empty and this quite frequently
- If you only call
readAll()
once in response to eachreadRead()
signal you will never get 0 bytes. - If you get 0 bytes you are calling
readAll()
a second time/not in response toreadyRead()
. Find out where, and don't do it.
I would like to receive each time the data in full form
You cannot guarantee you will receive all bytes on any one particular
readAll()
call. Like @J-Hilk said you need to write code to accumulate the (potentially fragments) of data you receive. - If you only call
-
Imu::~Imu()
{
serialPort->close();
}void Imu::handleError(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError){
qDebug()<<"Handle Error"<<error;
serialPort->close();
}
}void Imu::pollSerialPort()
{QByteArray d= serialPort->readAll().toHex(); QByteArray hexData = d.append(serialPort->readAll().toHex()); qDebug() << "Serial received " << hexData;
i used it like this
-
@manel-sam
This is wrong because you have two calls toserialPort->readAll()
. How many more times can I say you cannot afford to do this? [In fact you kind of get away with this the way you write, but why are you calling it twice??] -
@manel-sam can you show more of your code, calling connect multiple times will lead to such a behaviour as well
-
Imu::Imu() :
moving(false)
{serialPort = new QSerialPort("COM3",this); if (serialPort->open( QIODevice::ReadWrite)) { qDebug()<<"SerialPort"<<serialPort<<"Opened successufly"; } else { qDebug()<<serialPort->error(); QSerialPortInfo::availablePorts(); } if (!serialPort->setBaudRate(57600)) log_error("imu","failed to set baudrate, error no %d",serialPort->error()); serialPort->setDataBits(QSerialPort::Data8); serialPort->setParity(QSerialPort::NoParity); serialPort->setStopBits(QSerialPort::OneStop); // One Stop bit serialPort->setFlowControl(QSerialPort::NoFlowControl); qDebug()<<"error"<<serialPort->errorString(); QObject::connect(this->serialPort,SIGNAL(readyRead()),this,SLOT(pollSerialPort())); QObject::connect(serialPort, &::QSerialPort::errorOccurred,this,&Imu::handleError); }
Imu::~Imu()
{
serialPort->close();
}void Imu::handleError(QSerialPort::SerialPortError error)
{
if (error == QSerialPort::ResourceError){
qDebug()<<"Handle Error"<<error;
serialPort->close();
}
}void Imu::pollSerialPort()
{QByteArray hexData; hexData.append(serialPort->readAll().toHex()); qDebug() << "Serial received " << hexData; QByteArray data = QByteArray::fromHex(hexData); // data size qInfo() << QStringLiteral("data size is : ") << data.size() << " octets"; QDataStream stream(data); // Read The BigIndian value stream.setByteOrder(QDataStream::BigEndian); qint16 headerSignature; stream >> headerSignature;
-
@manel-sam said in Serial data received:
QByteArray hexData;
hexData.append(serialPort->readAll().toHex());hexData is local, so you append nothing !
hexData.append(serialPort->readAll().toHex());
qDebug() << "Serial received " << hexData;
QByteArray data = QByteArray::fromHex(hexData);you convert to ascii then back to binary !!??
You must check the packet is complete (37 bytes) before processing any further.
-
@manel-sam said in Serial data received:
I used the readAll once, but I still get the 0 Bytes
And where in your code do you now get this?
Separately you need to follow @mpergand's comments.
In
handleError()
you only report anything ifQSerialPort::ResourceError
, and silently ignore if any other error, for whatever reason. Please don't write code like this, and certainly not while developing/debugging. -
@manel-sam said in Serial data received:
So the append I should do it where§?
Create a member variable in your imu class.
// _packetData member variable of imu _packetData.append(serialPort->readAll()); if(_packetData.size()>=PACKET_LENGTH) { // packet complete qInfo() << QStringLiteral("data size is : ") << _packetData.size() << " octets"; qDebug() << "Serial received " << _packetData.toHex(); // go ahead with this packet QDataStream stream(_packetData); // Read The BigIndian value stream.setByteOrder(QDataStream::BigEndian); qint16 headerSignature; stream >> headerSignature; }
You may also check the data received don't exceed PACKET_LENGTH, cause it means you have already received data from the next packet. (it may be irrelevant in your case, I don't kown)