Serial data received
-
@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)