MMA7660FC I2C accelerometer with Arduino

Hi,

I am new to I2C and am trying to interface MMA7660FC with Arduino. As I understand different I2C devices have different form of I2C read and write protocols. Could some one help me with the code.

MMA7660FC data sheet
http://cache.freescale.com/files/sensors/doc/fact_sheet/MMA7660FCFS.pdf

I am using wire.h .I am not able to implement the message protocol for read and write. Thanks in advance.

#include <Wire.h>

#define I2C_ADDRESS 0x4C
#define POWER_UP_DELAY 10


#define X_OUT 0x00
#define Y_OUT 0x01
#define Z_OUT 0x02



void setup()
{ 
  Serial.begin(38400);  // start serial for output
  setupacc();
  startacc();
}

void loop()
{
  char x = readRegister(X_OUT);
  char y = readRegister(Y_OUT);
  char z = readRegister(Z_OUT);
  char mode = readRegister(0x07);
  char tilt = readRegister(0x03);
  char sample = readRegister(0x04);
  char fac = readRegister(0x0B);
 
  Serial.print("X=");
  Serial.print(x, DEC);
  Serial.print(", Y=");
  Serial.print(y, DEC);
  Serial.print(", Z=");
  Serial.print(z, DEC);
  Serial.print(", Mode=");
  Serial.print(mode,DEC);
  Serial.print(", Tilt=");
  Serial.print(tilt,DEC);
  Serial.print(", sample=");
  Serial.print(sample,DEC);
  Serial.print(", fac=");
  Serial.print(fac,DEC);
  Serial.println(".");
 
 

  delay(100);
}

void setupacc()
{
 
  Serial.println("Setting up Acc");
 
 
 
  Wire.begin();       
 
}

void startacc()
{
 
  Serial.println("Powering up acc");
 

  delay(POWER_UP_DELAY);
 
// writing mode register of MMA7660 to active mode
  writeRegister(0x07,0x02);
  delay(100);

// setting SR register to 64 samples active and auto //sleep mode

  writeRegister(0x08,0x01);
  delay(100);
 
  //read who am i
  char myself = readRegister(0x07);
 
    Serial.print("found an ");
    Serial.print(myself, HEX);
   
}

void writeRegister(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);
  Wire.send(v);
  Wire.endTransmission();
}

unsigned char readRegister(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available())
  {
    // waiting
  }
  v = Wire.receive();
  return v;
}

The code is not working. I just get X, y, z and other registers as 0s. What could be the mistake?

Could some one please suggest a solution?

Hello
Also I'm trying to get MMA7660 working. did you managed to make it work? thank you. reha

Hello,
as far as I figure out that..

// writing mode register of MMA7660 to active mode
writeRegister(0x07,0x02);

is not correct. Because, Mode:02 is TEST mode. As described in document "MMA7660FC" page 17. So, correct one should be:

// writing mode register of MMA7660 to active mode
writeRegister(0x07,0x00);

In order to have module make the measurement. regards, reha

Sorry reha but you're wrong it must be
writeRegister(0x07,0x01);
Check the datasheet

If i'm reading it with this code X, Y and Z gives the same value.

Should you already have a working code?
I'm intrested in this project
I'm creating an autonome zeppelin.
And can use this project to run my system.

Please reply.

Hi all, im making a same project with that accelerometer and i think im having troubles with the init. Someone found a way to measure the X Y Z??

i wait your response :slight_smile:

thx :wink:

I updated the above code
I can measure the X-axis
But Y and Z are the same values

#include     <Wire.h>
#include     <stdio.h>
#include     "MMA7660FC.h"
//-------------------------------------------------------
#define      I2C_ADDRESS      0x4C
#define      POWER_UP_DELAY   10
//-------------------------------------------------------

void setup()
{
  Serial.begin(9600);  // start serial for output
  setupacc();
  startacc();
}


void loop()
{
  char x = readRegister(XOUT);
  Serial.print("X=");
  Serial.print(x, DEC);
  
  char y = readRegister(YOUT);
  Serial.print(", Y=");
  Serial.print(y, DEC);
  
  char z = readRegister(ZOUT);
  Serial.print(", Z=");
  Serial.println(z, DEC);
  
  delay(200);
}


void setupacc()
{
  Wire.begin();
}


void startacc()
{
  delay(POWER_UP_DELAY);

// writing mode register of MMA7660 to standby mode ==> possible to write to registers
  writeRegister(0x07,0x00);

// setting Sleep Count register
  writeRegister(0x05,0x00);
  
 // setting Interupt registers to 0
  writeRegister(0x06,0x00);
  
// setting SR register to 2 samples active
  writeRegister(0x08,0b00010100);
  
// setting Tap/Pulse Detection Register
  writeRegister(0x09,0x00);
  
// writing mode register of MMA7660 to active mode
  writeRegister(0x07,0x01);
  
}

void writeRegister(unsigned char r, unsigned char v)
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);
  Wire.send(v);
  Wire.endTransmission();
}

unsigned char readRegister(unsigned char r)
{
  unsigned char v;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(r);  // register to read
  Wire.endTransmission();

  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available())
  {
    // waiting
  }
  v = Wire.receive();
  return v;
}

Someone has a solution?

but this is a real measure on X? because what I'm seeing. I'm not sure writeRegister function is such as to this. Since I seem to be written simultaneously the option in the registration form

wire.send (r, v)

and not in the way

wire.send (r);
wire.send (v);

thx :slight_smile:
:wink:

Yes, it's purpose is to measure the angle in al 3axes

I just tried your "wire.send (r, v)" and it gives error's
I tried everything, even rebuilding a new sensor.
Same result. :frowning:

Now i'm using the following

void loop()
{
  char z;
  Serial.print("Z in Degrees: ");
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x02);   // * 0x02 is the Z register => Datasheet

  Wire.requestFrom(I2C_ADDRESS, 1);
  if (Wire.available()) {
    z = Wire.receive();
    Serial.println(z, DEC);
  }  
    Wire.endTransmission();
}

With this code i should get the Z value's but i get the X value's, AGAIN!

What am i doing wrong?

Recently came to my house, now I'm going to start experimenting and I will be posting what you execute.
With respect to wire.send (r, v), was only a proposal, I will review the wire.h library in search of a function that does that.

And I think what we're doing all wrong has to do with initialization.

Bye! :wink:

PS: If anyone is welcome to speak Spanish because I can not explain very well in English ..

try this code, and tell me if work

//SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5

#include <Wire.h>

#define I2C_ADDRESS 0x4C
#define I2C_ADDRESS_W 0x99 //MMA7660 Address + 1 bit (Write) pag. 21
#define I2C_ADDRESS_R 0x98 //MMA7660 Address + 0 bit (Read) pag 21
#define TILT_STATUS 0x03
#define SRST 0x04
#define SPCNT 0x05
#define INTSU 0x06
#define MODE 0x07
#define SR 0x08
#define PDET 0x09
#define PD 0x0A


#define POWER_UP_DELAY 10


#define X_OUT 0x00
#define Y_OUT 0x01
#define Z_OUT 0x02



void setup()
{
  Serial.begin(38400);  // start serial for output
  Serial.println("Setting up I2C protocol...");
  Wire.begin();
  SLAVE_I2C_INIT();
  pinMode(13, OUTPUT);
}

void loop()
{
  char x = SLAVE_I2C_READ(X_OUT);
  char y = SLAVE_I2C_READ(Y_OUT);
  char z = SLAVE_I2C_READ(Z_OUT);
  char mode = SLAVE_I2C_READ(0x07);
 // char tilt = SLAVE_I2C_READ(0x03);
  char sample = SLAVE_I2C_READ(0x04);
 // char fac = SLAVE_I2C_READ(0x0B);

  Serial.print("X=");
  Serial.print(x, DEC);
  Serial.print(", Y=");
  Serial.print(y, DEC);
  Serial.print(", Z=");
  Serial.print(z, DEC);
  Serial.print(", Mode=");
  Serial.print(mode,DEC);
  //Serial.print(", Tilt=");
 // Serial.print(tilt,DEC);
  Serial.print(", sample=");
  Serial.print(sample,DEC);
  //Serial.print(", fac=");
  //Serial.print(fac,DEC);
  Serial.println(".");
  delay(100);

}
void SLAVE_I2C_INIT()
{

  Serial.println("Powering up SLAVE interface...");
  delay(POWER_UP_DELAY);

  SLAVE_I2C_SEND(MODE,0x00); // Setting up MODE to Stand by to set SR
  delay(100);
  
  SLAVE_I2C_SEND(SR,0x00);  // Setting up SR register to 120 samples active and auto sleep mode
  delay(100); 
   
  SLAVE_I2C_SEND(MODE,0x01); //Setting up MODE Active to START measures 
  delay(100);

 
}

void SLAVE_I2C_SEND(unsigned char REG_ADDRESS, unsigned  char DATA)  //SEND data to MMA7660
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.send(DATA);
  Wire.endTransmission();
}

unsigned char SLAVE_I2C_READ(unsigned char REG_ADDRESS) //READ MMA7660 data
{
  unsigned char R_VALUE;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(REG_ADDRESS);  // register to read
  Wire.endTransmission();
  
  Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
  while(!Wire.available())
  {
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(100);
  }
  
  R_VALUE = Wire.receive();
  return R_VALUE;
}

I'm testing the code that I posted above, and I get the same problem to you, I get the same value for X, Y, Z. As I reached the conclusion that we are misreading the data from the MMA7660.

Now I will keep experimenting, and posting my results

:wink:

http://www.datasheets.org.uk/pdf/getfile.php?dir=Datasheet-076&file=DSAE0033553.pdf&scan=n

I found this,
I will test this tutorial today
Maybe it can help you to as well.

Grtz

if you get it to work with the information that is in the datasheet. I ask you to please post and did it because i can't read very well the information received of the MMA7660.

Thanks

Tried today

No succes

Tommorow another day. :smiley:

Grtz

Hi friend, I mention that after so much experience, manages to walk the MMA7660. Found in the datasheet a section which says that to give the first reading the other direction gives them to you automatically to a log autoincrement function (it is explained on page 22 of datasheet).

And that was the key to make it work!

No more here that I leave the code used to read X, Y, Z.

Thanks

Tell me any questions ...

//SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5

#include <Wire.h>

#define I2C_ADDRESS 0x4C
#define TILT_STATUS 0x03
#define SRST 0x04
#define SPCNT 0x05
#define INTSU 0x06
#define MODE 0x07
#define SR 0x08
#define PDET 0x09
#define PD 0x0A


#define POWER_UP_DELAY 10


#define X_OUT 0x00
#define Y_OUT 0x01
#define Z_OUT 0x02



void setup()
{
  Wire.begin();
  Serial.begin(38400);  // start serial for output
  Serial.println("Setting up I2C protocol..."); 
  Serial.println("Powering up SLAVE interface...");
  SLAVE_I2C_INIT(); 
  pinMode(13, OUTPUT);

}

void loop()
{

SLAVE_I2C_READ();

}
void SLAVE_I2C_INIT()
{

 

    SLAVE_I2C_SEND(0x07,0x00); // Setting up MODE to Stand by to set SR
    delay(2);
    
    SLAVE_I2C_SEND(0x06,0x10);
    delay(2);
    
    SLAVE_I2C_SEND(0x08,0x00);  // Setting up SR register to 120 samples active and auto sleep mode
    delay(2); 
 
    SLAVE_I2C_SEND(0x07,0x01); //Setting up MODE Active to START measures 

 
}

void SLAVE_I2C_SEND(unsigned char REG_ADDRESS, unsigned  char DATA)  //SEND data to MMA7660
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.send(DATA);
  Wire.endTransmission();
}

void SLAVE_I2C_READ() //READ MMA7660 data
{
  unsigned char REG_ADDRESS[3];
  int i=0;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x00);  // register to read
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
  
  for(i=0; i<3; i++){
   if(Wire.available())REG_ADDRESS[i]=Wire.receive();
  }
  for(i=0; i<3; i++){
    Serial.print("  || 0x0");
    Serial.print(i);
    Serial.print(":");
    Serial.print(REG_ADDRESS[i], DEC);
    Serial.print("  ||");
    
  }
  Serial.println("");
  delay(100);
}

PD: Sorry my english!

Yeah, great.
Finnaly, that was indeed the key.

Thx Emma, i owe you one!

Question: Why " pinMode(13, OUTPUT); " ?

I editted the code a bit.
Now he brings out the value in degrees.

#include <Wire.h>

#define   I2C_ADDRESS 0x4C
#define   X_OUT       0x00
#define   Y_OUT       0x01
#define   Z_OUT       0x02
#define   INTSU       0x06
#define   MODE        0x07
#define   SR          0x08

void setup()
{
  Wire.begin();
  Serial.begin(9600);  // start serial for output
  Serial.println("Setting up I2C protocol...");
  Serial.println("Powering up SLAVE interface...");
  SLAVE_I2C_INIT();
}

//------------------------------------------------------------------

void loop()
{
SLAVE_I2C_READ();
}

//------------------------------------------------------------------

void SLAVE_I2C_INIT()
{
    SLAVE_I2C_SEND(MODE ,0x00); // Setting up MODE to Stand by to set SR
    delay(2);

    SLAVE_I2C_SEND(INTSU,0x10);
    delay(2);

    SLAVE_I2C_SEND(SR   ,0x00);  // Setting up SR register to 120 samples active and auto sleep mode
    delay(2);

    SLAVE_I2C_SEND(MODE ,0x01); //Setting up MODE Active to START measures
}

//------------------------------------------------------------------

void SLAVE_I2C_SEND(unsigned char REG_ADDRESS, unsigned  char DATA)  //SEND data to MMA7660
{
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(REG_ADDRESS);
  Wire.send(DATA);
  Wire.endTransmission();
}

//------------------------------------------------------------------

void SLAVE_I2C_READ() //READ MMA7660 data
{
  unsigned char REG_ADDRESS[3];
  int i=0;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x00);  // register to read
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS, 3); // read a byte

  for(i=0; i<3; i++)
  {
   if(Wire.available())REG_ADDRESS[i]=Wire.receive();
  }
  for(i=0; i<3; i++){
    switch (i) 
     {
      case 0: { Serial.print("     X-as = ");  
       char x = REG_ADDRESS[i];
        switch (x)
        {
          case 0:  Serial.print("  0.00 'C"); break;
          case 1:  Serial.print("  2.69 'C"); break;
          case 2:  Serial.print("  5.38 'C"); break;
          case 3:  Serial.print("  8.08 'C"); break;
          case 4:  Serial.print(" 10.81 'C"); break;
          case 5:  Serial.print(" 13.55 'C"); break;
          case 6:  Serial.print(" 16.33 'C"); break;
          case 7:  Serial.print(" 19.16 'C"); break;
          case 8:  Serial.print(" 22.02 'C"); break;
          case 9:  Serial.print(" 24.95 'C"); break;
          case 10: Serial.print(" 27.95 'C"); break;
          case 11: Serial.print(" 31.04 'C"); break;
          case 12: Serial.print(" 34.23 'C"); break;
          case 13: Serial.print(" 37.54 'C"); break;
          case 14: Serial.print(" 41.01 'C"); break;
          case 15: Serial.print(" 44.68 'C"); break;
          case 16: Serial.print(" 48.59 'C"); break;
          case 17: Serial.print(" 52.83 'C"); break;
          case 18: Serial.print(" 57.54 'C"); break;
          case 19: Serial.print(" 62.95 'C"); break;
          case 20: Serial.print(" 69.64 'C"); break;
          case 21: Serial.print(" 79.86 'C"); break;
          default: Serial.print("   ---   "); break;
          case 43: Serial.print("-79.86 'C"); break;
          case 44: Serial.print("-69.64 'C"); break;
          case 45: Serial.print("-62.95 'C"); break;
          case 46: Serial.print("-57.54 'C"); break;
          case 47: Serial.print("-52.83 'C"); break;
          case 48: Serial.print("-48.59 'C"); break;
          case 49: Serial.print("-44.68 'C"); break;
          case 50: Serial.print("-41.01 'C"); break;
          case 51: Serial.print("-37.54 'C"); break;
          case 52: Serial.print("-34.23 'C"); break;
          case 53: Serial.print("-31.04 'C"); break;
          case 54: Serial.print("-27.95 'C"); break;
          case 55: Serial.print("-24.95 'C"); break;
          case 56: Serial.print("-22.02 'C"); break;
          case 57: Serial.print("-19.16 'C"); break;
          case 58: Serial.print("-16.33 'C"); break;
          case 59: Serial.print("-13.55 'C"); break;
          case 60: Serial.print("-10.81 'C"); break;
          case 61: Serial.print("- 8.08 'C"); break;
          case 62: Serial.print("- 5.38 'C"); break;
          case 63: Serial.print("- 2.69 'C"); break;
        }
      break;
      }
      case 1: { Serial.print("     Y-as = ");  
       char y = REG_ADDRESS[i];
        switch (y)
        {
          case 0:  Serial.print("  0.00 'C"); break;
          case 1:  Serial.print("  2.69 'C"); break;
          case 2:  Serial.print("  5.38 'C"); break;
          case 3:  Serial.print("  8.08 'C"); break;
          case 4:  Serial.print(" 10.81 'C"); break;
          case 5:  Serial.print(" 13.55 'C"); break;
          case 6:  Serial.print(" 16.33 'C"); break;
          case 7:  Serial.print(" 19.16 'C"); break;
          case 8:  Serial.print(" 22.02 'C"); break;
          case 9:  Serial.print(" 24.95 'C"); break;
          case 10: Serial.print(" 27.95 'C"); break;
          case 11: Serial.print(" 31.04 'C"); break;
          case 12: Serial.print(" 34.23 'C"); break;
          case 13: Serial.print(" 37.54 'C"); break;
          case 14: Serial.print(" 41.01 'C"); break;
          case 15: Serial.print(" 44.68 'C"); break;
          case 16: Serial.print(" 48.59 'C"); break;
          case 17: Serial.print(" 52.83 'C"); break;
          case 18: Serial.print(" 57.54 'C"); break;
          case 19: Serial.print(" 62.95 'C"); break;
          case 20: Serial.print(" 69.64 'C"); break;
          case 21: Serial.print(" 79.86 'C"); break;
          default: Serial.print("   ---   "); break;
          case 43: Serial.print("-79.86 'C"); break;
          case 44: Serial.print("-69.64 'C"); break;
          case 45: Serial.print("-62.95 'C"); break;
          case 46: Serial.print("-57.54 'C"); break;
          case 47: Serial.print("-52.83 'C"); break;
          case 48: Serial.print("-48.59 'C"); break;
          case 49: Serial.print("-44.68 'C"); break;
          case 50: Serial.print("-41.01 'C"); break;
          case 51: Serial.print("-37.54 'C"); break;
          case 52: Serial.print("-34.23 'C"); break;
          case 53: Serial.print("-31.04 'C"); break;
          case 54: Serial.print("-27.95 'C"); break;
          case 55: Serial.print("-24.95 'C"); break;
          case 56: Serial.print("-22.02 'C"); break;
          case 57: Serial.print("-19.16 'C"); break;
          case 58: Serial.print("-16.33 'C"); break;
          case 59: Serial.print("-13.55 'C"); break;
          case 60: Serial.print("-10.81 'C"); break;
          case 61: Serial.print("- 8.08 'C"); break;
          case 62: Serial.print("- 5.38 'C"); break;
          case 63: Serial.print("- 2.69 'C"); break;
        }
      break;
      }
      case 2:   { Serial.print("     Z-as = ");  
       char x = REG_ADDRESS[i];
        switch (x)
        {
          case 0:  Serial.print(" 90.00 'C"); break;
          case 1:  Serial.print(" 87.31 'C"); break;
          case 2:  Serial.print(" 84.62 'C"); break;
          case 3:  Serial.print(" 81.92 'C"); break;
          case 4:  Serial.print(" 79.19 'C"); break;
          case 5:  Serial.print(" 76.45 'C"); break;
          case 6:  Serial.print(" 73.67 'C"); break;
          case 7:  Serial.print(" 70.84 'C"); break;
          case 8:  Serial.print(" 67.98 'C"); break;
          case 9:  Serial.print(" 65.05 'C"); break;
          case 10: Serial.print(" 62.05 'C"); break;
          case 11: Serial.print(" 58.96 'C"); break;
          case 12: Serial.print(" 55.77 'C"); break;
          case 13: Serial.print(" 52.46 'C"); break;
          case 14: Serial.print(" 48.99 'C"); break;
          case 15: Serial.print(" 45.32 'C"); break;
          case 16: Serial.print(" 41.41 'C"); break;
          case 17: Serial.print(" 37.17 'C"); break;
          case 18: Serial.print(" 32.46 'C"); break;
          case 19: Serial.print(" 27.05 'C"); break;
          case 20: Serial.print(" 20.36 'C"); break;
          case 21: Serial.print(" 10.14 'C"); break;
          default: Serial.print("   ---   "); break;
          case 43: Serial.print("-87.31 'C"); break;
          case 44: Serial.print("-84.62 'C"); break;
          case 45: Serial.print("-81.92 'C"); break;
          case 46: Serial.print("-79.19 'C"); break;
          case 47: Serial.print("-76.45 'C"); break;
          case 48: Serial.print("-73.67 'C"); break;
          case 49: Serial.print("-70.84 'C"); break;
          case 50: Serial.print("-67.98 'C"); break;
          case 51: Serial.print("-65.05 'C"); break;
          case 52: Serial.print("-62.05 'C"); break;
          case 53: Serial.print("-58.96 'C"); break;
          case 54: Serial.print("-55.77 'C"); break;
          case 55: Serial.print("-52.46 'C"); break;
          case 56: Serial.print("-48.99 'C"); break;
          case 57: Serial.print("-45.32 'C"); break;
          case 58: Serial.print("-41.41 'C"); break;
          case 59: Serial.print("-37.17 'C"); break;
          case 60: Serial.print("-32.46 'C"); break;
          case 61: Serial.print("-27.05 'C"); break;
          case 62: Serial.print("-20.36 'C"); break;
          case 63: Serial.print("-10.14 'C"); break;
        }
      Serial.println("");
      delay(200);
      break;
      }
    }
  }
}

Maybe this can help you

Tubi ... as of pinMode (13, OUTPUT) is because I knew he had put a sign led by the pin 13 when he read the data, but then remove that piece of code and I'm the pin assignment.

PS: thx for the code but I'm making a smart glove dect my hand movements

Sorry my english!

Grtz