I have a custom signal-slot in Qt C++ in which I want to store data received from a serial port (QSerialPort) to show data from 25 different sensors I have on an embedded system. Values for my sensors range from 5900 to 7200, so I wanted to send a different letter as a char (ranging from a to y, 25 letters) between each sensor value, so my Qt program can tell which sensor data is received next, followed with a stop byte which would be universal for my 25 sensors.
void MainWindow::serialReceived() // runs individually for almost every byte
{
QByteArray ba = serial->readAll();
qDebug() << ba.size();
}
for now, I am using the readAll() function, and most of the time this slot function (serialReceived() ) is called often enough so that only 1 char is received at a time, so I can check for the letter identifying the sensor, then at the next function call I can check the leftmost number of the sensor data, etc until I reach the 4th number and then the stop byte, before the process is repeated.
The problem is sometimes it receives more than a byte at once, so if there are more than one values in my ba, I do not know what would be a good way to check for the individual bytes received (ex: did I receive a letter, followed by the 2 first numbers of the next sensor value??).
This is what I managed to do so far, but it doesnt work since I get a problem as soon as I read more than 1 byte at once in my slot function:
void MainWindow::serialReceived() // runs individually for almost every byte
{
static char stepFlag = 0;
QByteArray ba = serial->readAll();
qDebug() << ba.size(); //receives 1 byte and
QString s;
s = QString::number(stepFlag), qDebug() <<"step: "<< s;
qDebug() <<"ba: " << ba;
if (ba == "<") stepFlag = 1, s = QString::number(stepFlag), qDebug() << s;
s = QString::number(currentSensorValue), qDebug() << s;
switch (stepFlag) {
case 0:
qDebug() << "starts";
if (ba == "<")
stepFlag = 1;
break;
case 1:
ID = ba.toInt();
qDebug() << ID;
stepFlag = 2;
break;
case 2:
stepFlag++;
currentSensorValue = ba.toInt()*1000; // first char is the 1st number of data (representing thousands)
break;
case 3:
stepFlag++;
currentSensorValue += ba.toInt()*100;
break;
case 4:
stepFlag++;
currentSensorValue += ba.toInt()*10;
break;
case 5:
stepFlag++;
currentSensorValue += ba.toInt();
break;
case 6:
//qDebug() << "a" << currentSensorValue;
if (ba.toInt() == 'r')
{
switch (ID)
{
case 'a':
ui->RX0TX0_LCD->display(currentSensorValue);
qDebug() << "a" << currentSensorValue;
break;
case 'b':
qDebug() << "b" << currentSensorValue;
break;
//This switch would go on for all of the 25 letters (sensors)
default:
break;
}
ID = 0;
}
if (ba.toInt() == 'n')
{
stepFlag = 0;
}
break;
default:
break;
}
}
So basically my problem is how can I read 1 byte at a time from the QserialPort so this problem does not occur anymore? I am also unsure of if my method for receiving chars is very efficient. Thank you!
You can iterate each single byte through a QByteArray as:
QByteArray::iterator iteratorByte;
int count = 0;
for (iteratorByte = ba.begin(); iteratorByte != ba.end() ; iteratorByte++ ) {
QByteArray test1Byte(1,0); //Define a 1 Byte fixed length variable
test1Byte[0]= ba.at(count++); //Assign each byte of the QByteArray ba to this variable
qDebug() << test1Byte.toHex(); //Print that 1 Byte in hex format
}