Serial.Flush bug?

Between two programs on remote machines I use a Serial-USB connection. Only one-byte messages are being exchanged. Handshake is not much of an issue but I thought it was a good idea to use ‘Serial.Flush’ after each ‘Serial.Write’. I understood that this Flush-command sends the contents of the outputbuffer – one byte in my case – without delay. But I noticed that after using this Flush-command the inputbuffer is also cleared. Result: incoming commands, still waiting to be processed, were deleted!
The program seems to work ok without the Flush-command, so it’s not a big issue. But I think this is not expected behavior, or am I missing something?

According to the Docs:
Serial.Flush()
Clears all data from the serial port buffer.

I would think that means the input or output buffer. Why is it that you think you need to use flush? Is there another issue that you’re having that could be dealt with differently?

I use Serial.Flush in my app only once. This is when the user connects to the usb port. Without using flush, I found I was getting residual data from the previous connection.

[EDIT] Serial.Write already sends data to the buffer, so there’s nothing else required.

1 Like

@Steve K
Thank your for your reaction.

I’m not sure where you’ve read this. But according to Xojo Documentation after clicking on Serial.Flush:
Writeable.Flush
Immediately sends the contents of internal write buffers to disk or to the output stream.

The documentation doesn’t mention that both buffers will be cleared.

I added Serial.Flush because 99% of the transmitted commands is only one byte, and I was afraid that some systems might hold the data until something more came in. I thought it was not a bad idea to add Flush so every command was transmitted immediately.
But as I mentioned before, it’s not an issue anymore. All systems seem to work just fine without the Flush command. It’s just that its behavior doesn’t reflect the documentation.

Buffering data to be sent together in a single packet is pertinent to network communications, but not to serial. Serial writes should happen in real time. There’s no reason not to. I would suggest removing Flush and don’t look back.

[quote=402172:@Joop Riem]@Steve K
Thank your for your reaction.

I’m not sure where you’ve read this. But according to Xojo Documentation after clicking on Serial.Flush:
Writeable.Flush
Immediately sends the contents of internal write buffers to disk or to the output stream.

The documentation doesn’t mention that both buffers will be cleared.

I added Serial.Flush because 99% of the transmitted commands is only one byte, and I was afraid that some systems might hold the data until something more came in. I thought it was not a bad idea to add Flush so every command was transmitted immediately.
But as I mentioned before, it’s not an issue anymore. All systems seem to work just fine without the Flush command. It’s just that its behavior doesn’t reflect the documentation.[/quote]

I read the info here: https://documentation.xojo.com/index.php/Serial.Flush
Not much info I know.

Ive never seen Writeable.Flush. Are you sure you’re not confusing with writing to a file, compared to writing to the serial buffer?

In relation to writing to files, Ive used Flush to ensure that data is written to a file, ie. writePrefs.Flush, then closed the file: writePrefs.Close

But I’m no expert.

SideNote: Writeable is an interface which is applied to IPCSocket, TCPSocket, TextOutputStream, BinaryStream and Serial which contains three methods: Flush, Write(text as String) and WriteError() as Boolean and provides the ability to use these classes interchangeably for output purposes. Typically this interface is applied to classes that Write data. There is a similar Readable interface for incoming data.

UART chips have I/O Buffers. The comm software (usually drivers) can opt to implement different modes of operation. It could, for example, implement something like a synchronous API sending a byte and returning a fail code after 100ms trying to send that byte with no success, or something like put that byte in the UART FIFO (usually they can hold 16 bytes) and forget, if there’s space left for sure; or wait a bit waiting a bit for room, or fail returning the condition. Well, if the API opt for a more asynchronous approach, sometimes you need to make sure all bytes were sent to the other side, that’s why you should implement a Flush() routine to check if there is a fail situation holding bytes in buffer and return a fail condition, or just wait all them to be gone, and return the status of “buffer flushed successfully”. So, serial writes COULD need a flush if there is a scheme like this implemented, in the hardware space, using the FIFO buffer of the chip, or in user space, using an even larger buffer; in the user space, disk writings uses it all the time.

I don’t think Xojo clears the input buffer in a Writable.Flush(), it should be too much lame. But as many things Xojo does syncronously, one thread only, maybe they do things in a way that when you ask to force the output, the flush routine gets busy in output losing bytes in the input. Things should be more asynchronous and multi-thread in Xojo. So, yes, they probably have a bug in this part, but maybe you receive it as an answer like “it’s this way by design”.

@Steve K
I see what you mean. Not much info indeed. But it’s telling exactly what Serial.Flush actually does.
If you Click on the ‘Serial’ lemma from your link it will bring you back to the main ‘Serial’ info, and if you click from there on ‘Flush’ it will show Writeable.Flush: that’s the info I initially got.
In other words: the link from Serial’s main lemma to .Flush points to Writeable.Flush, and it’s info is wrong.
Message to Xojo: please alter this link. End of discussion…

@Rick Araujo
You’re right, very good info. I struggle with Serial Communication over 40 years now, and remembering my early years I know that sometimes data can be held up in the input buffer. That’s why I implemented this .Flush command, thinking it worked as a Writeable.Flush according the documentation. It took some time before I found out why sometimes commands waiting in the input buffer vanished…