C doesnt parse array first element - AVR GCC

112 views Asked by At

The code is pretty straight forward, i am storing the last 10 values and outputting the mean value. However, the 0 element of the array remains unchanged with initialized value '0'.

long int avg[10] = {0,0,0,0,0,0,0,0,0,0};
int i;
float temp2;

for (i=0;i<9;i++){
   avg[i] = avg[i+1];    //shift all values to the left
}
avg[9] = temp2;          //temp2 is the last value

temp2 = 0;               //i am reusing temp2 as mean result

for (i=0;i<10;i++){
   temp2 += avg[i];
}

temp2 /= 10;

By dividing the result by 9, the value is corrected but its purely a workaround and i would like to know why it is happening.

Thanks

EDIT:

so lets say my adc reads values close to 250. in the first runs, values are added in the array right to left:

0   0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0   251
0   0   0   0   0   0   0   0   251 252
0   0   0   0   0   0   0   251 252 248

etc.

while after a lot of runs the values should have filled the table, the table always has this form:

0  251  252  248  250  247  253  252  248  247

i hope i made it more clear

-- edit 2:

Why are you downvoting my question? Is it because you dont understand it? What serious compiler would compile that without an error/warning that i did not initialize temp2 and what exactly is the probability that this problem would appear because of that reason?

2

There are 2 answers

1
Shravan40 On

You have not initialized int temp2. That's why you are getting such result.

int temp2 = 0;
avg[9] = temp2;
1
vlad_tepesch On

Your code looks ok. it should do exact the thing it is supposed to do. Thats why the bug may be in the part you do not showed to us. maybe some out of bounds write that overwrites avg[0]?

Two things that i noticed: You mix float and ints. I doubt that you really need the floats here. since you store the input float in an int variable. so keep the processing completely in ints and only do the division at the end in float (but i also think that using int as an average should be sufficient)

The other thing is that you could integrate the summing into the first loop and just add the new value at the end.

long sum =0;
for (i=0;i<9;i++){
   avg[i] = avg[i+1];    //shift all values to the left
   sum +=avg[i]; 
}
avg[9] = temp2;          //temp2 is the last value
sum += avg[9];

Edit:
another two efficiency tips: the ADC only outputs 10bit values. so avg can be int16_t. Also 16bit is sufficient for the accumulator. If you use power-of-2 sizes the division is much more fast (even if using float). So you may average over 8 or 16 values.