Array in Custom Library not holding Values

I’m trying to write a class that will store the last n values and return the average of the last n values. I’m still very new to working with C++ and don’t quite know where my problem is, but the array isn’t holding the values and is also storing incorrect values.

Here’s the .h

#ifndef MovingAvg_h
#define MovingAvg_h
#include "Arduino.h"

class MovingAvg
{
public:
    MovingAvg(int);
    void add(float);
    void reset();
    float get();
    int length();
private:
    int _size;
    float _values[];
    int _index;
    float _sum;
};
#endif // MovingAvg_h

Here’s the .cpp

#include "Arduino.h"
#include "MovingAvg.h"

MovingAvg::MovingAvg (int length)
{
    _size = length;
    float _values[_size];
    for(int i = 0 ; i < _size ; i++)
    {
        _values[i] = 0.0;
    }
    _index = 0;
}
int MovingAvg::length()
{
    return _size;
}
void MovingAvg::add(float input)
{
    if (_index >= _size)
    {


        Serial.print("_index = ");
        Serial.println(_index);
        Serial.println("looped!");
        _index = 0;

    }
    else
    {

        _values[_index] = input;

        Serial.print("_index = ");
        Serial.println(_index);
        Serial.print("Value Stored = ");
        Serial.println(_values[_index]);

        for (int i = 0 ; i < _size ; i++)
        {
            Serial.print("_values index: ");
            Serial.print(i);
            Serial.print(" = ");
            Serial.println(_values[i]);
        }


    _index++;
    }
}

void MovingAvg::reset()
{
    for(int i = 0 ; i < _size ; i++)
    {
        _values[i] = 0.0;
    }
    _index=0;
}

float MovingAvg::get()
{
    _sum = 0.0;
    for (int i = 0 ; i < _size ; i++)
    {
        _sum += _values[i];
    }
    return _sum / float(_size);
}

Here’s the arduino sketch:

#include <MovingAvg.h>

MovingAvg avg(10);
float average = 0;

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


void loop(){
  avg.add(30.0);
  average = avg.get();
  Serial.print("Average: ");
  Serial.println(average);
}

And here is some output when run on duemilanove w/ atmel 328:

_index = 0
Value Stored = 30.00
_values index: 0 = 30.00
_values index: 1 = 0.00
_values index: 2 = 0.00
_values index: 3 = 0.00
_values index: 4 = 0.00
_values index: 5 = 0.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 0.00
_index = 1
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 30.00
_values index: 2 = 0.00
_values index: 3 = 0.00
_values index: 4 = 0.00
_values index: 5 = 0.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 3.00
_index = 2
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.00
_values index: 3 = 0.00
_values index: 4 = 0.00
_values index: 5 = 0.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 3.00
_index = 3
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 0.00
_values index: 5 = 0.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 6.00
_index = 4
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 0.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 9.00
_index = 5
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 30.00
_values index: 6 = 0.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 12.00
_index = 6
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 30.00
_values index: 6 = 30.00
_values index: 7 = 0.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 15.00
_index = 7
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 30.00
_values index: 6 = 30.00
_values index: 7 = 30.00
_values index: 8 = 0.00
_values index: 9 = 0.00
Average: 18.00
_index = 8
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 30.00
_values index: 6 = 30.00
_values index: 7 = 30.00
_values index: 8 = 30.00
_values index: 9 = 0.00
Average: 21.00
_index = 9
Value Stored = 30.00
_values index: 0 = 0.00
_values index: 1 = 0.00
_values index: 2 = 30.03
_values index: 3 = 30.00
_values index: 4 = 30.00
_values index: 5 = 30.00
_values index: 6 = 30.00
_values index: 7 = 30.00
_values index: 8 = 30.00
_values index: 9 = 30.00
Average: 24.00

I kept getting incorrect average values, which prompted me to use Serial.print to see what’s going from within the library code itself. Couldn’t think of a better way of doing it.

To make sense of the output: The program currently outputs from within the class the _index value used for storing the input into the array using the add() function, followed by the array value as read back from the _index position. Next the entire contents of the array are output, followed by the average as called from within the sketch.

Any insight into what might be causing the weirdness, as well as possible fixes would be appreciated.

You are creating a local array in your function, and not using the array in your class.

class MovingAvg
{
public:
MovingAvg(int);
void add(float);
void reset();
float get();
int length();
private:
int _size;
float _values;
int _index;
float _sum;
};

MovingAvg::MovingAvg (int length)
{
_size = length;
float _values[_size];
for(int i = 0 ; i < _size ; i++)
{
_values = 0.0;

  • }*
  • _index = 0;*
    }[/quote]
    Drop the ‘float’ in the function and you will use the class version.

Drop the 'float' in the function and you will use the class version.

I removed the 'float' in the constructor but am experiencing the exact same issues.

You have to size the array.

If you do not want to use templates, or give it a default size, create an array outside of the class and pass in its pointer and length.

class MovingAvg
{
public:
    MovingAvg(int, float*);
    void add(float);
    void reset();
    float get();
    int length();
private:
    int _size;
    float *_values;
    int _index;
    float _sum;
};
MovingAvg::MovingAvg (int length, float *f )
{
    _size = length;
    _values = f;
    for(int i = 0 ; i < _size ; i++)
    {
        _values[ i ] = 0.0;
    }
    _index = 0;
}
float arr[ 10 ];
MovingAvg m( 10, arr );

Thanks. This has been very helpful!