PDA

View Full Version : QtSerialPort--blocking read of X chars with timeout



davethomaspilot
30th November 2013, 15:37
I'm using QtSerialPort in an application that receives data from the serial port.

The application receives a variable number of fixed (32 byte) length records. An "end of message" byte in the correct byte position of a record indicates a complete message has been received and the application starts processing it.

Generally, everything works well. But, occasionally, the end of message record is missed (cause under investigation). This causes the message parser to get out of sync with incoming character string and many bad things to happen.

In the real usage, the received messages will be spaced in time--minutes apart. So, I'd like to implement something that starts a time-out when the first character is received and concludes an end-of-message will never be received, if not received within a few seconds. Then take action to clean-up , loose as little of the received data as makes sense, and be ready for the next message.

So, I think a blocking read with a time-out of the serialport is what I need. I'd change the message protocol to use a fixed number of records. Ideally, the blocking read wouldn't return until the expected number of bytes were read. I understand the GUI would freeze during the time-out period, but I can live with that.

Looking at the QtSerialPort class, there are methods for reading with time-outs, but there's only a max characters to read. So, these methods can (and do) return before the entire message (or even an entire record) has been read.

I could start a timer in another thread and use that as a time-out mechanism. Then, I'd loop looking for more input and poll the timer until it expires.

Is there a better way?

Thanks,

Dave Thomas

Added after 1 28 minutes:

Reading about QTimer, I see another thread isn't necessary.

I could use a single shot timer, and restart it each time the QtSerialPort readyRead() fires. If it expires before the end of message occurs, the code will do the clean-up stuff.

I'm hoping that a second start issued to a timer configured for single shot mode before it expires will reset the timer, but I can't tell from the docs whether that's true or not. So, I'll do a simple testcase to find out.

Dave Thomas