Logging Averaged Sensor Data

I have a noisy sensor attached to A2 on my Pro Mini, so I need to smooth out my data before I log it to my SD card(or just print it to the serial monitor for now). I'd like to calculate a single mean based on a window of 10 measurements at 1 measurement per second (AKA 1 measurement for every 10 seconds)

I've found lots of help logging running averages that would create a constant running mean based on the last 10 measurements. But I'd like to log a single (averaged) data point every 10 seconds, as opposed to a single (averaged) data point every second.

Thanks!

Vinterwoo: I have a noisy sensor attached to A2 on my Pro Mini, so I need to smooth out my data before I log it to my SD card(or just print it to the serial monitor for now). I'd like to calculate a single mean based on a window of 10 measurements at 1 measurement per second (AKA 1 measurement for every 10 seconds)

I've found lots of help logging running averages that would create a constant running mean based on the last 10 measurements. But I'd like to log a single (averaged) data point every 10 seconds, as opposed to a single (averaged) data point every second.

Thanks!

First you have to decide if you want an average, easy to do, or mean, needing to sort the readings and pick the middle reading.

In either case, make an array to store the 10 values. Then if you want average, program a loop to add all 10 values and divide by 10. Then reset the array entries to zero.

If you want the mean value, then you will have to sort the array values into an order. Ascending is easiest to visualize. I don't know how people do it here, but one of the first "C" programs I ever wrote was a "bubble sort".

Paul

Thanks for that good advice. Though just to be clear, I am interested in the Average/ Mean- not the Mode.

But as far as making an array for 10 values, I thought I was on to something with the following code

const int sensorPin = A2;
const int numReadings= 10; // how many measurements to average over



int index=0;
float total=0;
float average=0;



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

void loop() {
  
 total=total + analogRead(sensorPin);
 index=index+1;


 if (index >=numReadings)

 {index=0;
 average=total/numReadings;

    Serial.print("Mean value is: ");
    Serial.println(average);
    delay(1000);

    total=0;
}
}

I think the code is doing what I want it to do, but just too fast. I'm still getting data every second, as opposed to every 10 seconds. I'm not sure if I just need to add another delay in somewhere, or if I'm fundamentally doing something wrong.

Like adding a delay here:

total=total + analogRead(sensorPin);
 delay(1000);
 index=index+1;

Perhaps this statistics library might be helpful:

http://playground.arduino.cc/Main/QuickStats

Vinterwoo: Thanks for that good advice. Though just to be clear, I am interested in the Average/ Mean- not the Mode.

But as far as making an array for 10 values, I thought I was on to something with the following code

const int sensorPin = A2;
const int numReadings= 10; // how many measurements to average over


int index=0; float total=0; float average=0;

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

void loop() {   total=total + analogRead(sensorPin); index=index+1;

if (index >=numReadings)

{index=0; average=total/numReadings;

    Serial.print("Mean value is: ");     Serial.println(average);     delay(1000);

    total=0; } }





I think the code is doing what I want it to do, but just too fast. I'm still getting data every second, as opposed to every 10 seconds. I'm not sure if I just need to add another delay in somewhere, or if I'm fundamentally doing something wrong.

My apologies, you are correct, my operations research/statistics class was sometime in the 1970's and my statistics book is at work. The value halfway in a sorted list is the median value.

Your method does give you an average, as you know.

I always try to start a program based on doing many things at the same time. Using that method wil make your life much easier. No delays are involved. You take sensor readings after a set number of milliseconds have elapsed.

Paul

One suggestion here - the best data is going to be from the cleanest data. If your sensor is very noisy as you indicate, the first step should be to try to isolate issue and eliminate the noise at the start then go from there to get your average, but first clean up the sensor data. Contrary to the sign we used to have at work “Garbage in, Gold out” it really does not work that way :slight_smile:

I made some voltage/amper loggers and calculate the average like you did. Instead for 10 samples why not take 100 or 1000 - gets better average.

And you can just sample until 10 seceond have passed using the arduino timer https://www.arduino.cc/en/Reference/millis

Perhaps put a delay(10) after every analog read for the ADC get some rest.

"for the ADC get some rest" Like its electron get tired? No need. Just take 2 readings every time and use the 2nd reading, gives the signal time to settle thru the mux and sample and hold cap and then the 2nd reading will be accurate.