According to the Arduino reference Serial.flush() functionality has been changed starting with Arduino 1.0 It is supposed to halt program execution until TX buffer is empty. It doesn't seem to work properly though. I print a word to serial port and then change a state of an I/O pin to verify with an oscilloscope. It does appear to wait some time but not till the end of the transmission.
I see on one channel of the oscilloscope TX starts and proceeds normally but then the I/O pin goes high approximately 2-3ms before TX ends. The time is also dependent on the length of the message. If I add whole bunch of "e's" in there the time between pin changing state and the end of the transmission becomes greater. Such behavior makes Serial.flush() completely useless.
Look into the code, I'm just recalling my memory of an earlier post. The byte that gets sent to the UART hardware doesn't get counted so once it's sent to UART, the wait is over, although the transmission continues for another byte. I'm not sure about the length dependent delay though.
If that's the case I should have I/O pin change state one character before the end of the transmission (if I'm not mistaken Atmega328 has one character TX buffer?) I get multiple charters. As I said 2-3 milliseconds (not microseconds)
I'm trying to make it work but it doesn't want to cooperate. I put several Serial.print and Serial.flush in sequence. It seems to corrupting TX buffer If I comment out flush lines it works just fine.
ArtSmart:
According to the Arduino reference Serial.flush() functionality has been changed starting with Arduino 1.0 It is supposed to halt program execution until TX buffer is empty. It doesn't seem to work properly though. I print a word to serial port and then change a state of an I/O pin to verify with an oscilloscope. It does appear to wait some time but not till the end of the transmission.
I see on one channel of the oscilloscope TX starts and proceeds normally but then the I/O pin goes high approximately 2-3ms before TX ends. The time is also dependent on the length of the message. If I add whole bunch of "e's" in there the time between pin changing state and the end of the transmission becomes greater. Such behavior makes Serial.flush() completely useless.
That is because the flush is only emptying the SRAM software transmit character buffer, it doesn't know about the one serial hardware holding register and the active serial output shift register, so there is still up to one+ one character(s) waiting to be sent out even when the flush command has completed. How much longer time that can be is dependent on the baud rate being used.
Serial.flush is pretty useless. All it does is wait for the output buffer to be emptied. After it you need to add extra lines for the hardware to actually send the last byte or two (on the Uno):
while (!(UCSR0A & (1 << UDRE0))) // Wait for empty transmit buffer
UCSR0A |= 1 << TXC0; // mark transmission not complete
while (!(UCSR0A & (1 << TXC0))); // Wait for the transmission to complete
It is running inside a serialEvent() function. So every time I send a symbol to the unit it sends the output. The first line of the output is the output of the initialization of the program and not related. However you can see the the second line is supposed to be "Test1" and it outputs "Teplete" . Sometimes it outputs two lines at a time (carriage return in the middle of the string) and sometimes one line.
How much longer time that can be is dependent on the baud rate being used.
As I already said - my discrepancy is not one or two characters but more like 10-20 for long strings printed. I'm working with baud rate of 57600bps.
Serial.flush is pretty useless
I suppose it is until you need that functionality. I guess I could write code in AVR studio but why would I need then to mess with Arduino at all? If there is a documented function in Arduino I'm assuming that somebody actually tested its functionality even though it seems fairly useless.
holmes4:
Are you saying that you have Serial.print and Serial.flush() INSIDE a serialEvent()?
That's legitimate, isn't it? SerialEvent() is another of those methods that seems utterly pointless to me, but at the end of the day it's just a function called from main() and there aren't any special restrictions on what you can do inside it.