Triple Axis Accelerometer MMA7361 (How do I convert ADC values to Gs?)

I am having problems trying to convert the ADC value that the Arduino Uno reads from the x, y, and z outputs from the MMA7361 Triple Axis Accelerometer to Gs. I don’t really understand what these output readings (ADC values) mean and why they are in that particular scale.

I put the photos of the circuit setup I have. I followed the suggested layout from the data sheet, and I am positive my setup is right. Anyway, the link to the datasheet is this:

Also, I put a picture of the serial monitor readings. The readings correspond to the Accelerometer when it is lying flat on a surface and it’s stationary. By the way, the g-Select setting is at 1.5g.


(Btw in this picture the g-range is set at 6g – the second pin from top to bottom is connected to power)


(Note that the g-Select pin is now disconnected – 1.5g range is enabled.)


(Analog outputs for x, y, and z pins)

Also, here's the code I am using:

int valX = 0;
 int valY = 0;
 int valZ = 0;
 
 void setup()
 {
 Serial.begin(9600);
 }
 
 void loop() 
 {
 valX = analogRead(A2);
 valY = analogRead(A1);
 valZ = analogRead(A0);

 Serial.print("X=");
 Serial.print(valX);
 Serial.print("\t");
 Serial.print(" Y=");
 Serial.print(valY);
 Serial.print("\t");
 Serial.print(" Z=");
 Serial.print(valZ);
 Serial.print("\n");
 delay(500);
 }

At the position shown in the picture I took, the data sheet of the accelerometer indicates that the output pins of the accelerometer should have the following voltage readings.

Xout @ 0g = 1.65 V
Yout @ 0g = 1.65 V
Zout @ + 1g = 2.45 V

(This info is on page 6 in the data sheet for the top side view)

When I measured the outputs with a multimeter, I get the following results:
(Again, the g-Select setting is at 1.5g)

1.655 V for Xout
1.738 V for Yout
2.139 V for Zout

I thought this information might help, but I can’t really figure out or think of a way to take all this information and convert it to Gs.

I would really appreciate some help.
Thanks in advance.

I had a similar accelerometer, and here's how you do that:

first we need to convert the ADC units (quids I think) into a voltage:

(analogRead(accelAxsispin) - theADCvalueAtZero)*(Aref/1023)

the ADC zero value is an average value of the accelerometer axis at zero Gs
aref is the analog reference voltage, if your sensor is 3.3 volts, for greater resolution connect the 3.3v pin to the Areref pin and add analogReference(EXTERNAL); to the setup() function (if you don't add that line, the calculations will be wrong and the Arduino may be harmed). Aref is now 3.3 volts. If your sensor is 5v, or if you have another sensor that is 5v, don't do this, and Aref will be 5v
Then, take the amount of milivolts per g out of the datasheet, (its variable with the g select on this accelerometer) and divide the voltage by it.
final line of code should be something like this:

((analogRead(accelAxsispin) - theADCvalueAtZero)*(Aref/1023)/Gsens)

theory:
voltage = (ADCvalue - theADCvalueAtZero)*(Aref/1023)
gforce = voltage/sensitivity
then just repeat that for all axis.

my first forum post, so lemme know what you think

This is how it worked for me. The offset is 1/2 vcc and the sensitivity is 800mv/g for the 7361 so I changed the values in the code but left the comments for a different accelerometer.

/*  Accelerometer Test
    Written by Allen Lee (alee@sparke.ca)
    Uses the Lilypad Accelerometer (ADXL335)
    IMPORTANT:  SUPPLY THE ACCELEROMETER WITH VDD=3.3 V  JUMPER 3.3 V ON AN UNO TO AREF
    A good tutorial on accelerometers is on Instructables at: http://www.instructables.com/id/Accelerometer-Gyro-Tutorial
*/


// Setup global variables for analog read (x,y & z), voltages (vx,vy & vz) and g-readings (gx,gy & gz)
int x,y,z;
float vx, vy, vz, //gx, gy, gz;


void setup()
{
  Serial.begin(9600);
  analogReference(EXTERNAL);    //set aref to 3.3v, if you use built in 3.3v for value, use a 15K resistor to limit current
}


void loop()
{
  // Read in accelerometer values
  x = analogRead(A0);
  y = analogRead(A1);
  z = analogRead(A2);
  
  // Convert ADC values to voltages and G values
  // The formula for voltage conversion is v = (ADCREAD*VREF/1023)-ZGV, where ZGV is "Zero-G voltage" (voltage at 0G)
  // ZGV is found in the spec sheet and happens to be 1.5 in our case.  Warning: you need to make the variable signed!
  // The formula for G conversion is g = v/SENSITIVITY.  The sensitvity is also found in the spec sheet and happens to be 300 mV/g here.
  // Remember to make your units consistent! (g = v[V]*1000 / SEN [mV] )
  vx = (x*3.3/1023)-1.62;
 // gx = vx*10/8;
  vy = (y*3.3/1023)-1.62;
 // gy = vy*10/8;
  vz = (z*3.3/1023)-1.62;
//  gz = vz*10/8;
  
  Serial.print("vx=");
  Serial.print(vx,DEC);   // delet the dec?
  Serial.print("  ");
  Serial.print("vy=");
  Serial.print(vy,DEC);   //delete the dec?
  Serial.print("  ");
  Serial.print("vz=");
  Serial.println(vz,DEC);   //delete the dec?
  
  delay(50);
  
}

ImNotPedo,
I also found in the AnalogReference wiki that you need a 15K resistor on the Aref pin to limit current, it just senses the voltage.
TomJ

Figure 29-363 in the datasheet for the 328 family says the AREF input takes 140uA or so when the chip runs from 5V, so a 15k resistor would lead to 2.1V error. The datasheet also says if an external voltage reference is used the chip must be configured as analogReference(EXTERNAL).

Hello,

I finally got it to work. Young_Maker's code worked fine.

Also I just want to clarify that if you want to use 3.3V as the voltage reference and you are going to be providing that voltage from the 3.3V pin of the arduino, then you don't really need to add any resistors. You would only have to add another resistor if you were trying to get a different reference voltage.
This is because the AREF pin has a built-in resistor. This resistor is 32 Kilo-Ohms and it's set in the AREF pin such that it is connected between the AREF voltage reader and the ground. (In other words, inside the AREF pin you have: the AREF voltage reader, the 32K resistor, and then ground; connected in that order). So, when you connect another resistor to the AREF pin, you are creating a voltage divider. Therefore, you are lowering the voltage reading at the AREF voltage reader.

Here's the equation for the voltage divider that you would create by connecting a resistor to the AREF pin:

(V_out) = ( 32k / (R + 32k) ) * (V_in)

where V_out is the voltage being read by the AREF reader. So, if for some reason you needed a voltage reference equals to 2.2 V, you would need to used this equation to figure out the resistor that you need:

R = (32k) * ( ( V_in / V_out ) - 1)

where V_out is the desired reference voltage, in this case 2.2 V, and R is the value in Kilo-Ohms of the resistor that you will need to use in order to provide that voltage.

The library for the analogReference(type) on the Arduino.cc website was very confusing on this this. I had to do some research to figure this out.

Anyways, my accelerometer is working fine now. Thank you guys.
Btw, this was my first post in the forum too.

ImNotPedro.
You are certainly correct on that, when I revisited the reference page I saw that i had missed the word "Alternitvely". I had also forgotten that I had used a 1.5k resistor, not a 15k to get the voltage I wanted.
Thanks for the explanation.
TomJ