taking an average every 10 seconds of accelerometer magnitude

Hi, Im new to programming and for a project I need to take an average of the accelerometer magnitude every 10 seconds and record these values. below low is my code, is it possible to help with doing this?
My code is below.


int scale = 3;

void setup()
  // Initialize serial communication at 115200 baud
// Read, scale, and print accelerometer data, caculate acceleromteer magnatude, convert to m/s
void loop()
  // Get raw accelerometer data for each axis
  int rawX = analogRead(A0);
  int rawY = analogRead(A1);
  int rawZ = analogRead(A2);
  // Scale accelerometer ADC readings into common units
  // Scale map depends on if using a 5V or 3.3V microcontroller
  float scaledX, scaledY, scaledZ; // Scaled values for each axis
  scaledX = map(rawX, 0, 1023, -scale, scale); // 0 = 0 3.3 = 1023
  scaledY = map(rawY, 0, 1023, -scale, scale);
  scaledZ = map(rawZ, 0, 1023, -scale, scale);
  // Print out raw X,Y,Z accelerometer readings
  Serial.print("X: "); Serial.println(rawX);
  Serial.print("Y: "); Serial.println(rawY);
  Serial.print("Z: "); Serial.println(rawZ);
  // Print out scaled X,Y,Z accelerometer readings
  Serial.print("X: "); Serial.print(scaledX); Serial.println(" G");
  Serial.print("Y: "); Serial.print(scaledY); Serial.println(" G");
  Serial.print("Z: "); Serial.print(scaledZ); Serial.println(" G");
  delay(500); // Minimum delay of 2 milliseconds between sensor reads, current set at 500mS (500 Hz)
  //caculate the magnuitde of acceleration
 float mag = sqrt((scaledX * scaledX) + (scaledY * scaledY) + (scaledZ * scaledZ));
 //convert gs to m/s
 Serial.print("mag: ");Serial.println(" m/s");  


It is best to use millis() for timing, and avoid delay() as that blocks.

If you don't know how to do so, study the Blink Without Delay example, explained here.

BTW please post your best attempt at code. It should compile without errors (unless asking about an error message). Do you know how to calculate an average?

Are you wanting to average or filter the accelerometer readings? I think you will find filtering to be a better option.

There are several ways to filter the IMU data. If Using a Uno, I'd use a low pass complementary filter "arduino uno low pass complementary filter"; words you can use to search on.

I am wanting to take the average of the readings every 10 seconds. The reason is the device Im trying to build is to monitor sleep and the best way to determine the difference between awake and asleep is by movement and the movement is take ever 10 seconds. I have seen how to take the rolling average but being new to code I don't know how to change this into taking an average every 10 seconds from the data I have

First, write the code for calculating an average and get that working to your satisfaction.

Then, study the blink example, and learn how to make an LED blink every 10 seconds.

With that understanding, you will be ready to put the two concepts together.

This forum is for solving specific problems with project code, so post again when you have a specific question.

How fast per every 10 seconds will you be sampling your data?

Such as 100000 samples per 10 seconds or 1/2 sample over ten seconds?

Lets say you are going to sample one time a second from second 0 to 9.

So you'd take a reading and add the reading to a storage variable.

int qwer =0;

do ten times
qwer += reading
After ten times

qwer /= 10

The **Smoothing Example **shows you how to calculate a moving average (without the timing).

My World's Simplest Lighting Effect saves a reading once per second and saves it in 20 element array to get a 20 second moving average. It has a function called UpdateAverage() which is called from the main loop once per second (every 1000 milliseconds). If you understand how that works you should be able to write something similar for your application.

It's a sort-of a "dumb" averaging routine because the array is initialized with zeros and you don't get a valid average until the array is full (20 seconds in my case). If that's a problem in your application you'll need to make some changes.

Silver bullet approach?

If you know how many data readings you want to take an average of.. You could use a runningAvg object. Or in your case 3 of them. x,y & z.

create them.

runningAvg xSmoother(numReadings); // Total number of readings to average over.
runningAvg ySmoother(numReadings);
runningAvg zSmoother(numReadings);

Now when you take readings..

smoothedX = xSmoother.addData(scaledX); // Each time you read incoming data, drop it in here
smoothedY = ySmoother.addData(scaledY); // for a running average.
smoothedZ = zSmoother.addData(scaledZ);

And as your system runs you have smoothed x, y & z values to work with.

If you'd like to try this, open the library manager nd look for LC_baseTools. Its in that library.

-jim lee

I have seen how to take the rolling average but being new to code I don't know how to change this into taking an average every 10 seconds from the data I have

The average is just the reading you get from a rolling average that is configured to average over a period of 10 seconds. So there is nothing to change.