Serial.flush() doesn't wait for the end of the transmission

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.

Here is a code snippet:

Serial.println("Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest");
Serial.flush();
digitalWrite(SERIAL_MUX_PIN, HIGH);

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.

The length dependency may be due to the sketch stalling if the output buffer is full.

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)

No, I meant the 64 byte transmit buffer

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 :astonished: If I comment out flush lines it works just fine.

ArtSmart:
I put several Serial.print and Serial.flush in sequence. It seems to corrupting TX buffer

Post a sketch demonstrating the problem, and tell us what output you expect to get and what you actually get.

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.

Here is a code snippet:

Serial.println("Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest");

Serial.flush();
digitalWrite(SERIAL_MUX_PIN, HIGH);




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.

Lefty

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

Post a sketch demonstrating the problem

Here is just the portion that causes the problem.

                                Serial.println("Test1");
                                Serial.flush();
                                delay(5);

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.

???Ground Start complete
Teplete
Test1
Te1
Test1
Te<0>Test1
Te˜t1
Te¾Te¾Test1
Test1
Te×t1
Test1
TeÑTest1
Teþst1
TeÕ
TeÁTest1
Test1
TeÇst1
Test1
Te1
Test1
TeTest1
Te<0>1
TeTeêest1
Test1

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.

Are you saying that you have Serial.print and Serial.flush() INSIDE a serialEvent()?

Mark

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.

Enough with the snippets. Show a complete sketch that demonstrates the problem, so we can try it too.