How to clear out or flush the arduino serial buffer

For the discussion of Arduino related topics.

Moderator: phalanx

Post Reply
jedihonor1
Posts: 32
Joined: Sun May 27, 2012 11:54 am

How to clear out or flush the arduino serial buffer

Post by jedihonor1 » Sat Jun 09, 2012 7:29 am

Hi,
Scott here from Salem. My program goal. Press 1 on the key board and an led lights up on the arduino. Press 2 and it goes off. Press anything else and the command port prints out "invalid". I then want to clear the serial port to erase anything else, because if I press a bunch of numbers e.g. 3456, it prints out invalid several times. I would like it to print out invalid only once. I read that Serial.flush() no longer works. I have tried byte = discard Serial.read() but this does not work. Can someone help me with how to flush the serial port of the remaining data?

Here is the code;

Code: Select all

  int val = 0;
int led = 13;
void setup()
{
  Serial.begin(9600);
  pinMode(led,OUTPUT);
}

void loop()

{
  while(Serial.available()== 0);  //stays on this line until something's in the buffer
  val = Serial.read() - 48;  // gives me the correct ascii output character
  
  Serial.println(val);
  
  if(val == 1)
  {
    digitalWrite(led,HIGH);
    
  }
    else if (val == 2)
    {
      digitalWrite(led,LOW);
    } 
      else
      {
        Serial.println("invalid");
        
        for (int i = 0; i < 18; i++)  // This is where I want to flush any remaing data
        byte discard = Serial.read();
      }
      
}    

thank you,
Scott

Philba
Support Volunteer
Posts: 2503
Joined: Sun Feb 13, 2005 11:33 pm
Location: Seattle

Re: How to clear out or flush the arduino serial buffer

Post by Philba » Sat Jun 09, 2012 8:39 am

This seems like the wrong approach to solving your problem. You know when you see the second invalid input, why print out the unwanted message in the first place?

jedihonor1
Posts: 32
Joined: Sun May 27, 2012 11:54 am

Re: How to clear out or flush the arduino serial buffer

Post by jedihonor1 » Sat Jun 09, 2012 9:03 am

Hi Philba,
Thanks for responding. I was trying to follow Jeremy Blum's tutorial on utube and he used serial.flush to erase the buffer. Perhaps I may need this on some future project. Since serial.flush is not longer used to erase the buffer. Is there another way to erase what's in the buffer?
Thanks,
Scott

Philba
Support Volunteer
Posts: 2503
Joined: Sun Feb 13, 2005 11:33 pm
Location: Seattle

Re: How to clear out or flush the arduino serial buffer

Post by Philba » Sun Jun 10, 2012 7:07 am

For input, you could just read (and ignore) it until it's empty. For output, maybe .begin() flushes.

westfw
Posts: 79
Joined: Wed Mar 09, 2005 3:13 am
Location: California
Contact:

Re: How to clear out or flush the arduino serial buffer

Post by westfw » Sun Jun 10, 2012 1:36 pm

Code: Select all

void serial_flush_buffer()
{
  while (Serial.read() >= 0)
   ; // do nothing
}
Note that this doesn't flush "characters in transit." If you send "3456" at 9600bps, the 5 will arrive avour 1ms after the 4, and won't get flushed if you call the function immediately after receiving the 4. (however, this is the way the old flush function worked as well.)

dwyer2bp
Posts: 3
Joined: Fri Dec 03, 2010 8:55 am

Re: How to clear out or flush the arduino serial buffer

Post by dwyer2bp » Wed Aug 21, 2013 6:22 pm

westfw wrote:

Code: Select all

void serial_flush_buffer()
{
  while (Serial.read() >= 0)
   ; // do nothing
}
Note that this doesn't flush "characters in transit." If you send "3456" at 9600bps, the 5 will arrive avour 1ms after the 4, and won't get flushed if you call the function immediately after receiving the 4. (however, this is the way the old flush function worked as well.)
What if your serial input is coming faster than you can read? Point being, you are going to waste precious processing time 'flushing' the serial buffer by performing a read for each piece of data in the buffer (when all you want to do is reset your buffer index to 0 so serial.available() returns 0). I just realized that they completely changed the serial.flush() function...which was probably a bad idea since 'flush' means to empty! Now flush 'waits' for transmitting data to complete.

I'm looking into the original flush() operation, will post a fix comparable to the original function (if I can come up with one)

dwyer2bp
Posts: 3
Joined: Fri Dec 03, 2010 8:55 am

Re: How to clear out or flush the arduino serial buffer

Post by dwyer2bp » Wed Aug 21, 2013 6:43 pm

For anyone curious about the serial.flush() code change...

New (Arduino 1.0+ Serial.Flush())

Code: Select all

void HardwareSerial::flush()
{
  while (_tx_buffer->head != _tx_buffer->tail)
    ;
}
Old (Arduino 23- Serial.Flush())

Code: Select all

void HardwareSerial::flush()
{
  _rx_buffer->head = _rx_buffer->tail;
}
What I did to return this function to my current Arduino version, was add a new function to HardwareSerial.h.

Code: Select all

virtual void flushRX(void);
Then, add the above (old) flush() function to HardwareSerial.cpp (but name it flushRX). Worked like a charm.

Code: Select all

void HardwareSerial::flushRX()
{
  _rx_buffer->head = _rx_buffer->tail;
}
I did not realize they changed the function, and have been debugging code that USED to work... and suddenly stopped working.

Good Luck!

fixloop
Posts: 1
Joined: Wed Nov 09, 2016 4:30 am

Re: How to clear out or flush the arduino serial buffer

Post by fixloop » Wed Nov 09, 2016 4:46 am

I did as advised, but there was an error:

C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.cpp:192:35: error: request for member 'tail' in '*(unsigned char*)(&((HardwareSerial*)this)->HardwareSerial::_rx_buffer)', which is of non-class type 'unsigned char'

_rx_buffer->head = _rx_buffer->tail;

^

exit status 1

I added a line in HardwareSerial.cpp:

void HardwareSerial::flushRX()
{
_rx_buffer->head = _rx_buffer->tail;
}
void HardwareSerial::flush()
{
// If we have never written a byte, no need to flush. This special
// case is needed since there is no way to force the TXC (transmit
// complete) bit to 1 during initialization
if (!_written)
return;

while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
// Interrupts are globally disabled, but the DR empty
// interrupt should be enabled, so poll the DR empty flag to
// prevent deadlock
if (bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
}

I added a line in HardwareSerial.h:
public:
inline HardwareSerial(
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *ucsrc, volatile uint8_t *udr);
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint8_t);
void end();
void flushRX(void);
virtual int available(void);
virtual int peek(void);
virtual int read(void);
int availableForWrite(void);
virtual void flush(void);
virtual size_t write(uint8_t);
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool() { return true; }

// Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void);
void _tx_udr_empty_irq(void);
};
Please help me to understand whats wrong?

sakirullahi
Posts: 1
Joined: Thu Jul 26, 2018 6:37 am

Re: How to clear out or flush the arduino serial buffer

Post by sakirullahi » Thu Jul 26, 2018 6:41 am

I got the same error and fixed by changing following code

Code: Select all

void HardwareSerial::flushRX()
{
_rx_buffer->head = _rx_buffer->tail;
}
with

Code: Select all

void HardwareSerial::flushRX()
{
  _rx_buffer_head = _rx_buffer_tail;
}
But the problem is that even if this is not returning any errors, the Serial input is not getting flushed. :|

Post Reply