UART buffer size -- is it 63 or 64?

Theoretically, I know that UART buffer size is 64 which means, it can store up to 64 characters coming from INPUT BOX of Serial Monitor. The following sketch shows that I can catch only 63 characters coming from INPUT BOX implying that buffer size is 63. I would appreciate if someone clarifies the case.

void setup()
{
  Serial.begin(9600);
  L1: byte n = Serial.available();
  if ( n != 64)    // works for n != 63
  {
    goto L1;
  }
  Serial.println(n);
}

void loop() {}
1 Like

Why this is so important?
The right code should flush the buffer way before it overflowed.

2 Likes

It is important; because, I want to verify that the buffer size is indeed 64.

I understand that the buffer will be overflowed when more than 64 characters will be entered.

When I enter 63 characters (with No line ending option), the sketch works with if(n != 63) and the Serial Monitor shows 63.

When I enter 64 characters (with No line ending option), the sketch does not work with if(n != 64) and the Serial Monitor shows nothing.

You have the source at your fingertips.

1 Like

Take a view into the Serial-libary to gain the knowledge.

1 Like

@b707 actually implies that you should collect data when it becomes available; not wait till you have 64 bytes in the serial input buffer and then read them all.

Serial Input Basics - updated might be applicable.

else

byte buffer[64];

/*
read 64 bytes from serial
Returns:
  true when 64 bytes are read, else false;
*/
bool readSerial()
{
  static uint8_t idx = 0;

  if(Serial.available() >= 0)
  {
    buffer[idx++] = Serial.read():
  }
  if(idx == 64)
  {
    idx = 0;
    return true;
  }

  return false;
}

You call this repeatedly from loop()

void loop()
{
  if(readSerial() == true)
  {
    process the data
  }
}

Note:
not tested but it should give you the idea.

2 Likes

Welcome to the forum

Sorry, but it is my policy never to examine code that uses goto

2 Likes

It is common that an n-byte circular buffer will be considered "full" when it contains n-1 bytes.

As the others have said, it's all Open Source - so you can take a look at the code if it's important to you ...

Added:

1 Like

Your sketch works well; but, it does not answer to my query as you always clear the buffer by reading a character as it arrives. I want to read all the 64 characters once they are accumulated. (There are two typo mistakes in sketch of post #6 which I have corrected.)

 if(Serial.available() >= 0)
  {
    buffer[idx++] = Serial.read():

===>

if(Serial.available() > 0)
  {
    buffer[idx++] = Serial.read();

Again, that query could be answered by looking at the Serial library source code.

It is, indeed, using a Ring Buffer:

image

Then you really don't need a circular buffer ...

1 Like

Using goto statement, the OP observes visually that the program control is reverting to his designated label. The following equivalent codes do the same thing with a little bit of abstraction.

void setup()
{
  Serial.begin(9600);
  while (Serial.available() != 63)
  {
    ;
  }
  for (int i = 0; i < 63; i++)
  {
    Serial.print((char)Serial.read());
  }
}

void loop() {}

This seems to be a bad programming idea for me

1 Like

I know that :wink:

In my opinion it's the wrong approach; you should read when bytes arrive, not when your buffer is full.

2 Likes

So why do you want to do that?
What advantage does that bring?

It seems to me that it just adds overhead to no benefit? :thinking:

Thank you. This article actually contains the answer to my query of knowing that if the buffer size is 63 or 64. Now, I know that it's a circular buffer and the actual capacity is N-1 = 64-1 = 63.

Note that it's not necessarily the case that a Circular Buffer of length N can only hold N-1 entries - but that is a common implementation.

Again, if you really want to know for sure, then you need to check the source code.

You still to ignore the questions why you need to process a packet of 64 bytes at once.

1 Like

I don't want to process 64 characters at once; rather, I want to know through experiment that the serial buffer has 64 locations to hold 64 characters.

Again, why not just look at the source code - no need to mess about with experiments which may or may not yield valid results.
:roll_eyes:

2 Likes

The HardwareSerial.h says that --
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.

#define SERIAL_RX_BUFFER_SIZE 64

#define SERIAL_TX_BUFFER_SIZE 64

Nowhere is told that the actual capacity is N-1 bytes. It is only the experiment through which the OP has discovered the fact which has been supported by post #8 @awneil.