MMA7260 3axis accelerometer

I have the sparkfun breakout board for the subject accelerometer. I've tried all the various code bits I can find, and frankly am not sure that the darn thing is even working (first time with this). On my arduino mega I have (Pins are as silkscrened on the mega) VCC to the 3V3 pin on the Mega GND to the Mega GND pin g1 Digital Pin 52(Set to high with digital write) g2 Digitla Pin 53 (set to high with digital write) Sleep to Digital 51 (set high) X analog Pin 0 Y analog Pin 1 Z analog Pin 2

I have a very simple sketch which loops reading the inputs, and prints them to the serial monitor. I'm getting values like x=327 y=333 z=338 with the device resting. They vary slightly by one or 2 on each, but are pretty consistent.

Moving the board around does give some changes in the values.

Is the device working. How do I convert the read values to G's (or even angle for that matter.

This is my code

int xpin = 0; // x-axis of the accelerometer int ypin = 1; // y-axis int zpin = 2; // z-axis (only on 3-axis models) int g1 = 52; int g2 = 53; int slp = 51; int xinit,yinit,zinit; void setup() { Serial.begin(9600);

// Provide ground and power by using the analog inputs as normal // digital pins. This makes it possible to directly connect the // breakout board to the Arduino. If you use the normal 5V and // GND pins on the Arduino, you can remove these lines.

Serial.println("enter 0 for write, any other for read"); while (!Serial.available()); int inByte = Serial.read();

pinMode(g1, OUTPUT); pinMode(g2, OUTPUT); pinMode(slp,OUTPUT); pinMode(xpin,INPUT); pinMode(ypin,INPUT); pinMode(zpin,INPUT);

digitalWrite(g1, HIGH); digitalWrite(g2, HIGH); digitalWrite(slp, HIGH);

xinit=analogRead(xpin); yinit=analogRead(ypin); zinit=analogRead(zpin); Serial.println("Initial Values"); Serial.print(xinit);Serial.print(" "); Serial.print(yinit);Serial.print(" "); Serial.print(zinit);Serial.print(" "); Serial.println(); Serial.println("Measured"); Serial.flush(); while (!Serial.available()){;} }

void loop() {

int x,y,z;

x = analogRead(xpin); y = analogRead(ypin); z = analogRead(zpin);

if ( (x != xinit) || (y != yinit) || (z != zinit)){ Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.print(z); Serial.println(); xinit=x; yinit=y; zinit=z; } else { Serial.println("Skipping"); } //Serial.flush(); //while (!Serial.available()); // delay(1); }

g1 Digital Pin 52(Set to high with digital write) g2 Digitla Pin 53 (set to high with digital write)

I'd begin with these set to 0 for maximum sensitivity (1.5g, or 0.8V/g).

I have a very simple sketch which loops reading the inputs, and prints them to the serial monitor. I'm getting values like x=327 y=333 z=338 with the device resting. They vary slightly by one or 2 on each, but are pretty consistent.

That's good. At rest, the output voltage should be about half the supply, or 1.65V. Referenced to the 5V analog reference voltage of the arduino I would expect a reading of 1.65/5 * 1024 ==> 338. So far so good.

Now at your sensitivity setting (both G1 and G2 high) the change is 200mV/g. The Z-axis is feeling the force of gravity thus we would expect this to be higher (or lower) by 0.2V from the center 1.65V value. This gives a reading of either 1.85/5*1024==>379 or 1.45/5*1024==>297, depending on which way is "up".

Now that's a bit of a concern because none of your values are 379/297. The Z axis reading should be this different from the rest when it's just sitting on your desk.

A good way to test it, then, is to put the accelerometer in different orientations (portrait, landscape, upside down, etc.) and have the gravity acceleration vector affect the three axes in sequence.

-- Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html

Thanks. Would the ref voltage not.be 3.3 since that is the input voltage

The reference voltage is determined by the Arduino. The default is the Arduino’s supply voltage, or 5V. You can apply 3.3V to the AREF pin and reconfigure the A/D converter to use this, but this is potentially dangerous as misconfiguration can damage your 3.3V supply.


Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html

thanks. So that means its referenced to the Arduino, not the voltage into the sensor.. that makes sense

Sorry for all the bonehead questions. I changed the sensitivity to 1.5G (0,0 on the G1/G2 pins). Measuring Static. With the device “level” on a bench, X=274,y=297,z=528. Since its static, Z should be measuring 1G.

If I do the math. Converting the measurement to V should be 5*(528/1024) = 2.573V Which is 2573MV Divide that by sensitivity of 800MV/G gives me 3.2G which seems to be incorrect

So clearly my math is wrong.

If I turn the unit over (negative 1G), I get a calculated value of 1.19G which is probably close due to tollerances

Same thing for the X axis. If I stand the board so the arrow for X points down. I should get 1G measured. The value there is 441

V=5*(441/1024) gives me 2.15V, which converts to 2.69G

I’m wondering if I have to calibrate the device somehow

At 800mV/G 1G should be an additional 164 from the center value of 1.65

If I do the math. Converting the measurement to V should be 5*(528/1024) = 2.573V Which is 2573MV Divide that by sensitivity of 800MV/G gives me 3.2G which seems to be incorrect

You forgot to subtract out the 0g reference which is 1.65V (approximately...should be 3.3V/2). This allows for both positive g's (above 1.65V) and negative g's (below 1.65V).

So the math should be 2.573V - 1.65V -->0.923V / 0.8V/g --> 1.15g. Much more reasonable.

See if that reasoning makes the remaining numbers reasonable.

-- Check out our new shield: http://www.ruggedcircuits.com/html/gadget_shield.html

yep.. that makes sense and the values seem correct.

now to write a log to a file on the ST card and see what I get.

Hey,

I tried the same sketch as you, cause I also have some problems with my MMA7260. Now after printing 'Measured', nothing happens. Which means that my serial is not available? How to solve this?

Thx

The MMA7260 is connected the right way.. I don't think the accelerometer is fried, cause it is the first time I'm using it since I've ordered it.

Can someone help?

I gave up on the MMA7260 and am using the ADXL320 (yes its only 2 axis, but for what I'm doing 2 is fine for now).

Here you can see my Sketch, with an auto configuration section at first.

You can check updates or MMA7260 in my blog: La navaja del Geek: Midiendo las inclinaciones con el MMA7260 (in spanish but easy to follow and i can reply in english)

In rest you can see de g-force near 1 with good results!!! In the configuration step keep the accelerometer quiet in horizontal position

x,y,z
-0.03 0.05 1.05
-0.05 0.06 1.06
-0.04 0.01 1.06
-0.07 0.09 1.04
-0.04 0.06 1.06
-0.08 0.09 1.05

the code here


#define DEBUGMODE

const float RESOLUTION=800; //0.8 v/g → resolucion de 1.5g → 800mV/g
const float VOLTAGE=3.3; //voltage al que está conectado el acelerómetro

const float ZOUT1G = 2450; // mv Voltage en Zout a 1G
const float ZOUT0G = 1650; // mv Voltage en Zout a 1G
const float ZOUT_1G = 850; // mv Voltage en Zout a 1G

const float XOUT1G = 2450; // mv Voltage en Zout a 1G
const float XOUT0G = 1650; // mv Voltage en Zout a 1G

const float YOUT1G = 2450; // mv Voltage en Zout a 1G
const float YOUT0G = 1650; // mv Voltage en Zout a 1G

const int NADJ = 50;

// Entradas analógicas donde van los sensores
const int xaxis = 0;
const int yaxis = 1;
const int zaxis = 2;

// Salida digital del led de la placa
const int LEDPIN = 13;

float XError,YError,ZError;
float zero_g_reference, ZRes, XRes, YRes;
float xd,yd,zd,z,x,y;

float AccelAdjust(int axis)
{
float acc = 0,lectura = 0;
int j;

for (j=0;j<NADJ;j++)
{
lectura=analogRead(axis);
acc = acc + ((lectura*5000)/1024.0);
delay(11); //número primo para evitar ciclos de lectura
}

return acc/NADJ;
}

void setup()
{
Serial.begin(9600); // 9600 bps
pinMode(xaxis,INPUT);
pinMode(yaxis,INPUT);
pinMode(zaxis,INPUT);
pinMode(LEDPIN, OUTPUT);

digitalWrite(LEDPIN, HIGH);
XError = AccelAdjust(xaxis);
YError = AccelAdjust(yaxis);
ZError = AccelAdjust(zaxis);
ZError = ZError - ZOUT_1G;
digitalWrite(LEDPIN, LOW);

#ifdef DEBUGMODE
Serial.println(“Ajustado acelerometro eje X”);
Serial.print("Error de X= ");
Serial.println(XError);

Serial.println(“Ajustado acelerometro eje Y”);
Serial.print("Error de Y= ");
Serial.println(YError);

Serial.println(“Ajustado acelerometro eje Z”);
Serial.print("Error de Z= ");
Serial.println(ZError);
#endif
}

void loop()
{
x=analogRead(xaxis);
y=analogRead(yaxis);
z=analogRead(zaxis);

float aax = (((x5000.0)/1024.0)-XError)/RESOLUTION;
float aay = (((y
5000.0)/1024.0)-YError)/RESOLUTION;
float aaz = (((z*5000.0)/1024.0)-ZError)/RESOLUTION;

Serial.print(aax);
Serial.print(" “);
Serial.print(aay);
Serial.print(” ");
Serial.print(aaz);
Serial.println();

delay(500);
}