trying to create circular buffer (convert from matlab code to arduino)

Hi! Im working to create a circular buffer. I have made it already in matlab but am having trouble converting it into arduino. If anyone can help that would be great!!

buffSize = 100; %Length of signal
Fs = 50; %Sampling frequency (i.e. 20ms increments)
prd = 1/Fs; %Period
thresh = 0.5; %Threshold of amplitude needed to count pitch in FFT

circBuffX = nan(1,buffSize);
circBuffY = nan(1,buffSize);
circBuffZ = nan(1,buffSize);
circBufft = nan(1,buffSize);
% circBuffarea = nan(1,buffSize);
count = 0;
wait = 100; %number of steps to wait before potential next pitch (2 secs @50 Hz)
flag = -wait; %Initialized at -wait so that first trip through loop will not be obstructed

for step = 1:length(X);
circBuffX = [X(step,1) circBuffX(1:end-1)];
circBuffY = [Y(step,1) circBuffY(1:end-1)];
circBuffZ = [Z(step,1) circBuffZ(1:end-1)];
circBufft = [t(step,1) circBufft(1:end-1)];

but am having trouble converting it into arduino.

You appear to be having the most trouble posting your Arduino code. You'll need to read the stickies at the top of the forum and figure out how to post your code yourself. THEN we can help.

circBuffX = [X(step,1) circBuffX(1:end-1)];

So, that's MatLab-ese for "set the array circBuffX to the new sample concatenated with the old array not including the last element"? What a horrible way to implement a circular buffer, unless matlab optimizes it automagically.
Circular buffers on Arduino would normally be implemented with an array and a pointer to the "next" entry. Exact details would be dependent on how you wanted to access the data, but something like:

/*
 * add a new value to a circular buffer
 */
circadd(cirbuf *buf, float newval) {
   buf->ptr = (buf.ptr + 1) % buf->size;
   buf->buffer[buf->ptr] = newval;
}
/*
 * Get the nth oldest value from circular buffer (0 is oldest, bufsize-1 is newest)
 */
float circget(cirbuf *buf, int n) {
   int index = (buf->ptr + 1 + n) % buf->size;
   return buf->bufffer[index];
}

Thanks so much! Where would you put this in the code? In the void loop()??

westfw:
What is cirbuf and buf and newval?

/*
  • add a new value to a circular buffer
    */
    circadd(cirbuf buf, float newval) {
      buf->ptr = (buf.ptr + 1) % buf->size;
      buf->buffer[buf->ptr] = newval;
    }
    /
  • Get the nth oldest value from circular buffer (0 is oldest, bufsize-1 is newest)
    */
    float circget(cirbuf *buf, int n) {
      int index = (buf->ptr + 1 + n) % buf->size;
      return buf->bufffer[index];
    }

Those were just sort-of "hints"; a real implementation would take a bit longer...
A "proper" implementation would probably be wrapped in C++ operator overloading so that it looked like an ordinary array, but I don't think I'm up to it. (You'd think that this might already exist, but a quick search didn't turn up anything. Lots of "circular buffers" to fill and empty, and assorted queues of arbitrary size, but no efficient fixed-length circular arrays.)

you can create an array and move a pointer around the array to add elements... something like this:

struct CircularBuffer{
  CircularBuffer(size_t size);
  void addElement(float newElement);
  float average();
  
  float* array;
  float* next;
  size_t size;
  int index = 0;
  int num_elements = 0;
};

CircularBuffer::CircularBuffer(size_t arraySize)
{
  size = arraySize;
  array = new float[arraySize];
  next = &array[0];
}

void CircularBuffer::addElement(float newElement)
{
  *next = newElement;
  index++;
  if (index >= size)
  {
    index = 0;
  }
  next = &array[index];
  if(++num_elements > size)
  {
    num_elements = size;
  }
}

float CircularBuffer::average()
{
  float average = 0;
  for(int i = 0; i < num_elements; i++)
  {
    average += array[i];
  }
  return average/num_elements;
}

CircularBuffer myBuffer(10);  // create a 10 element (float) circular buffer

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

void loop() 
{
  if(Serial.available())
  {
    myBuffer.addElement(Serial.parseFloat());
    for(int i = 0; i < myBuffer.num_elements; i++)
    {
      Serial.print(myBuffer.array[i]);
      Serial.print(',');
    }
    Serial.println();
    Serial.print("Average: ");
    Serial.println(myBuffer.average());
  }
}

I added an averaging function for demonstration

This works great thank you so much!! Do you know how I would read a signal from an accelerometer and make the buffer work in real time?

For example, I am reading the raw accelerometer data for the x, y, and z axis and want to analyze the first 100.

Thanks so much for your help!!

For example, I am posting the code of what I think I would do. Let me know if you think it is right!

circular_buffer_2.ino (1.39 KB)

ou'd think that this might already exist, but a quick search didn't turn up anything. Lots of "circular buffers" to fill and empty, and assorted queues of arbitrary size, but no efficient fixed-length circular arrays.

The HardwareSerial class contains two circular buffers, of fixed length, for bytes. Changing that implementation of be float-based would be relatively simple.

ced_project:
For example, I am posting the code of what I think I would do. Let me know if you think it is right!

It looks like you posted the little program I wrote for you?

Could you tell us how it is that the stream of data comes in to your arduino? An example of the data stream would help.