Embedded RingBufCPP
This is a simple ring (FIFO) buffer queuing library for embedded platforms, such as Arduino’s. This library is based on a previous one I wrote, only now in C++ instead of C. It uses C++’s templating, so no more weird pointer casting, and deep copies of objects are supported. It has concurrency protection built in, so feel free to do operations on the buffer inside of ISR’s. All memory is statically allocated at compile time, so no heap memory is used. It can buffer any fixed size object (ints, floats, structs, objects, etc…).
FAQ’s
- I only have a C compiler for my platform
- No worries, try the vanilla C version of the library.
Use Cases
A ring buffer is used when passing asynchronous io between two threads. In the case of the Arduino, it is very useful for buffering data in an interrupt routine that is later processed in your void loop()
.
Supported Platforms
The library currently supports:
AVR
ESP8266
Any other platform (just implement the
RB_ATOMIC_START
andRB_ATOMIC_END
macros)
Install
This library is now available in the Arduino Library Manager, directly in the IDE. Go to Sketch > Include Library > Manage Libraries
and search for RingBufCPP
. Then #include <RingBufCPP.h>
in your sketch.
To manually install this library, download this file as a zip, and extract the resulting folder into your Arduino Libraries folder. Installing an Arduino Library.
Examples
Look at the examples folder for several examples.
Contributing
If you find this Arduino library helpful, click the Star button, and you will make my day.
Feel free to improve this library. Fork it, make your changes, then submit a pull request!
API
Constructor
RingBufCPP<typename Type, size_t MaxElements>();
Creates a new RingBuf object that can buffer up to MaxElements of type Type.
Methods
add()
bool add(const Type &obj, bool overwrite=false)
Append an element to the buffer. If there is already MaxElements in the buffer, the oldest element will either be overwritten (when overwrite is true) or this add will have no effect (when overwrite is false). Return false on a full buffer.
peek()
Type *peek(uint16_t num);
Peek at the num’th element in the buffer. Returns a pointer to the location of the num’th element. If num is out of bounds or the num’th element is empty, a NULL pointer is returned. Note that this gives you direct memory access to the location of the num’th element in the buffer, allowing you to directly edit elements in the buffer. Note that while all of RingBuf’s public methods are atomic (including this one), directly using the pointer returned from this method is not safe. If there is a possibility an interrupt could fire and remove/modify the item pointed to by the returned pointer, disable interrupts first with noInterrupts()
, do whatever you need to do with the pointer, then you can re-enable interrupts by calling interrupts()
.
pull()
bool pull(Type *dest);
Pull the first element out of the buffer. The first element is copied into the location pointed to by dest. Returns false if the buffer is empty, otherwise returns true on success.
numElements()
size_t numElements();
Returns number of elements in the buffer.
isFull()
bool isFull();
Returns true if buffer is full, otherwise false.
isEmpty()
bool isEmpty();
Returns true if buffer is empty, false otherwise.
License
This library is open-source, and licensed under the MIT license. Do whatever you like with it, but contributions are appreciated.
References
Used by
IRremoteESP8266 Library Library
SoC support
esp32
esp32c2
esp32c3
esp32s2
esp32s3
esp8266
host
rp2040