Serial buffer

krishna
Tue May 03, 2016 2:52 pm
Hi,
I am working with maple mini,
when am trying to read data from Serial.read() function am unable to read more then 64 byte.
How to increase the size of the Rxbuffer?

for example

void setup()
{
Serial.begin(9600);
Serial2.begin(9600);
}

void loop()
{
delay(1000);
if(Serial2.available())
{
Serial.print("Number of bytes to read : ");
Serial.println(Serial2.available(),DEC);
whlile(Serial2.available())
{
Serial.read();
}
}
}


GrumpyOldPizza
Tue May 03, 2016 3:08 pm
You could edit cores/maple/HardwareSerial.h and set SERIAL_RX_BUFFER_SIZE to say 128 …

The 63 is due to the buffering scheme that requires one entry to be not occupied. A 64 byte buffer will always max out at 63, a 128 byte buffer at 127 and so on.

You also don’t have more than 63 bytes in the receiver. The extra data that cannot be buffered is simply discarded.

Anyway mind quickly explaining why 63 bytes of receive buffer is not sufficient for your scenario ?

– Thomas


mrburnette
Tue May 03, 2016 5:00 pm
GrumpyOldPizza wrote:You could edit cores/maple/HardwareSerial.h and set SERIAL_RX_BUFFER_SIZE to say 128 …

krishna
Wed May 04, 2016 8:26 am
Thank you very much mrburnette,
Thanks for reply too..

krishna
Wed May 04, 2016 8:27 am
Thanks for reply Grumpy.

krishna
Wed May 04, 2016 8:30 am
Anyway mind quickly explaining why 63 bytes of receive buffer is not sufficient for your scenario ?

63 bytes of receive buffer is not sufficient for my scenario,
Even 127 bytes of receive buffer is not sufficient for my scenario.
any other solution?

Thanks,
Krishna.


WereCatf
Wed May 04, 2016 8:37 am
krishna wrote:63 bytes of receive buffer is not sufficient for my scenario,
Even 127 bytes of receive buffer is not sufficient for my scenario.
any other solution?

krishna
Wed May 04, 2016 8:55 am
Thanks WereCatf for reply,

You also don’t have more than 63 bytes in the receiver. The extra data that cannot be buffered is simply discarded.

But I am unable to read more then 63 bytes of data as Grumpy said.


WereCatf
Wed May 04, 2016 10:08 am
krishna wrote:But I am unable to read more then 63 bytes of data as Grumpy said.

RogerClark
Wed May 04, 2016 10:09 am
krishna wrote:Thanks WereCatf for reply,

But I am unable to read more then 63 bytes of data as Grumpy said.


krishna
Wed May 04, 2016 10:52 am
WereCatf wrote :
Now, the bigger issue here is that you haven’t explained what you’re reading from the serial-port, or what you’re planning on doing with it — there are most likely better ways of going about this in the first place

I am just trying to read GPS data.


RogerClark
Wed May 04, 2016 11:01 am
There are plenty of examples of reading GPS Data

Have you tried the one on the Arduino site

http://playground.arduino.cc/Tutorials/GPS

It looks like it uses a 300 character buffer, into which it reads the GPS chars, until it finds an end marker in which case it processes the data.


mrburnette
Wed May 04, 2016 11:45 am
krishna wrote:WereCatf wrote :
Now, the bigger issue here is that you haven’t explained what you’re reading from the serial-port, or what you’re planning on doing with it — there are most likely better ways of going about this in the first place

I am just trying to read GPS data.


bluesystems
Sat Mar 11, 2017 5:53 pm
I note that on the STM32F103 the serial buffer size does not seem to be pulled from HardwareSerial.h.
It HardwareSerial.h is edited from 64 bytes to 128 there is no change in the serial port’s buffer size.

I changed
C:\Users\johnston\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\cores\maple\HardwareSerial.h
//#define SERIAL_TX_BUFFER_SIZE 64
//#define SERIAL_RX_BUFFER_SIZE 64
#define SERIAL_TX_BUFFER_SIZE 128
#define SERIAL_RX_BUFFER_SIZE 128


bluesystems
Sat Mar 11, 2017 6:35 pm
After doing some digging it become clear the uart buffer sizes in pulled from

C:\Users\johnston\Documents\Arduino\hardware\Arduino_STM32-master\STM32F1\system\libmaple\include\libmaple\usart.h

Changing the file as follows…
/*
* Devices
*/

#ifndef USART_RX_BUF_SIZE
//#define USART_RX_BUF_SIZE 64
#define USART_RX_BUF_SIZE 512
#endif

#ifndef USART_TX_BUF_SIZE
//#define USART_TX_BUF_SIZE 64
#define USART_TX_BUF_SIZE 128
#endif


asmallri
Sun Jan 14, 2018 3:09 pm
Thanks Bob, This was a great help. I could not find how to fix this ring buffer size problem.

mrburnette
Sun Jan 14, 2018 9:33 pm
[asmallri – Sun Jan 14, 2018 3:09 pm] –
Thanks Bob, This was a great help. I could not find how to fix this ring buffer size problem.

Ol’ Bob has not been active in the forum since
by bluesystems
Sun Mar 12, 2017 4:14 pm

While it is appropriate to wake-up an old thread to add pertinent information, it is considered bad forum manners to wake up a long sleeping post just to say, “Thank you.”

However, his suggestion on enlarging the serial buffer will work, but is not a recommended “fix” since editing the core files is always a last resort.

Rather the coder should implement their own separate buffer(s) if the default size is not satisfactory. If one hacks around in the core, then all changes are overwritten the next time you update… and at the rates changes are being submitted for github pull requests, that could be often.

If you need an example of double-buffering, Lady Ada (Adafruit) has an example here in her GPS parser:

https://raw.githubusercontent.com/adafr … it_GPS.cpp

Ray


stevestrong
Sun Jan 14, 2018 10:41 pm
As Ray said, you should not change the buffer size in the core.

If your sensor is reeeeaaaaallllly slow, then I would recommend to attach a short function to the systick interrupt which (each 1 ms) will read a character from the serial, if received, and stores it in an additional larger buffer. (viewtopic.php?f=18&t=2117)
This way you don’t have to mess with the core inner organs.


asmallri
Mon Jan 15, 2018 9:12 am
Thank you for the advice, I understand exactly what you are saying however in my case large interrupt driven receive ring buffers are the appropriate solution.

It is unfortunate that it requires modding the core but there are some things, such as the ability to specify the size of ring buffers, do not belong in the core. It should be possible to specify the size of a ring buffer per device without having to perform your own management of two tier ring buffers by performing unnecessary buffer to buffer copies.


stevestrong
Mon Jan 15, 2018 9:23 am
[asmallri – Mon Jan 15, 2018 9:12 am] –
It should be possible to specify the size of a ring buffer per device without having to perform your own management of two tier ring buffers by performing unnecessary buffer to buffer copies.

Of course it is possible by using dynamic allocation, but not preferred, as malloc() could by case behave other than expected, increase the generated bin size, also dependent on the compiler version and used compiler switches. For relatively small RAM (embedded systems) the dynamic allocation brings no advantage, just increases the risk the application to fail.
This has been discussed already and has been decided that static size definitions will be used.
It was agreed that there are other methods (like those suggested) which help when larger buffer is needed.

Whether the ring buffer is interrupt driven or not is of lower importance if you have anyway slow sensors which hinder you to get the received data from the serial interface, which forces you to increase the size of the buffer.


edogaldo
Mon Jan 15, 2018 10:12 am
In my opinion there are 2 weakness in current Serial buffer implementation:

  • the buffer size is not easily configurable via code (anyway it could be changed at board level in boards.txt passing -DUSART_RX_BUF_SIZE=xx -DUSART_TX_BUF_SIZE=yy)
  • if you have N Serial devices (Maple has 3 and other have more), you will have 2*N buffers instantiated, even if you use only one Serial or don’t use any at all..

I’d think these are issues that could be addressed in order to make a better core, one option could be moving the buffers in the variant files.


asmallri
Mon Jan 15, 2018 4:51 pm
I could not find a reference to “DUSART_RX_BUF_SIZE” or “DUSART_TX_BUF_SIZE” anywhere including a general google search. Do you have a reference or example?

Thanks, Andrew


edogaldo
Mon Jan 15, 2018 5:23 pm
[asmallri – Mon Jan 15, 2018 4:51 pm] –
I could not find a reference to “DUSART_RX_BUF_SIZE” or “DUSART_TX_BUF_SIZE” anywhere including a general google search. Do you have a reference or example?

Thanks, Andrew

In boards.txt you could add, for example, row: <board_name>.build.hs_flag=-DUSART_RX_BUF_SIZE=100 -DUSART_TX_BUF_SIZE=100
i.e.:
###################### Generic STM32F103C ########################################

genericSTM32F103C.name=Generic STM32F103C series
[...] genericSTM32F103C.build.hs_flag=-DUSART_RX_BUF_SIZE=100 -DUSART_TX_BUF_SIZE=100
[...]


mrburnette
Mon Jan 15, 2018 6:51 pm
[edogaldo – Mon Jan 15, 2018 10:12 am] –
<…>
I’d think these are issues that could be addressed in order to make a better core, one option could be moving the buffers in the variant files.

Yes, the Boards.txt file could be modified to pass a variable from a list of pre-determined buffer sizes. Seems a bit silly, IMHO, since someone could still require a buffer size not identified in the boards.txt

Folks that honestly need a change in the default size “should” be able to correct the problem on-their-own. I am a proponent of users not hacking on the core, so the “fix” really should be a user-defined buffer (again, in my opinion.) This solves the concern about increasing the send buffer when only the receiver buffer needs to be enlarged … OH, well I guess the boards.txt file could have two (2) variables, one for Tx and one for Rx. Convoluted.

Now, I believe that the 64 byte Arduino values are probably too small for the STM32 as the uC has a faster clock and far more SRAM. But a default is a default … we just need to figure out if bluesystems numbers are appropriate of if staying with the 64/64 is better because that is what Arduino does.

When we start pulling all of the constants into the boards.txt file, it is very easy to “lose” the actually deployed setting after the fact … failing to document completely in notes what settings were actually chosen. ArduinoIDE fails on many fronts, but the metadata utilized from all of the soft-settings really should be appended to the source.ino file for documentation purposes…. or to a separate file as far as I am concerned. File exists in current directory, read it and set the values. File does not exist in current directory, set the default values.

Maybe we should just all kick the IDE in the butt and use make? At least that way, settings that are not defaults are documented.

There are so many smart developers here (and I except myself since I was technically never a developer but one of those gosh-darn managers.) We simply cannot go changing the core or the environment every time someone runs into a bit of a rough spot. Roger cannot keep up with the churn.

Why not build a library that allows buffering of any serial port? At least with a library, the source code automatically documents the settings. Caveat

Ray


Leave a Reply

Your email address will not be published. Required fields are marked *