Unsolved QtSerialPort receiving data issue
-
Hello,
I have a small program in Qt that sends a request to an arduino board for analog voltage. From Qt I click on a button to send the request to the arduino. The board receives the request properly, but when it returns the ADC result and I try to read the string in Qt it's all over the place. Some times it reads it correctly, some times it doesn't. I know the Arduino is working property as I have tested this with putty and it always returns the correct result when I send it the command. I've tried to limit the bytes Qt receives, but have not been successful. Any help will be appreciated.
void MainWindow::on_powerON_clicked() { int res24 QByteArray chkTstr24VDC ("$AR!ARP022#"); QByteArray powerON ("$DW!SHP079#"); sndTesterData(powerON); //Enable 24VDC sndTesterData(chkTstr24VDC); //Request 24VDC status to Tester serial->waitForReadyRead(1000); res24 = readADC(24); }
int MainWindow::readADC(int range) { QByteArray data; bool ok = false; float r = 0.0; int inBytesExpected = 5; if (range == 24) { if (inBytesExpected <= serial->bytesAvailable()) { data = serial->readAll(); qDebug() << data; r = data.toFloat(&ok); if (!ok) qDebug() << "24VDC Conversion Failed"; } qDebug() << r; if ((r > 23.2) && (r < 24.8)) //Check tolerance (3.3%) return 1; }
Qt output is below
"$DW!SHPOHL#" "$AR!ARP\x16HL#" "24.0024" 24.0024 "$DW!SHPOHL#" "$AR!ARP\x16HL#" ".0024." 24VDC Conversion Failed 0 "$DW!SHPOHL#" "$AR!ARP\x16HL#" "0024." 24
-
Serial can be slow. Likely you are trying to read data too fast and it hasn't all been received yet.
For example, this part:
"$DW!SHPOHL#" "$AR!ARP\x16HL#" ".0024." 24VDC Conversion Failed 0
The last part of the recieved data is '24.' which is the first part of what you were expecting. The initial data '.00' could be from something that hadn't been read in the previous attempt to read the data.
When reading serial you need to allow the data to accumulate so you have a complete block. There is no guarantee that the entire expected response will be available for reading when 'serial->waitForReadyRead(1000)' returns (all this means is that some data has been read). In your case you read part of when is sent and the part that isn't read becomes the first part of the next data read attempt.
For example, when you send "$AR!ARP\x16HL#" it appears that the hash '#' represents the end of the command block. When you read the data you need to read until you have found a terminator of some sort (maybe CR/LF, '#' or possibly a fixed number of bytes in response to your query). Don't do anything with the read data until you know you have read it all.