Help Please: About "Flush()"

I Maked Serial.flush() but it dose’nt work, in fact when i enter a string the program execute with all the characters.Do you have any idea.?
this is the code:
-----------------------------------------------------------------Code---------------------------------------------
int ledpin =13;
void setup()
{ //Setup pin
pinMode(ledpin,OUTPUT);
//create a serial Object
Serial.begin(9600); }
void loop()
{//Have the arduino wait to receive input
while(Serial.available() == 0);
//Read Input
int val = Serial.read()- ‘0’;
//Echo the input
if (val == 0)
{ Serial.println(“Led Mis a Zero”);
digitalWrite(ledpin,LOW);
}
else if (val == 1)
{digitalWrite(ledpin,HIGH);
Serial.println(“Led is On”);
}
else
{ Serial.println(“Invalid”); }

Serial.flush();
}

Flush is just a delay until the serial output buffer empties.

What do you expect to happen?

I've never used flush(), and I've written close to 300 sketches - you almost certainly don't need it, although one case would be preparing to power down.

Grumpy_Mike: Flush is just a delay until the serial output buffer empties.

Which isn't the same as waiting until the last bit of the last byte has has been transmitted which is what it should do.

to clear out any remaining data in the receive buffer do this:

while (Serial.available()){
int x = Serial.read();
}

to read it all out and throw it away.

How do decide how many characters to ignore?

toto10900: i sware the same code act differently with a nother user.ok i want to read just the first digit when i enter many ones in the same time ,, how should i do?

Oh, I'm sorry. I figured you could see to just replace your flush calls with the code I posted. I'll post it again with reading the one character left in there.

char theCharacterYouWant = 0;
if (Serial.available()){                                            //We only enter this block if we've received some data
     theCharacterYouWant = Serial.read();      // Pull off the first character and store it in a variable you can use later
     while(Serial.available()){                             // As long as there's still something in the Serial buffer
          int x = Serial.read();                                 // Keep reading it out into a dummy variable x that you never do anything else with
     }
}

If all you're ever going to do is act on the first character received, you may as well just do for(;;); as soon as you've acted on it- why bother reading any more?

The problem with this entire approach is: How do you know that the entire thing that you want to throw away has arrived when you enter that block. Imagine you’re getting a packet that looks like “0653716636553736” and you’re only interested in the 0 at the beginning. If you enter some block of code like the one you want when you see the first character you’ll get the 0 alright, but most likely the rest of this number is still showing up. You flush the Serail buffer and leave the block of code. Next time around the loop the rest of the number is showing up. SO again you find a character in the Serial buffer and enter the block of code. Only this time, it’s not something you’re interested in. It’s the rest of that transmission you meant to throw away. Maybe you’re getting the last end, 553736, so you enter the block and read off the first character which is now 5.

Unless the thing sending the transmission to you is also giving you signals that a transmission is starting and ending, there is no way of knowing. So either the sender can send a digital HIGH or LOW on some pin to let you know, or the transmission itself can include markers to let you know. For instance if I instead sent <0653716636553736> then I can look at the characters in the serial buffer and if I see a ‘<’ I know it’s the start of a transmission and the next character is the one I want. Then you throw your data away until you read a > and you know that it’s over.

But really, why are you bothering to send data you’re just going to throw away?

According to the reference, that's true.

http://arduino.cc/en/Serial/Flush

Serial.flush use to empty the input receive character buffer, it was then changed to just cause a variable delay until the transmit character buffer has time to be emptied.

A more fundamental question is when and how to utilize a flush operation either for transmission or receiving of characters. In most cases it is not used for a good purpose and just reflects poor program structure or understanding of the task at hand.

Please improve title of your post next time, 99% of the threads are questions :wink:
it will give more/faster feedback!

toto10900: Serial.flush() don't clear anymore the buffer from the creation of 1.0 arduino version,Is that True??

Why are you asking this again, I told you this yesterday!

The POSIX fflush function performs a different operation depending on the direction of the stream you are working with:

For  output streams, fflush() forces a write of all user-space buffered data for the given output or update stream
via the stream's underlying write function.  For input streams, fflush() discards any buffered data that has  been
fetched  from the underlying file, but has not been consumed by the application.  The open status of the stream is
unaffected.

Arduino started by emulating half that functionality with their “flush” method to the Stream class. They chose the input stream action for reasons of their own. It was, in hind sight, the wrong choice, and so they changed it. The output stream action is far far more useful as it means you can synchronise your program with the outputting of data - especially useful for such things as RS-485 where you may want to switch the transceiver from receive to transmit and back to receive again when you want to transmit some data, so knowing when the transmission is finished is critical. And so, Arduino changed their flush() method accordingly.

So what if you want to empty your receive buffer? Well, unlike the output stream action, the input stream action is really really simple to emulate with just a couple of lines of code (one line if you’re clever). All you need to do is read what is in the input buffer and just throw it away.

A simple little loop like:

while (Serial.available() > 0) {
  int dummy = Serial.read();
}

would suffice. It can be optimised though…

If there is nothing to receive (i.e., Serial.available() == 0) and you try and read, the read() function returns -1 (it actually calls Serial.available() first). So you could massively shrink the code to:

while (Serial.read() != -1) continue;

That saves a call to Serial.available(). You don’t need the “continue” in there at all really - I just like to put it there so it is obvious to the causal reader that this is the entire loop and this is all it does.

bperrybap:

Grumpy_Mike: Flush is just a delay until the serial output buffer empties.

Which isn't the same as waiting until the last bit of the last byte has has been transmitted which is what it should do.

Yes but it can't because that information is not available in the actual processor. There are few processors that set a flag to say it has.

Grumpy_Mike:

bperrybap:

Grumpy_Mike: Flush is just a delay until the serial output buffer empties.

Which isn't the same as waiting until the last bit of the last byte has has been transmitted which is what it should do.

Yes but it can't because that information is not available in the actual processor. There are few processors that set a flag to say it has.

Yes it is, and I don't know of any processors that DON'T provide that information. This is flush:

  while (transmitting && ! (*_ucsra & _BV(TXC0)));

TXC0 is:

This flag bit is set when the entire frame in the Transmit Shift Register has been shifted out and there are no new data currently present in the transmit buffer (UDRn). The TXCn Flag bit is automatically cleared when a transmit complete interrupt is executed, or it can be cleared by writing a one to its bit location. The TXCn Flag can generate a Transmit Complete interrupt (see description of the TXCIEn bit).

I.e., the flag is set when the last byte has left the chip completely and is "on the wire".

Grumpy_Mike:

bperrybap:

Grumpy_Mike: Flush is just a delay until the serial output buffer empties.

Which isn't the same as waiting until the last bit of the last byte has has been transmitted which is what it should do.

Yes but it can't because that information is not available in the actual processor. There are few processors that set a flag to say it has.

Actually, most do because just knowing when the transmit buffer is ready for another byte is pretty useless. If really needed for synchronization it is vital to know when the byte has finished transmitting on the wire particularly in the scenario like majenko mentioned of turning around transceivers.

The AVR is VERY screwy with respect to setting the status bits to know when the the data byte has actually been sent. In my opinion the AVR guys screwed this up. However, the information can be determined. There was a long discussion about this about a year ago, and a fix was put into 1.0.2 HardwareSerial to deal with it appropriately.

In reality there are needs/uses for being able to flush/drain the data in both directions. In my view, in the old days (before C++) it was much more consistent in Unix serial drivers. There were termio ioctl calls for flush (purge the input) and drain (wait for transmits to finish). It wasn't until C++ came along and created the stream i/o that the terminology and functionality started to get all wonky. They overlayed the same terminology names on their new interfaces to mean something different.

--- bill

If really needed for synchronization it is vital to know when the byte has finished transmitting on the wire

Yes I agree it is vital to know, but I have also found that processors do not set a flag when this happens they set there flag when the TX pending buffer is free. There has been many projects I managed in industry that had to jump through hoops to get round this. I think you will find you are misreading the data sheet on this one.

However, the information can be determined.

Sure it can, those are the hoops we had to jump through.

Grumpy_Mike:

If really needed for synchronization it is vital to know when the byte has finished transmitting on the wire

Yes I agree it is vital to know, but I have also found that processors do not set a flag when this happens they set there flag when the TX pending buffer is free. There has been many projects I managed in industry that had to jump through hoops to get round this. I think you will find you are misreading the data sheet on this one.

However, the information can be determined.

Sure it can, those are the hoops we had to jump through.

Mike, I've been dealing with serial interfaces for 40 years and most UARTs that I've dealt with have both types of status. The AVR also has both. I was part of the lengthy discussion about flush() a while back and I used a logic analyzer to verify the solutions. The hoops I referred to on the AVR is because the status for knowing when the transmit is really complete is intertwined with the unrelated interrupt status and transmit buffer empty status. i.e. you can't just poll the TX complete status in a polled only environment.. That is the screwup I was referring to. And I have seen some situations where the h/w doesn't provide the needed status. In my experience that has been quite rare. For those situations you can work around it by doing a s/w delay that is equivalent to a single character time.

When needed this functionality, the most important thing is that there must be a way to ensure that all the data has been sent out the wire.

--- bill