Shifting Values in an array

Hi everyone Hope all is well.

i’m hoping (fingers crossed) some one might be able to help me.

I’ll try to keep it short

in the code below is my beginners approach

it gives the general idea of what i want to do but it obviously doesn’t exactly work and i’m not sure if its the right approach
I have 2 arrays a buffer and values …the values array is just there for the moment to work things out with. (much much later it will be an analog read of some description)
the objective is to read a value from its array and buffer 7 values continuously… so i can perform an fft calculation in slow motion to understand whats under the hood i’m just using integers for the moment just to build the framework.

any way at the moment i’m getting as an print

1 0 0 0 0 0 0 Then Calculate
2 1 0 0 0 0 0 Then Calculate
3 2 1 0 0 0 0 Then Calculate
4 3 2 1 0 0 0 Then Calculate
5 4 3 2 1 0 0 Then Calculate
6 5 4 3 2 1 0 Then Calculate
7 6 5 4 3 2 1 Then Calculate
8 6 5 4 3 2 1 Then Calculate
9 8 5 4 3 2 1 Then Calculate
10 9 8 4 3 2 1 Then Calculate
11 10 9 8 3 2 1 Then Calculate
12 11 10 9 8 2 1 Then Calculate
13 12 11 10 9 8 1 Then Calculate
14 13 12 11 10 9 8 Then Calculate
15 13 12 11 10 9 8 Then Calculate
16 15 12 11 10 9 8 Then Calculate
17 16 15 11 10 9 8 Then Calculate
18 17 16 15 10 9 8 Then Calculate
19 18 17 16 15 9 8 Then Calculate
20 19 18 17 16 15 8 Then Calculate

hopefully from this you can see what i’m trying to achieve but things fall apart as the while loop repeats and i lose the number 7

if you got this far thanks for reading : and here’s a joke

Why can’t you trust an Atom ??
Because they make up everything

int buffer[7]= {
0,0,0,0,0,0,0};
int values[20]={
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};

int i = 0;
int ii = 0;
int fromarray;

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

}

void loop() {
delay(5000);

while (1){
// Serial.print("i = “);Serial.print(i); Serial.print(” ii = ");Serial.println(ii);
if (i == 0){
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 1){
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 2){
buffer[2] = buffer[1];
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 3){
buffer[3] = buffer[2];
buffer[2] = buffer[1];
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 4){
buffer[4] = buffer[3];
buffer[3] = buffer[2];
buffer[2] = buffer[1];
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 5){
buffer[5] = buffer[4];
buffer[4] = buffer[3];
buffer[3] = buffer[2];
buffer[2] = buffer[1];
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
}

if (i == 6){
buffer[6] = buffer[5];
buffer[5] = buffer[4];
buffer[4] = buffer[3];
buffer[3] = buffer[2];
buffer[2] = buffer[1];
buffer[1] = buffer[0];
fromarray = values[ii];
buffer[0] = fromarray;
i = -1;
}

printer();
delay(1000);
i=i++;

if ( ii == 19){
break;
}
ii=ii++;

}//eo while 1

while (1){
Serial.println(“The End”);
delay (300000);

}

}//eo void

void printer(){
for(int i = 0; i < 7;i++){
Serial.print(buffer*);*
_ Serial.print(" ");_

  • delay(200);*
  • }*
    _ Serial.println(“Then Calculate”);_
    }
    [/quote]

That's a crazy approach. Leave the data where you put it and just move the pointer to it. Modulo arithmetic is often helpful here.

thanks for the reply

my math skills and things were lacking even some 60 years ago when i was at school

but please humor me i'm trying to learn even if it is to late.

all i'm trying to achieve or go by is this spreadsheet here

http://www.arduinoos.com/wordpress/wp-content/uploads/fir20.jpg

I can understand spreadsheets and even though it may be crazy i would still like to know how to buffer values. as the calculation requires access to the 7 most recent values ...remembering that the values array is just a test.

thanks again

As the other poster pointed out, shifting all the data each time is time-consuming. Better to write each new value to a different slot in the array, moving a pointer to the next position each time. The data will wrap around rather than sliding, so you need understand how to read it.

index  06 05 04 03 02 01 00

values 00 00 00 00 00 00 01
                         ^ last item written here

values 00 00 00 00 00 02 01
                      ^ last item written here

values 00 00 00 00 03 02 01
                   ^ last item written here

values 00 00 00 04 03 02 01
                ^ last item written here

values 00 00 05 04 03 02 01
             ^ last item written here

values 00 06 05 04 03 02 01
          ^ last item written here

values 07 06 05 04 03 02 01
       ^ last item written here

values 07 06 05 04 03 02 08
                         ^ last item written here

values 07 06 05 04 03 09 08
                      ^ last item written here

values 07 06 05 04 10 09 08
                   ^ last item written here
etc…

To interpret the values in your table, you need to know where the “Current item” pointer is.

In the table above I’m showing the position where the last item was written. The code actually keeps an index “nextIndex”, to the slot in the array where it’s going to write the next entry, so you want to subtract 1 from nextIndex to figure out the current item index (if nextIndex is zero, wrap back to the largest index)

You then read that item, then the item at the next lower index in the array. After index 0 you wrap around to the highest index, look there, and keep looking until you either find an empty slot (if the array isn’t filled yet) or get to the item before your current item pointer.

The code to write to a table like that is trivial:

int array[7];
int nextIndex;
...

setup()
{
  //Initialize the starting index and the array contents.
  nextIndex = 0;
  for (int i=0; i< sizeof(array); i++)
  {
    array[index] = 0;
  }
}

loop()
{
  int newValue = getNewValue();
  array[nextIndex] =  newValue;
  //The "%" is the modulo operator. "a = b%c" gives you the remainder of dividing b by c
  newValue = (newValue+1) % sizeof(array);
}

In the code above, it uses “nextIndex”, which shows the slot where the program is going to write the next value. To read the data, you should subtract 1 from nextIndex to get the index of the last item written in the array. Look at that value, subtract 1, wrapping back to the highest array index, and stop when you get back to “nextIndex”.

michaelmartin2758:
thanks for the reply

my math skills and things were lacking even some 60 years ago when i was at school

but please humor me i’m trying to learn even if it is to late.

all i’m trying to achieve or go by is this spreadsheet here

http://www.arduinoos.com/wordpress/wp-content/uploads/fir20.jpg

I can understand spreadsheets and even though it may be crazy i would still like to know how to buffer values.
as the calculation requires access to the 7 most recent values …remembering that the values array is just a test.

thanks again

Assuming you want the output I showed earlier then the below code will produce it.

byte values[26] = {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0};

void setup(){
  Serial.begin(115200);
  for (byte a = 19; a < 20; a--){
    for (byte b = 0; b < 7; b++){
      Serial.print(values[a + b]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

void loop(){}
1	0	0	0	0	0	0	
2	1	0	0	0	0	0	
3	2	1	0	0	0	0	
4	3	2	1	0	0	0	
5	4	3	2	1	0	0	
6	5	4	3	2	1	0	
7	6	5	4	3	2	1	
8	7	6	5	4	3	2	
9	8	7	6	5	4	3	
10	9	8	7	6	5	4	
11	10	9	8	7	6	5	
12	11	10	9	8	7	6	
13	12	11	10	9	8	7	
14	13	12	11	10	9	8	
15	14	13	12	11	10	9	
16	15	14	13	12	11	10	
17	16	15	14	13	12	11	
18	17	16	15	14	13	12	
19	18	17	16	15	14	13	
20	19	18	17	16	15	14

The point is to save recorded data values to a buffer and then display them, not print a set of arbitrary bytes. Your answer doesn’t address the OPs question.

Riva:
Assuming you want the output I showed earlier then the below code will produce it.

byte values[26] = {20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0,0,0,0};

void setup(){
  Serial.begin(115200);
  for (byte a = 19; a < 20; a–){
    for (byte b = 0; b < 7; b++){
      Serial.print(values[a + b]);
      Serial.print("\t");
    }
    Serial.println();
  }
}

void loop(){}






1 0 0 0 0 0 0
2 1 0 0 0 0 0
3 2 1 0 0 0 0
4 3 2 1 0 0 0
5 4 3 2 1 0 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1
8 7 6 5 4 3 2
9 8 7 6 5 4 3
10 9 8 7 6 5 4
11 10 9 8 7 6 5
12 11 10 9 8 7 6
13 12 11 10 9 8 7
14 13 12 11 10 9 8
15 14 13 12 11 10 9
16 15 14 13 12 11 10
17 16 15 14 13 12 11
18 17 16 15 14 13 12
19 18 17 16 15 14 13
20 19 18 17 16 15 14

The OP was having problems figuring out how to save a stream of values into a buffer and "age off" the oldest value. This screams for a circular queue, saved in an array.

What you posted has almost nothing to do with the OPs problem. You wrote nested loops that display values from 0 to 19. You did not post any code that saves anything into any kind of data structure. Your code does not contain an array of any kind.

You generate output that looks the same, but so what? It doesn't get the OP any closer to a solution to his/her stated problem.

I don't want to be combative, but I really don't think your post offers anything of value to the OP.

Riva:

DuncanC: The point is to save recorded data values to a buffer and then display them, not print a set of arbitrary bytes. Your answer doesn't address the OPs question.

Really! It's a very short step from printing the values on screen to either using them directly or storing them in a separate array.

the objective is to read a value from its array and buffer 7 values continuously.. so i can perform an fft calculation in slow motion to understand whats under the hood i'm just using integers for the moment just to build the framework.

That just about sums up the code. The OP was having trouble indexing the value from the array.

I apologize if I have offended.

Riva:

DuncanC: The OP was having problems figuring out how to save a stream of values into a buffer and "age off" the oldest value. This screams for a circular queue, saved in an array. Yes it does suit a circular array but the OP posted code to pull values from a pre loaded array and states that [u]later[/u] the values will be analogue reads.

What you posted has almost nothing to do with the OPs problem. You wrote nested loops that display values from 0 to 19. You did not post any code that saves anything into any kind of data structure. Your code does not contain an array of any kind. You must be blind then because the very first line is an array. The nested loops do not just print the values 0 to 19 it prints the values from the array that just happen to be sequential numbers (from the OP's original post). As I previously stated it is a small step from printing the values to the serial monitor to either storing them or using directly.

You generate output that looks the same, but so what? It doesn't get the OP any closer to a solution to his/her stated problem. The output is what I assume the OP wanted as they could not get the sequence correctly. AFAIK that has fixed their initial problem. I feel sure they are capable of expanding the code to do the rest of the things they want in the same way they would need to expand your code example to work with known values loaded from a separate array as outlined in the first post.

I don't want to be combative, but I really don't think your post offers anything of value to the OP. If you did not want to be combative then you should choose your words with more care. The way you worded your response on my reply and posting it again in it's entirety added nothing to the thread and feels like a personal attack to me. The fact you could not leave it at that and felt the need to justify your reasoning in a later post only reinforces my belief.

DuncanC: I apologize if I have offended.

Shall we just delete all the offending posts and pretend it never happened?

Here is some ringbuffer code I wrote a while ago. You'll need to change 'char' to an appropriate datatype for your application.

const byte bufLen = 5;
char ringBuf[bufLen] = "";
byte bufHead = 0; // where new chars get written to
byte bufTail = 0; // where oldest chars get pulled off

// =====================================================================================
// writes one char to the buffer. If the buffer is full, discard the oldest to make room
void pushBuf(const char pushed)
{
ringBuf[bufHead] = pushed; // insert new char at the front
bufHead++;
if(bufHead > bufLen)
  { bufHead = 0; }
if(bufHead == bufTail) // if buffer overflowed
  { bufTail++; } // discard oldest 
}

// =====================================================================================
// destructively reads one char from the buffer
char pullBuf()
{
char pulled;
pulled = ringBuf[bufTail];
bufTail++; // discard oldest
if(bufTail > bufLen)
  { bufTail = 0; }
return pulled;
}

// =====================================================================================
boolean bufEmpty()
{
if(bufHead == bufTail) 
  { return true;  } 
return false;
}

// =====================================================================================
// nondestructively prints the entire buffer for debugging purposes
void peekBuf()
{
char peekBuffer[bufLen + 1] = ""; // can't forget NULL terminator on C strings
byte peekBufferIndex = 0;
byte ringBufIndex = bufTail; // start at the tail...
while(ringBufIndex != bufHead) // ... and stop at the head
  {
  peekBuffer[peekBufferIndex] = ringBuf[ringBufIndex];
  peekBufferIndex++;
  ringBufIndex++;
  if(ringBufIndex > bufLen)
    { ringBufIndex = 0; }
  }
Serial.print("buffer=["); 
Serial.print(peekBuffer);
Serial.println("]");
}

// =====================================================================================
void clearBuf()
{
bufTail = bufHead;
}

// =====================================================================================
// see if the buffer contains a particular value. Can help avoid putting duplicates in the buffer. !UNTESTED!
boolean bufContains(byte value)
{
byte ringBufIndex = bufTail; // start at the tail...
while(ringBufIndex != bufHead) // ... and stop at the head
  {
  if(ringBuf[ringBufIndex] == value) // if the buffer contains the value we're looking for...
    { return true; } // ...stop looping and inform the calling code of that fact
  ringBufIndex++;
  if(ringBufIndex > bufLen)
    { ringBufIndex = 0; }
  }
// well we made it through the entire buffer and didn't find the value we were looking for, so...
return false;
}

// =====================================================================================
void setup() 
{

Serial.begin(38400);

Serial.println("Testing for non-empty buffer: ");
Serial.println("Pushing: X"); pushBuf('X'); 
if(!bufEmpty())
  { Serial.println("Buffer contains data"); }
else
  { Serial.println("Buffer is empty"); }

clearBuf();

Serial.println("Testing for empty buffer: ");
if(!bufEmpty())
  { Serial.println("Buffer contains data"); }
else
  { Serial.println("Buffer is empty"); }

Serial.println("Testing queue depth of 4");
Serial.println("Pushing: C"); pushBuf('C'); peekBuf();
Serial.println("Pushing: a"); pushBuf('a'); peekBuf();
Serial.println("Pushing: t"); pushBuf('t'); peekBuf();
Serial.println("Pushing: s"); pushBuf('s'); peekBuf();
while(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }

Serial.println("Testing queue depth of 5");
Serial.println("Pushing: H"); pushBuf('H'); peekBuf();
Serial.println("Pushing: e"); pushBuf('e'); peekBuf();
Serial.println("Pushing: l"); pushBuf('l'); peekBuf();
Serial.println("Pushing: l"); pushBuf('l'); peekBuf();
Serial.println("Pushing: o"); pushBuf('o'); peekBuf();
while(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }

Serial.println("Testing queue depth of 6");
Serial.println("Pushing: T"); pushBuf('T'); peekBuf();
Serial.println("Pushing: r"); pushBuf('r'); peekBuf();
Serial.println("Pushing: i"); pushBuf('i'); peekBuf();
Serial.println("Pushing: v"); pushBuf('v'); peekBuf();
Serial.println("Pushing: e"); pushBuf('e'); peekBuf();
Serial.println("Pushing: t"); pushBuf('t'); peekBuf();
while(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }

Serial.println("Testing rolling queue");
Serial.println("Pushing: 1"); pushBuf('1'); peekBuf();
Serial.println("Pushing: 2"); pushBuf('2'); peekBuf();
Serial.println("Pushing: 3"); pushBuf('3'); peekBuf();
Serial.println("Pushing: 4"); pushBuf('4'); peekBuf();
Serial.println("Pushing: 5"); pushBuf('5'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
Serial.println("Pushing: 6"); pushBuf('6'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
Serial.println("Pushing: 7"); pushBuf('7'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
Serial.println("Pushing: 8"); pushBuf('8'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
Serial.println("Pushing: 9"); pushBuf('9'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
Serial.println("Pushing: 0"); pushBuf('0'); peekBuf();
if(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }
while(!bufEmpty())
  {
  Serial.print("Pulled: ");
  Serial.println(pullBuf());
  peekBuf();
  }

}

// =====================================================================================
void loop()
{

  
}