Taking actions based on sensor input over a period of time (not a moving avg.)

Hey all.

I'm trying to write a program based on Arduino Uno that will allow me to take one of three actions depending on the average input from a vehicle ride height sensor over a period of time.

Being a ride height sensor, there will always be minor noise as roads are not perfectly level. In addition, there will be occasional larger spikes as the car goes over bigger bumps or corners.

The program needs to find the center of this data, and establish whether the car is riding too high, too low, or within the correct range, and take one of three actions based on this for a few seconds, before starting the process over again.

I looked into moving averages, but it seems like it would make things much simpler if I just gather data for a minute, calculate an average, take an action, and then start the loop over again. Constant adjustments are not needed, there shouldn't be much variation in the ride height from one minute to the next. Whether mean or median is better for this, I'm not sure.

All I've found so far are sketches for moving averages, how would one take a series of, say, 60 values, average this, take an action, and then start all over again, dumping all previous data?

SgtMustang:
I looked into moving averages, but it seems like it would make things much simpler if I just gather data for a minute, calculate an average, take an action, and then start the loop over again. Constant adjustments are not needed, there shouldn't be much variation in the ride height from one minute to the next. Whether mean or median is better for this, I'm not sure.

So take as many samples as you can (over the time you want?), calculate the average, do the appropriate action, then start again. Sounds like three things do do inside the loop() part of your sketch.

void loop()
{
     // Take samples

     // Calculate average

     // Take action
}

giovanniguerra:
So take as many samples as you can (over the time you want?), calculate the average, do the appropriate action, then start again. Sounds like three things do do inside the loop() part of your sketch.

void loop()

{
    // Take samples

// Calculate average

// Take action
}

I understand the basic structure of what I'm gonna need to do. The question is the coding. I have a general understanding of how the array functions in a moving average, the question though is how do I get it to stop taking new values after completing the full array, spit out the average, and then start all over again?

For ride height, what you want is not an average, but a low-pass filtered signal. High frequency noise (i.e. - bumps) should not affect ride height, but lower frequency inputs (i.e. - cornering, accelerating, braking, etc.) should affect ride height. One or two series-connected simple IIR digital low-pass filters with suitable time-constants should give you exactly what you need.

Regards,
Ray L.

I can't seem to retool the example "Smoothing" sketch for my purposes, it keeps bugging out on me. If the sensor stays at either extreme for too long, the whole function just spazzes out and spikes a huge positive or negative value, and since it's a moving average, it takes ages to return to the proper range. I'm not sure why this is.

If anyone has a simple, no-frills, NON-moving average/median/low-pass-filter/etc program that would be very much appreciated.

We are assuming that the car is motion, and thus, that there is noise in the height sensor's readings. I already have the programming for an instant adjustment mode when the car is stationary, which will do the majority of the work at getting the car to the right height.

This part of the program I need averaging for is essentially just a safeguard; the ride height should actually not vary much after it has been trimmed properly when the car first started up. But in the case that there IS gradual change in the ride height, over a particularly long drive, I don't want to have to stop the car and reset the Arduino to get the module to retrim.

This is why I need averaging. I want the program to monitor and record values from the height sensor once or twice a second for 1-3 minutes and store them in an array to be calculated into a mean when the array is full, and after this, I want the array to zero itself out and start recording brand new values.

At the end of each of these data collection cycles, it calculates the average, and tests it to see if the car is riding in the right range, or is too high/low. It either does nothing, or takes one of two actions to attempt to correct the height, and then waits for the next average to come in a few minutes later.

It's basically just there to periodically check in and make sure everything is normal.

Hopefully the context makes it a little more clear what my problem is.

No need for a buffer if you just need the average in every loop:

void setup() {
  // put your setup code here, to run once:

}

#define NUM_SAMPLES 200


void loop() {
  // put your main code here, to run repeatedly:

  float Sum = 0 ;
  for (int i = 0 ; i < NUM_SAMPLES ; i++) {
    float Sample = analogRead(A0) ; // This is an example
    Sum = Sum + Sample ;
  }

  float Avg = Sum/NUM_SAMPLES ;

  // do something different according to what Avg is...


}

You’ll have to change things for your own requirements, but you get the idea…

giovanniguerra:
You’ll have to change things for your own requirements, but you get the idea…

Thanks so much! I modified it for my specific needs, but it works exactly as I needed. I think I have my full program running properly now.