Using an MMA7361 to measure G forces

Hello,

I know that there are dozens of threads related to this accelerometer but all of the responses that I see talk about angles and inclinations.

I'm trying to measure the G forces in a car. It doesn't matter which direction, I just want to measure the maximum G forces applied for that instant.

I've tried mutiple snippets of code but nonw of them worked as expected.

My last attempt was made using this library:

http://code.google.com/p/mma7361-library/downloads/detail?name=AcceleroMMA7361_v0.8b.zip

But still couldn't get somewhere. I tried to use a function called getTotalVector () and use the difference between the actual and previous call to calculate the actual G forces but I don0t think it is working as expected :frowning:

This is how the accelerometer is connected to the arduino:

X -> A0
Y -> A1
z -> A2
GND -> GND
3.3 -> 3.3
SL -> 3.3

G0 is not used and so is the Sensitivity selector ( LOW = 1.5G ).

And this is the piece of code I'm trying to use (ignore some of the pins I'm passing in the begin function because, just as I told you before, I'm not using them even though I need to point them to initialize the library):

#include <AcceleroMMA7361.h>

AcceleroMMA7361 accelero;
int x;
int y;
int z;
double G;
int current=0;
void setup()
{
  Serial.begin(9600);
  accelero.begin(13, 12, 11, 10, A0, A1, A2);
  accelero.setARefVoltage(3.3);                   //sets the AREF voltage to 3.3V
  accelero.setSensitivity(HIGH);                   //sets the sensitivity to +/-6G
  accelero.setAveraging(100);
  accelero.calibrate();
}

void loop()
{
//  g = [mV/analogRead unit] * ([units] - ([Aref/2]) / [mvPerG]
 
 current = abs(current - accelero.getTotalVector());
 
 G = 3.22 * ((current - 3.3 / 2)  / 2450);
 

  x = accelero.getXAccel();
  y = accelero.getYAccel();
  z = accelero.getZAccel();
  
  Serial.print("\nx: ");
  Serial.print(x);
  Serial.print(" \ty: ");
  Serial.print(y);
  Serial.print(" \tz: ");
  Serial.print(z);
  Serial.print("\tG*10^-2");
  Serial.print( " -> " );
  Serial.print( G );
  
  delay(500);                                     //make it readable
}

The G formula was copied from another post in this forum and it is giving me the following results:

Calibrating MMA7361011..................................................
DONE
x: 0 y: -8 z: 101 G10^-2 -> 0.13
x: 0 y: -5 z: 97 G
10^-2 -> 0.01
x: 0 y: -6 z: 100 G10^-2 -> 0.11
x: 0 y: -4 z: 97 G
10^-2 -> 0.00
x: 1 y: -6 z: 100 G10^-2 -> 0.12
x: 0 y: -4 z: 97 G
10^-2 -> -0.00
x: 1 y: -8 z: 99 G10^-2 -> 0.12
x: -1 y: -5 z: 96 G
10^-2 -> 0.00
x: 1 y: -9 z: 99 G10^-2 -> 0.12
x: -3 y: -7 z: 98 G
10^-2

Then I flip the accelerometer, put it on a table without any movement and the last column gives-me high values:

x: 115 y: 592 z: 5 G10^-2 -> 0.34
x: 118 y: 600 z: 10 G
10^-2 -> 0.46
x: 107 y: 601 z: 7 G10^-2 -> 0.34
x: 103 y: 604 z: 8 G
10^-2 -> 0.46
x: 103 y: 606 z: 7 G10^-2 -> 0.34
x: 104 y: 609 z: 11 G
10^-2 -> 0.47
x: 105 y: 609 z: 8 G10^-2 -> 0.34
x: 105 y: 607 z: 10 G
10^-2 -> 0.47
x: 98 y: 610 z: 8 G10^-2 -> 0.33
x: 105 y: 615 z: 8 G
10^-2 -> 0.48
x: 95 y: 614 z: 9 G10^-2 -> 0.33
x: 96 y: 613 z: 8 G
10^-2 -> 0.47

Obviously I'm not calculating this correctly, the question is, how can I do it?

After 53 views no one knows the answer? :frowning:

Maybe I'm using the wrong sensor, and in that case, could someone point out the right direction?

Thanks!

Your code seems strange.

You need to read the analog voltage from each of the three directions. This gives
you a number between 0 and 1023.

You convert this to a voltage.

You convert this to a G reading according to the stated zero point and sensitivity of the device.

You then have a g force in each of the three directions of the device. You should see 1 g down,
which is gravity. You have to disregard this if you are calculating the acceleration of the car.

When the accelerometer is at rest, with the Z axis facing vertically, you should see 1G of acceleration along the Z-axis, and 0 along the X, Y axes. It looks like your scale is off by a factor of 100. If you divide the values from your first example by 100, your results will look as expected.

In your second example with the accelerometer flipped, something is wrong with your Y-Axis, the values are much to high and this is why your total G-force is high. Juding by the X-values, which are around 100, the X-axis is now facing vertically and is exhibiting 1G force due to gravity. Your Y and Z axes should be zero. The Z axis is more or less zero (remember to divide it by 100), but your Y-axis is showing around 6G. Not sure why that is happening, you will need to investigate.

Also, I am not sure what your purpose is for wanting the total G-force vector in a automotive application, but you may want to either ignore the Z-axis completely and use a 2-D XY axes vector, or remove the 1G of accleration always present due to gravity before you do your calculations.

Hope this helps.

Well thats right, in an automobile, if the accelerometer is fixed in a horizontal position, then you
would look at the x and y and ignore the z.

The problem with this approach though, it is when the car is flying through the air or rolling over,
you won't actually get a good reading for the acceleration from the x and y then.

The real problem here, is that all the actual calculations are buried those calls to functions of "accelero",
and we have no idea what they are. That code doesn't looks remotely like my implementations for that device.

Yes, what you probably would want to do is remove the forces of gravity from your calculations, which is difficult to do with only an accelerometer. It is easy when it is at rest with the Z-axis is vertical, because you can just subtract 1-G from the Z-axis, but as the accelerometer tilts, you would need to calculate the angle it is at a remove the components of the X,Y and Z axis that are due to gravity. It is difficult to use an accelerometer to calculate angle changes though in dynamic situations since the many of the accelerations registered by the accelerometer will be caused by vibrations and bumps and not just from the tilt of the sensor. Ideally you would want a gyro as well. With a gyro you can determine the orientation of the sensor by integrating the rotational velocity. Then you could use the orientation of the sensor to determine the components of your X,Y,Z axis that are caused by gravity and remove those effects before determining your total G-vector.

You might look into a sensor like the MPU-6050.

http://www.ecrater.com/p/15333005/arduino-mpu-6050-6dof-module-3-axis?gps=1

They are very cheap and combine an accelerometer and gyro on one chip. It comes with an onboard DMP (digital motion processor) that lets you make calls to it and it returns yaw/pitch/roll, and accelerations. It even has a function to return acceleration with the components of gravity already removed, so it would save you a lot of time. The DMP uses a fusion algorithm that combines the data of the gyro and accelerometer to determine these values, so it theoretically should be more accurate than using either of the sensors data individually to determine orientation and acceleration. I say theoretically, because the DMP is more or less a black box, and we can't see calculations done inside of it, so we have to trust the algorithm is accurate. I have used it and find it to be pretty accurate.

It is difficult to use an accelerometer to calculate angle changes though in dynamic situations since the many of the accelerations registered by the accelerometer will be caused by vibrations and bumps and not just from the tilt of the sensor.

It is not just the vibrations, bumps and sensor errors which are the problem. The actual change of direction of the vehicle ( whether it is a turning car or a turning airplane ) causes an actual acceleration which cannot be distinguished from gravity, and will lead your program to the wrong conclusion. That is unless you have some independent means of determining the actual orientation of the moving vehicle.

I have used it and find it to be pretty accurate.

It is fine if your vehicle has limited actual acceleration.

I suggest you try this. Put you MPU 6050 in a car, and drive rapidly in a circle as fast as you can.
If you are driving counterclockwise, the vehicle will be continuously accelerating to the left. The little
weights in the accelerometer will be pushed to the right, and you will get the apparently direction
of gravity there. See if you teapot stays upright, or not. It won't.

michinyon:

It is difficult to use an accelerometer to calculate angle changes though in dynamic situations since the many of the accelerations registered by the accelerometer will be caused by vibrations and bumps and not just from the tilt of the sensor.

It is not just the vibrations, bumps and sensor errors which are the problem. The actual change of direction of the vehicle ( whether it is a turning car or a turning airplane ) causes an actual acceleration which cannot be distinguished from gravity, and will lead your program to the wrong conclusion. That is unless you have some independent means of determining the actual orientation of the moving vehicle.

Yes, this is why I recommended using a gyro+accelerometer for orientation sensing.

michinyon:

I have used it and find it to be pretty accurate.

It is fine if your vehicle has limited actual acceleration.

I suggest you try this. Put you MPU 6050 in a car, and drive rapidly in a circle as fast as you can.
If you are driving counterclockwise, the vehicle will be continuously accelerating to the left. The little
weights in the accelerometer will be pushed to the right, and you will get the apparently direction
of gravity there. See if you teapot stays upright, or not. It won't.

It does, I am using an MPU-6050 and I attached an HMC5883L magnetometer to the auxiliary pins, and I am running a MARG orientation fusion algorithm that uses the data from the accelerometer + gyro + magnetometer.

I doubt that you have actually tested the response with sustained lateral acceleration. With magnetic
correction, you have two axes of alignment with which to correct the orientation drift. Even so,
you will get a consistent dipping effect if there is sustained lateral acceleration, because the orientation
plane formed by the magnetic field vector and the apparent "down" vector will become tilted.

Since most cars and aircraft do not perform tight continuous turning manoeuvres, this may be
a non-obvious problem.

Anyhow, to get back to the OP's problem. There seems to be clearly something wrong with the
OP's device, or the way that the information is being processed.

If the offset and scale of the different axes is out of spec, this can be corrected for provided you
know what the behavior is, and provided the device is still linear. At the moment, this is being
obscured by the processing using code which we can't see.

The next thing that I would suggest the OP do, is try to obtain the actual A/D values which are being
obtained from the device. Then, imagine the device is a cube, and turn the cube so that each of the
faces of the cube is facing upwards, and write down what the readings are. In other words, take
the readings with the flat side of the module up, and down. And the the short end pointing up, and then
down. And the the long edge of the module pointing up, and then down. It will then become more
clear what the problem is.

The other thing I would do, is try actually observing the voltages with a multimeter.

michinyon:
I doubt that you have actually tested the response with sustained lateral acceleration. With magnetic
correction, you have two axes of alignment with which to correct the orientation drift. Even so,
you will get a consistent dipping effect if there is sustained lateral acceleration, because the orientation
plane formed by the magnetic field vector and the apparent "down" vector will become tilted.

Since most cars and aircraft do not perform tight continuous turning manoeuvres, this may be
a non-obvious problem.

Anyhow, to get back to the OP's problem. There seems to be clearly something wrong with the
OP's device, or the way that the information is being processed.

If the offset and scale of the different axes is out of spec, this can be corrected for provided you
know what the behavior is, and provided the device is still linear. At the moment, this is being
obscured by the processing using code which we can't see.

The next thing that I would suggest the OP do, is try to obtain the actual A/D values which are being
obtained from the device. Then, imagine the device is a cube, and turn the cube so that each of the
faces of the cube is facing upwards, and write down what the readings are. In other words, take
the readings with the flat side of the module up, and down. And the the short end pointing up, and then
down. And the the long edge of the module pointing up, and then down. It will then become more
clear what the problem is.

The other thing I would do, is try actually observing the voltages with a multimeter.

That is true, I have not tested it for extended lateral accelerations, but I don't see that would be an issue. The magnetometer is 3-axis and the fusion algorithm is takes into account tilt compensation for the magnetometer. Right now I do experience some drift, but that is because I have not properly calibrated the sensors yet. I need to create a jig to constrain the X,Y,Z axis individually so I can rotate them individually through 360 degrees.