Ring Buffer Library

Hi,
I am looking for a particle library for managing a ring buffer. My objective is to fill an array[10] with variables, when full, new data pushes the old data out. I can then analyse the data in the array. Is there something available which would suffice?
Thanks Micheál.

1 Like

I don’t think that a ring buffer library exists in the Particle libraries, but it’s simple enough for you to implement for your needs.

Since a ring buffer is similar to a queue data structure you can use any good C++ queue implementation you like and modify the enqueue function to dequeue an element if the queue is full before enqueueing the element.

https://www.google.com/search?q=c%2B%2B+implement+queue

You might also find this useful: https://embeddedartistry.com/blog/2017/05/17/creating-a-circular-buffer-in-c-and-c/

1 Like

Thanks very much for the info.

1 Like

If you don’t mind overwriting old data, you don’t need a complex ring buffer that keeps track of write position, read position and checking whether the buffer is full.

Just let your index loop around with a modulo.

int buf[10];
int index = 0;

void write(int val){
   index = (index + 1) % 10;
   buf[index] = val;
}

Now your most recent value is always at index.
So if you are only interested in having the 10 latest values and are pushing to the buffer at a regular interval, you don’t really need a ring buffer.

If you do need a ring buffer, because you need to keep track of how many items are in the buffer and you are producing and consuming them, the resources shared by @nrobinson2000 seem good.

3 Likes

Hi, yes, that makes things a good bit simpler. I can probably make this work a little easier.
Thanks all for the help.

I tend to make my buffer size ^2 and use a mask

Saves doing a division (%)

int buf[16];
int putIdx= 0;

void put(int val)
{
   buf[putIdx & 0x0F] = val;
   putIdx++;
}
3 Likes

Would you be able to explain what’s happening in this code please, and why you prefer it?

The buf index will range from 0-15 (0x0F) - 16 elements. No need for a computationally heavy % operation.

#define BUFFER_SIZE 16
#define BUFFER_MASK BUFFER_SIZE -1

int buf[BUFFER_SIZE];
int putIdx= 0;
int getIdx= 0;


bool get(int *out)
{
    // see if buffer is empty first
    if((getIdx & BUFFER_MASK) == (putIdx & BUFFER_MASK))
    {
        return FALSE; 
    }
    *out = buf[getIdx & BUFFER_MASK];
    getIdx++;
    return TRUE;
}

bool put(int val)
{
// see if buffer is full first
    if(((putIdx+1) & BUFFER_MASK) == (getIdx & BUFFER_MASK))
    {
        return FALSE;
    }
    buf[putIdx & BUFFER_MASK] = val;
    putIdx++;
    return TRUE;
}
2 Likes

If you care about the order of the values though, i.e. time series you may want to use the queue method described above. This one is less computationally intense but it will not store the last x values in order unless you use getIdx and putIdx to keep track of the current value. It’s a tradeoff between efficiency of code and ease of coding.

2 Likes