Go Down

Topic: Serial port flush fuction. (Read 9350 times) previous topic - next topic

vipersnh

Please make serial port flush function to do both,
1. Wait for output buffer to get emptied.
2. Clear all input buffer characters collected serially.


Using arduino latest ide, i lost many hours figuring why flush was not clearing all serial data.

robtillaart


Point 1) is this not done allready?
Point 2)

void FlushInput()
{
  while (Serial.Available() > 0) Serial.Read();
}

A far faster version would reset the pointers in the ringbuffer in the Serial Class.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

vipersnh

Thanks for reply.
Thats der. What i meant to say is why not include it as a standard.
The previous version had flushing of recieved data, and the new version of arduino has flush function which waits for all data to be transmitted.
So i combined the codes from both in the single flush function.

PaulS

Quote
Using arduino latest ide, i lost many hours figuring why flush was not clearing all serial data.

Why are you dumping random amounts of unprocessed data, anyway? It seems far better to process all the data, in my opinion. Or make the sender quit sending if you don't want to deal with it anymore.
The art of getting good answers lies in asking good questions.

SurferTim

The flush function only clears the receive buffer. To be correct, it sets the head pointer equal to the tail pointer.
This is from HardwareSerial.cpp
Code: [Select]
void HardwareSerial::flush()
{
 // don't reverse this or there may be problems if the RX interrupt
 // occurs after reading the value of rx_buffer_head but before writing
 // the value to rx_buffer_tail; the previous value of rx_buffer_head
 // may be written to rx_buffer_tail, making it appear as if the buffer
 // don't reverse this or there may be problems if the RX interrupt
 // occurs after reading the value of rx_buffer_head but before writing
 // the value to rx_buffer_tail; the previous value of rx_buffer_head
 // may be written to rx_buffer_tail, making it appear as if the buffer
 // were full, not empty.
 _rx_buffer->head = _rx_buffer->tail;
}


vipersnh


Quote
Using arduino latest ide, i lost many hours figuring why flush was not clearing all serial data.

Why are you dumping random amounts of unprocessed data, anyway? It seems far better to process all the data, in my opinion. Or make the sender quit sending if you don't want to deal with it anymore.


actually in my application, i'm using gsm module data to analyse. Its predetermined what it sends in reply, so i'm flushing the data. May be i must consider disabling the serial interrupt for that.

SurferTim

It may be the sender has more data than will fit in the receive buffer. In that case, the serial port should use the RTS/CTS to stop the sender. When you clear the serial buffer with flush(), the transmissions may be resuming from the sender.

As a test, do the flush, wait a bit, then check the receive buffer again.

Code: [Select]
Serial.flush();
delay(100);
if(Serial.available() > 0)
{
   // do something here to signal more data was coming from the sender after the flush
}


vipersnh

Thank you guys for all fast replies.. Btw i have posted it as a suggestion for arduino rather than a problem related to arduino.
I have found the solution for my problem, i'm using flush to reset the recieve buffer pointers as well as wait for all data to be transmitted.

PaulS

Quote
Its predetermined what it sends in reply, so i'm flushing the data.

It must be great to write perfect code that ALWAYS works with hardware that always works. There is a reason that the device produces a response. A responsible programmer would verify that the expected response was received.

I think you are solving the wrong problem, and I do not want to see more use of the Serial.flush() function proposed.
The art of getting good answers lies in asking good questions.

vipersnh


Quote
Its predetermined what it sends in reply, so i'm flushing the data.

It must be great to write perfect code that ALWAYS works with hardware that always works. There is a reason that the device produces a response. A responsible programmer would verify that the expected response was received.

I think you are solving the wrong problem, and I do not want to see more use of the Serial.flush() function proposed.


ya. Ur right. Its better to check the response for its correctness. But the thing is, it echo's the sent command in gsm kit. So i was flushing the data. And wait for the reply values to come.

jfhaugh


Quote
Its predetermined what it sends in reply, so i'm flushing the data.

It must be great to write perfect code that ALWAYS works with hardware that always works. There is a reason that the device produces a response. A responsible programmer would verify that the expected response was received.

I think you are solving the wrong problem, and I do not want to see more use of the Serial.flush() function proposed.


There are plenty of reasons to flush an input stream.  For example, discovering that an input packet is corrupted and waiting for the bad packet to go away.  Or doing initial validation on a packet and discovering it isn't addressed to you.

PaulS

Quote
For example, discovering that an input packet is corrupted and waiting for the bad packet to go away.  Or doing initial validation on a packet and discovering it isn't addressed to you.

I have to disagree. Both examples assume, incorrectly in my opinion, that all the as-yet-unread data belongs to the same packet, and imply that flushing the buffer will automatically advance to the next packet.

If you are certain that that is the case, go ahead and flush the data. I'm not that confident that no other packet is in the buffer, so I just read to the end of the packet, and discard any data that I don't want to store.
The art of getting good answers lies in asking good questions.

graynomad

#12
Oct 15, 2011, 05:57 am Last Edit: Oct 15, 2011, 06:04 am by Graynomad Reason: 1
I'm going to put two bob (~20c) each way here.

In general and for the sort of code written by most people using Arduinos I would say that flush is not necessary.

For the example of bad frames I can see that two things will happen if you flush the Rx buffer (all dependent on the data rate and the speed with which you service the UART).

a) You will clear the bad frame and also some parts of the following good frame.
b) You will clear some bytes of the bad frame but not all and then have to figure it out anyway.

So like I say, for the sort of protocol most people will implement here I can't see flush as being useful. Better off just reading and discarding bytes until the next SOF sequence.

I designed a protocol however where flushing was acceptable I think..

This protocol resynched with the data stream by waiting for an idle line for a period of 16 bit times. Therefore having decided that the frame was not addressed to me (or was bad) it was quite reasonable to ditch any further characters in the Rx buffer and enter the resync state. This resync state uses a hardware timer and therefore required almost no processor overhead so it was good to be able to do other stuff.

It mostly boils down to "how do you resync?" If a packet is corrupted there's no robust way to detect the end of the bad one or the beginning of the next one by looking at characters. IMO some form of low-level timing or some such is required, but there may be an option I hadn't thought about.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

AWOL

About the only use I've ever had for a flush function is where I want to do something starting from the next time the user presses a key.

robtillaart


Sometimes I need an unconditional flush like AWOL states, but mostly I used a parameterized flush, see below.

Usefull for skipping a known(!) number of bytes when parsing an input stream.

Code: [Select]
void FlushCount(uint8_t n)
{
  while (n > 0)
  {
    if (Serial.Available() > 0)
    {
      Serial.Read();
      n--;
    }
  }
}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up