qextserialport: detecting or signalling when all bytes have been sent
-
Folks,
Have used qextserialport a lot over the years, but have a slightly funky hardware setup where Tx is connected to Rx on the embedded device with which I am communicating, so I need to ignore bytes coming in until all bytes have been sent out in my Qt app. The Qt app is the master, sends a message to the slave and at this point I need to reset the receive mechanism, flush the buffer and get ready for receiving data.
As far as I can see there is no way to switch off receive so have been looking how to detect whether all bytes have been sent. (And actually, switching off receive wouldn't really help as I need to know when all bytes have gone out, so I can start analysing valid incoming data.)
One possibility seemed to be this:
connect(vcp, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
ie using the bytesWritten signal to let me know when all data had gone out of the serial port (TBH I'm not totally convinced that's what that signal indicates, but thought it was worth a try.
Anyway, the slot onBytesWritten never gets called.
I am using an event driven port:
vcp = new QextSerialPort(portName, QextSerialPort::EventDriven);
Anyone able to help me here please? Main questions are:
- Why might the bytesWritten signal not be getting called?
- Is this indeed the correct way to detect whether all data has been sent out of the port?
FWIW Am using Qt 5.6.3, for...reasons! And currently on Linux although it will be cross platform.
Thanks.
-
Hi @DiBosco
I have used
QextSerialPort
in early Qt 4 times, but I switched toQSerialPort
once it became a Qt module in Qt 5. (you can even use it with Qt4, btw.)So I would recommend you to port your app to this. The API is not the same, but really similar.
Regarding the
bytesWritten
signal: even if you receive it, there is no guarantee that the bytes are actually on the line, because there may be buffers in the driver section or even in the hardware.But as you receive every byte you send, you can use some small state machine:
- When you start sending, set the flag
isTx
- Buffer all outgoing bytes, e.g. in a queue
- In your
bytesReceived
slot, check theisTx
flag and compare the incoming bytes to your outgoing bytes queue - Remove the bytes that are equal from both the queue and from the incoming bytes
- Once all sent bytes are received back, clear the
isTx
flag and handle the incoming bytes as response
The tricky part may be, that incoming bytes are in chucks and there may even be one chunk that contains bytes to sent and already the first received bytes. But I think you get the idea.
Regads
- When you start sending, set the flag
-
hi @aha_1980
Thanks for the reply. Before I got it, I'd just started doing a thing where I was counting the bytes read back in and only starting to take any notice of the data when I had read in the number of bytes sent out, so I was along the right lines. It's a bit of a pain, but with what you're saying about bytesReceived being called not being a guarantee it's gone out on the line, I guess it's not going to help anyway.
For a while I have been thinking I need to get to grips with QSerialPort but as I know qextserialport so well I've been lazy. I do know that in v6 qext... is no longer available.
Thanks for the post.