Hello all,
in a little test I found out that most of the libraries for the MMA7660 won't show correct values.
I am using the Arduino DUE and the MMA7660 vie I2C at 3,3V.
The problem is located in the calculation from the 6-bit result to the real g values.
On page 28 in the datasheet there is a table showing the relation of the values. For 6-bit results from 0 to 31 you can divide the 6-bit result by 21 to get an approximate result. But for the 6-bit results from 32 to 63 you first have to subtract 64 and then divide it by 21.
You can check it in the serial monitor, all 6-bit values greater than 31 should be shown as negative acceleration.
*************
x = 8
y = 63
z = 20
accleration of X/Y/Z:
0.38 g
3.00 g
0.95 g
*************
x = 7
y = 51
z = 17
accleration of X/Y/Z:
0.14 g
2.38 g
0.67 g
*************
x = 50
y = 57
z = 53
accleration of X/Y/Z:
2.38 g
2.71 g
2.52 g
*************
By using my correction it looks like this:
*************
x = 17
y = 63
z = 14
accleration of X/Y/Z:
0.86 g
-0.05 g
0.67 g
*************
x = 17
y = 54
z = 12
accleration of X/Y/Z:
0.86 g
-0.52 g
0.52 g
*************
x = 10
y = 47
z = 61
accleration of X/Y/Z:
0.48 g
-0.95 g
-0.14 g
*************
Simply change these lines in MMA7660.cpp
from
void MMA7660::getAcceleration(float *ax,float *ay,float *az)
{
int8_t x,y,z;
getXYZ(&x,&y,&z);
*ax = x/21.00;
*ay = y/21.00;
*az = z/21.00;
}
to
void MMA7660::getAcceleration(float *ax,float *ay,float *az)
{
int8_t x,y,z;
getXYZ(&x,&y,&z);
if (x >= 0 && x <= 31)
*ax = x / 21.0;
else
*ax = (x-64) / 21.0;
if (y >= 0 && y <= 31)
*ay = y / 21.0;
else
*ay = (y-64) / 21.0;
if (z >= 0 && z <= 31)
*az = z / 21.0;
else
*az = (z-64) / 21.0;
}