Go Down

Topic: Efficient shifting of values in arrays (Read 641 times) previous topic - next topic

Hi!
I am using the accelerometer ADXL 345.
I get the x_acc from the deivce.
I want to store these values in an updating array of 50 values. So everytime I get a new value that gets updated in X[0] and every other value moves forward by 1 place.
{
  X[0] = x_acc;
 
  for( int i = 49; i>0 ; i--)
     {
       X = X[i-1];
     }
}

But because of this long for loop i loose some values that come from the device. Is there a more time efficient way of doing this?

AWOL

Don't move data, move pointers to data.
Much quicker.

Do you now see the reason we ask you to use code tags when posting code?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

billroy

Look into "circular buffers".  You can use two pointers, a head and a tail, to keep 50 items in the buffer without moving anything.

It's how Serial works.

-br


Don't move data, move pointers to data.
Much quicker.



Can you give me a small example of how to do that?
Thanx

billroy

Circular buffers are everywhere.  You could read the Serial() code that comes with Arduino.  There's a similar one here in the morse2 example that ships with Bitlash, at line 166:

https://github.com/billroy/bitlash/blob/master/examples/morse2/morse2.pde

-br

dhenry

Quote
Is there a more time efficient way of doing this?


1. google circular buffer;
2. Step back and ask yourself what you are trying to do this the data. If you are using it to calculate an average, there are far simpler ways.

Well I am trying to get the min and max values from this data.
I am not a frequent programmer, so not very well versed with the concept of pointers.
I am struggling to understand this circular buffer thing.

The idea is that the newest reading from the accelerometer should enter the array at the first spot and subsequently push the oldest reading from the last spot. I do not get how circular buffer does that, could you please be a little elaborate.
Thanks.

AWOL

Quote
Can you give me a small example of how to do that?

Yes sure.
Imagine you're a post-office worker, and part of your job is to delay the mail (I'm pretty sure the Royal Mail operates like this).
You've got a set of fifty pigeon holes.
A letter comes in, so you put it in the first pigeon hole, then a second, and so on.
When you've filled in fifty holes, it is time to send out the the first letter.
You don't take out the first letter, then go through each box, shifting the contents into the previous box, do you?
You take the letter out of the first box (the oldest one in your list), and put the most recent letter in its place.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

mstanley


Well I am trying to get the min and max values from this data.

If that's all you are trying to do there is a much simpler method that doesn't require an array. Using only 3 variables you can read the accelerometer into x_acc and then compare it to the min and max values.  After reading the accelerometer 50 times you will have the min and max.
Be warned, this code is only an example and doesn't stop reading the accelerometer after 50 readings. Also it does not reset the min_acc and max_acc variables for the next set of readings.
Code: [Select]

static float min_acc = 1000.0;   // Start with the maximum value possible from the accelerometer.
static float max_acc = 0.0;      // Start with the minium value possible from the accelerometer.
void loop() {
    x_acc = read_accelerometer();

    if (x_acc < min_acc) {
        min_acc = x_acc;
    }
    if (x_acc > max_acc) {
        max_acc = x_acc;
    }
}


robtillaart

#9
Jan 20, 2013, 03:50 pm Last Edit: Jan 20, 2013, 06:04 pm by robtillaart Reason: 1
Quote
Well I am trying to get the min and max values from this data.


This is a minimal circular buffer, with a max function, the min function should be similar.
Code: [Select]

int buf[50];
int pos = 0;

void add(int value);
{
 buf[pos++] = value; // place the value in the next slot.
 if (pos == 50) pos = 0;
}

int bufmax()
{
 int m = buf[0];
 for (int i=1; i<50; i++)
 {
   if (buf[i] > m) m = buf[i];
 }
 return m;
}

What this code does not do is handle the first 50 values correctly. So you need some code /vars to handle that (can be solved in various ways).
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

dhenry

Quote
Well I am trying to get the min and max values from this data.


For that, you don't need a buffer at all.

Code: [Select]

typedef struct {
  signed short min; //minimum
  signed short max; //maximum
} MINMAX_T;

//update minmax
void minmax(signed short value, MINMAX_T * minmax) {
  minmax->min = (value < minmax->min)? value: minmax->min;
  minmax->max = (value > minmax->max)? value: minmax->max;
}


So as the adc values come in, you pass it to minmax and it will update your minmax struct.

Go Up