Clearing the Serial Buffer?

Hello, I am trying to interface a CHR UM6-LT IMU with an Arduino Uno, and I was wondering if there was a single command to clear the Serial Buffer in the IMU. I read that Serial.flush() no longer works the way it used to, and I found this description for Stream.flush():

flush() clears the buffer once all outgoing characters have been sent.

This function is part of the Stream class, and is called by any class that inherits from it (Wire, Serial, etc). See the Stream class main page for more information.

If I can, I plan to use this command to clear the serial data buffer if an error is detected and poll the IMU for another read. Can someone give me a hint on how to impliment this for serial data transmission? To me, the page was a bit unclear on actual usage. Any help would be greatly appreciated!

Just read and discard any pending serial data.

Though why you would want to this escapes me. You should have start and end of packet markers. If a packet is bad, you wouldn't know that until you had read the whole packet, so anything still in the buffer is (part of) the next packet.

What you are doing is the equivalent of finding a type on a page, and turning the page, expecting to find a new paragraph at the top of the page. It doesn't work that way.

You could do this:

while (Serial.available ())
  Serial.read ();

But as PaulS says, maybe just keep reading until you get the start of the next packet. For example, the datasheet says:

When communication is performed over the UART, data transmitted and received by the UM6 is formatted into packets containing:

  1. The three character start sequence 's', 'n', 'p' to indicate the start of a new packet (ie. start new packet)

So just keep reading until you get 's', 'n', 'p' in sequence. You should probably do that anyway.

The UM6 will be in Listen Mode, not in Broadcast mode. Let's say that I'm polling the IMU for data from a specific register. If, for example, I receive 's' but not 'n' immediately after I may deduce that whatever data follows the initial 's' will completely useless. Similarly, if I get a Packet Type indicating a non-batch operation when I requested a batch operation, I'll want to start again. I would rather clear the entire serial buffer and ping the IMU for data again rather than burn through all the useless bytes. It will save both time and my helicopter from crashing into a wall.

I appreciate your input, but I don't think it would be safe for my project unless I am using two Arduino Unos, one to take care of motion and one dedicated to receiving/processing data.

Slightly off topic but....

The new Serial.print has thrown some of my code out of whack with its asynchronous processing.

How can can I block until the Serial.print has, in fact, sent out the characters?

How can can I block until the Serial.print has, in fact, sent out the characters?

See the comments in the original post. Serial.flush() now blocks until all outgoing data has been sent.

I appreciate your input, but I don't think it would be safe for my project unless I am using two Arduino Unos, one to take care of motion and one dedicated to receiving/processing data.

Reading, and discarding, the maximum of 64 bytes in the serial buffer, is incredibly fast.

PaulS:
Reading, and discarding, the maximum of 64 bytes in the serial buffer, is incredibly fast.

I understand that it may be fast, but I hope you can appreciate the fact that I would like something slightly faster. I emphasize efficiency in my projects, especially this one as I have a LOT riding on it. If there is no other way then of course I will be forced to burn through useless bytes of data (128 bytes total in the buffer, according to Arduino).

Is there a way to use Stream.flush() in the manner in which I am looking for? The documentation on its proper usage is a bit sketchy to me, and a definitive answer (either a yes or no) would be greatly appreciated!

It's great that you want to be efficient, but I think you are barking up the wrong tree here by wanting to clear the serial buffer "slightly faster".

The device you mention sends 's', 'n', 'p' followed by a packet type, some data, and two bytes of checksum.

Now let's say that in a particular case you get 's', 'n', 'x' instead. So you realize there has been an error and clear the buffer. However the sending device doesn't know that. So it is still sending packet type, data, checksum etc.

Now you start reading again, but you get . Oh no! Still not 's', 'n', 'p'! So you clear the buffer again. And try again. Then you get the checksum! Egads! Still not 's', 'n', 'p'! So you see, clearing the buffer "really fast" achieves nothing. In fact you have no really reliable way of knowing when all the "bad" data has arrived. Short of building in a nice long delay. Which itself is not efficient.

The only really reliable way of handling serial comms is to "take it as it comes". Just keep looking for the start of packet marker. After all, you can't pull it in any faster than the other end sends it out, so that is not at all inefficient.

Slappy:
If, for example, I receive 's' but not 'n' immediately after I may deduce that whatever data follows the initial 's' will completely useless.

Again, whether or not you think it is useless, the sending device will keep sending the rest of the packet. You can't stop that, short of arranging for it to be powered off mid-stream.

Also, keep in mind this ... Say there is some line noise, which happens to be an 's'. So you find an 's' which is the noise, followed by 's' 'n' 'p' which is VALID for the next packet. By discarding everything, you actually discarded a valid packet!

You really want a state machine. Find an 's'. OK, move onto next state. If you now get an 'n', move onto the next state. Ditto for 'p'. If something goes wrong, just go back to the first state.

I had completely overlooked that possibility! Thank you for bringing it to my attention. I have already made a state machine, so I'll just leave it as it for the most part. Thank you very much for your insight!

If there is no other way then of course I will be forced to burn through useless bytes of data (128 bytes total in the buffer, according to Arduino).

Since this whole discussion started because "the Serial.flush() function" changed, and the only changed to the Serial.flush() function occurred between 0023 and 1.0, I conclude that you are now using 1.0. In which case, the buffer size is no longer 128.

From HardwareSerial.cpp:

// Define constants and variables for buffering incoming serial data.  We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
#if (RAMEND < 1000)
  #define SERIAL_BUFFER_SIZE 16
#else
  #define SERIAL_BUFFER_SIZE 64
#endif

P.S. Since you have full access to the source code, you can always modify it to add a new method to restore the functionality of the old flush() method. Though, as has been said many times now, that is not a good idea.