Clearing serial buffer solved

What's your native language OP?

irrelevent stick to the topic!

multimedia:
irrelevent stick to the topic!

Relevant, beccause you aren't making much sense when you type and I thought if you are not a native English speaker I would help you find the forum where they speak your language.

If English is your native language then please take a little more care when you type to make something that is readable by others. Incude maybe some punctuation or something. You're asking a bunch of professionals for help, you're not typing a text message to your boyfriend. Try to look at least mildly intelligent if you want anything other than the dregs to try to help you.

2 Likes

aditya123:
Hi all,
i had this question a few weeks back , after the change in flush() method it had become quite difficult to empty the serial buffer , [...].

Unfortunately, I could never figure out the meaning/significance ofemptying the serial buffer.

A: Emptying the Serial Buffer of the Receiver Section
Data comes to the receiver one character at a time. When the character arrives, it is immediately read upon and is saved in an user defined array. If so, how a serial buffer can get full and such we need to empty/flush it after reading the data. It is only one byte long buffer as I understand. If we don't read the character that has just arrived, there is a possibility that the character byte might be overwritten by the arrival of the next character. Therefore, the speed of data read must be higher than the speed (the Bd) at which data arrives.

B: Serial Buffer of the Transmit Section.
In UART Protocol, one character is transmitted at a time. If so, the execution of the command Serial.print("Arduino"); requires that there should be an intermediate buffer to hold the characters of the message Arduino. As I understand, the transmission of Serial.print("Arduino"); is composed of the following 7 sub transmissions:

Serial.print('A');
Serial.print(r');
Serial.print('d');
Serial.print('u');
Serial.print('i');
Serial.print('n');
Serial.print('o');

How much (in byte) is the length of the serial buffer of the Transmit Section?

Both buffers are 64 bytes on most boards.

It's defined in HardwareSerial.h

#if !defined(SERIAL_TX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_TX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64
#endif
#endif
#if !defined(SERIAL_RX_BUFFER_SIZE)
#if ((RAMEND - RAMSTART) < 1023)
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_RX_BUFFER_SIZE 64
#endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if  (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif

Delta_G, it is just an academic query:

If the buffer size of the Transmit Section is 64 byte, only 64 characters of the following message should be transferred and the remaining characters are either lost or queued somewhere. Practically, it is observed that the whole text has appeared on the Se rail Monitor.

Serial.println("//put your setup code here, // put your setup code here, to run once: // put your setup code here, to run once: // put your setup code here, to run once:");

Yes, print will block if the buffer is full. cant post the code from print.h right now but it's there.

This is the reason Serial print from an interrupt is so dangerous. Nothing leaves the buffer because the interrupts are off and print deadlocks waiting for room in the buffer.

Delta_G:
Because throwing away serial data without any regard for what is there is generally considered "stupid as f&%k" and the people who wrote the language weren't generally that stupid. If you're throwing away random amounts of data you should at least be looking for valid packet start markers while you do it. But really, if you find yourself just blasting through throwing much away then you probably have a seriously flawed program or protocol and you should really fix that first.

I'm gonna call you on this. You shouldn't be calling scenarios like that stupid, making him feel bad.

I present a simple counter-example:
Random data which made its way through 8N1 encoding when your RX receiver was listening to data on a bus intended for another receiver.

This is the case in my project, and I'm not doing something 'stupid'. I'm using a single wire for both RX and TX, and when in RX, the baud rate is different from the TX baud rate. Some times you need to send out a command to change TX properties and reinitialize your receiver, clearing prior data you know is junk.

I too was looking for a simple method to clear the input buffer aside from a while loop.

Random data which made its way through 8N1 encoding when your RX receiver was listening to data on a bus intended for another receiver.

If you are throwing out the whole buffer, how do you know where the random data ends and the good data starts? I'll say it again, throwing away data without knowing what it is that you are throwing away is foolish. I'm sure you'll find some corner case where it makes sense to you, but it is still foolish from a design perspective.

If your receiver is picking up random garbage from some other bus that it wasn't supposed to be listening to then you have a design issue, not a need to throw away data.

In my case the lcd screen only holds x number of chars, so all good i wana be able to clear it to then print new input when thats the case but not if no new input comes in.

Delta_G:
If you are throwing out the whole buffer, how do you know where the random data ends and the good data starts? I'll say it again, throwing away data without knowing what it is that you are throwing away is foolish. I'm sure you'll find some corner case where it makes sense to you, but it is still foolish from a design perspective.

If your receiver is picking up random garbage from some other bus that it wasn't supposed to be listening to then you have a design issue, not a need to throw away data.

If the given design dictates that you know its all garbage, then its not foolish from a design perspective. And there's no 'design issue' - theres imposed constraints.

Don't be so righteous - there is a world of scenarios out there you haven't heard of and likely won't. You're not going to win this one - just take it on the nose that you shouldn't tell people they're foolish for their choices when you have no backstory.

There is a million scenarios where you are listening to garbage but you can TX out a command to clear it. Radio encounters jokes like this all the time. Be helpful.

1 Like

whatever kid.
It's just like the mailbox. If you throw away without knowing why it is then how you know it wasn't a big check from Ed McMahon?

If you know it is garbage then that isn't throwing it away randomly. But the question becomes how do you know it is garbage?

And yes, if you're having this problem then show me the design and I can fix it so you don't need to do something like this. If you do it right you don't have to throw away data you don't know what it is. If you find yourself with random garbage data then there is a better way to do whatever you are doing.

If you work for me and come to me with a design where you don't know where signals are coming from and can't control things then you'll probably be in the unemployment line real soon. And I'll get someone who knows what they're doing to rewrite it so that things are under control and we know where our signals are coming from.

oh yeah big man the employer.

You've just been caught out beating on a newbie and giving him bad advice. All that matters is that you should be helpful and learn that you're wrong somewhere.

It never occurred to you that there might be a side-channel which indicates when data is garbage or understandable. It never occurred to you that the flow control mechanism might actually make it deterministic so you can infer the entire buffer is garbage.

You just didn't think of these things. You just assumed it must be wrong, and because of some principal you know of, it MUST be other people's designs - not your rule of thumb yer sticking to.

You need to stop beating your chest and allow people to teach you things.

2 Likes

If you've got a side channel that tells you the data is garbage then why are you putting it in the buffer? Why aren't you tossing that data as it arrives? You're wasting resources. I'll get someone competent to write this. Better luck next time.

Ok its for an lcd display using i2c and i dont wish to use any sd card with that in mind heres the code...

https://forum.arduino.cc/index.php?topic=494077.0

is the link to my question please post as reply there or here, up to you.

Your problems there have nothing to do with this thread. That thread is old as hell. You didn't post your code right. Your errors are about really simple stuff like undefined functions. If that's your level of coding then you really have absolutely no place trying to school me on anything.

If you still need help on that thread then bump it, add some code tags, and wait for someone you haven't spent the last few posts trying to insult.

1 Like

Delta_G:
If you've got a side channel that tells you the data is garbage then why are you putting it in the buffer? Why aren't you tossing that data as it arrives? You're wasting resources. I'll get someone competent to write this. Better luck next time.

Do you know what the problem is here being solved? Or are you telling someone how to solve the problem. You're acting a mix of both. Which is very poor form. 'Wasting resources' aye. Now you're attributing worth to things without any justification because you don't understand the problem/scenario/constraints.

Look at how much work you gotta to do save face now. Much easier to just learn stuff & be kind aint it?

I hate to resurrect an old thread, except that I came here looking for suggestions on this for nearly (as far as I can tell) the same reason that multimedia did. I only wanted to resurrect to describe the use case I'm in, because I am quite experienced, and I still willfully want to discard serial data.

My use case is this: I'm streaming serial data to an LCD (it's a 160x128 TFT driven by a ST7735, to be exact). The serial data represents animation frames read from an SD card. I can't control the rate at which the frames come in, because it's part of an old Vixen sequence I don't want to rework. The frames take time to render. And not constant time either. I try to change a little of the display as possible. But they do come in faster than the draw time usually. The thing is, one animation frame from the human perspective is many Vixen frames, and most are redundant. Even if they aren't the animation looks fine. So I eat them up with a serial read to purposely frame drop. It looks great. There are no packets to mark. It's just raw bytes that point to frames by file name. I don't care if they get dropped.

I know. It's a weird use case (probably). I could go back and redo the entire old project, sure. But this simple fix is logical and it works with no real negative side effects. Plus the result is hilarious.

Here is the entire code:

#include <Adafruit_GFX.h>         // Core graphics library
#include <Adafruit_ST7735.h>      // Hardware-specific library
#include <SdFat.h>                // SD card & FAT filesystem library
#include <Adafruit_SPIFlash.h>    // SPI / QSPI flash library
#include <Adafruit_ImageReader.h> // Image-reading functions
#include <SoftwareSerial.h>

// TFT display and SD card share the hardware SPI interface, using
// 'select' pins for each to identify the active device on the bus.

#define SD_CS    D3 // SD card select pin
#define TFT_CS   D8 // TFT select pin
#define TFT_DC   D4 // TFT display/command pin
#define TFT_RST  D2 // Or set to -1 and connect to Arduino RESET pin

SdFat                SD;         // SD card filesystem
Adafruit_ImageReader reader(SD); // Image-reader object, pass in SD filesys


Adafruit_ST7735      tft    = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
Adafruit_Image       img;        // An image loaded into RAM
int32_t              width  = 0, // BMP image dimensions
                     height = 0;

SoftwareSerial mySerial(D1, D2); // RX, TX
int incomingByte;

void setup(void) {

  Serial.begin(9600);


  tft.initR(INITR_BLACKTAB); // Initialize screen

  // The Adafruit_ImageReader constructor call (above, before setup())
  // accepts an uninitialized SdFat or FatFileSystem object. This MUST
  // BE INITIALIZED before using any of the image reader functions!
  Serial.print(F("Initializing filesystem..."));
  // SD card is pretty straightforward, a single call...
  if (!SD.begin(SD_CS, SD_SCK_MHZ(10))) { // Breakouts require 10 MHz limit due to longer wires
    Serial.println(F("SD begin() failed"));
    for (;;); // Fatal error, do not continue
  }

  tft.fillScreen(ST7735_BLUE);

  reader.drawBMP("vprice.bmp", tft, 0, 0);

  // set the data rate for the SoftwareSerial port
  mySerial.begin(115200);
}

void loop() {
  if (mySerial.available( )) {
    Serial.println("Getting data");
    incomingByte = mySerial.read();
    Serial.print(incomingByte);
    Serial.println();
    draw_frame(incomingByte);
  } 

}

void draw_frame(int drawByte) {
  if (drawByte == 0) {
  } else if (drawByte < 10) {
    reader.drawBMP("vprice.bmp", tft, 0, 0);
  } else if (drawByte < 50) {
    reader.drawBMP("vpricesubb.bmp", tft, 30, 54);
  } else if (drawByte < 100) {
    reader.drawBMP("vprice2subb.bmp", tft, 30, 54);
  } else if (drawByte < 150) {
    reader.drawBMP("vprice3subb.bmp", tft, 30, 54);
  } else {
    reader.drawBMP("vpriceskullfin.bmp", tft, 0, 0);
  }
  
  // Drop the rest of the pending frames. No time to draw them now!
  while (mySerial.available()) {
    mySerial.read();
  }
}

I too am having an issue where I need to clear the receive buffer, or find a similar solution. The received command remains in the buffer and the program continuously runs, where I only want it to run once.

Has anyone got any helpful advice? And I do mean helpful, not belittling, demeaning or otherwise just some a$$ trying to prove they're better than we inexperienced newcomers to Arduino.

I have an example
I start the board, it creates the refference to the serial port 57600 baud
and by the time the code is running and transmitting (in my case a decimal number representing frequency at 500ms interval).
the receiver sees
6433882
¬5 or somother randon crap with squares and percentages in it before it settles
and outputs

150
150
150
etc.

if the data transmitted was for a critical system (yes i know its a hobby micro) then the garbage first sent could be a serious issue.

The point here is that the creators of Arduino instruction set have created this discipline. Im sure atmel and microchip would not set this as standard. The Arduino may be a hobby board but the Atmega 328 IC isnt and is certainly used in industry.

the question is how to prevent this issue.
flush is not the right answer as its function is to block further transmission or receipt until the buffer is emptied - basically a delay

If i were running a neuclear power plant i wouldnt want garbage data, i personally could not give a stuff if i ditched it. That is where the expertise of the designer and programmer come into it.

Who's an idiot

1 Like