system
July 12, 2010, 8:01pm
1
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.
system
July 12, 2010, 9:05pm
2
#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?
system
July 13, 2010, 9:39am
3
Could some one please suggest a solution?
reha
August 21, 2010, 4:57pm
4
Hello
Also I'm trying to get MMA7660 working. did you managed to make it work? thank you. reha
reha
August 21, 2010, 8:09pm
5
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
system
November 25, 2010, 7:21pm
6
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.
emapign
November 25, 2010, 10:35pm
7
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
thx
system
November 25, 2010, 10:44pm
8
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?
emapign
November 25, 2010, 10:59pm
9
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
system
November 26, 2010, 12:46am
10
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.
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?
emapign
November 26, 2010, 1:01am
11
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!
PS: If anyone is welcome to speak Spanish because I can not explain very well in English ..
emapign
November 26, 2010, 2:38am
12
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;
}
emapign
November 26, 2010, 4:35pm
13
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
system
November 29, 2010, 7:59am
14
emapign
November 29, 2010, 6:03pm
15
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
emapign
November 30, 2010, 8:12pm
17
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!
system
December 1, 2010, 9:17am
18
Yeah, great.
Finnaly, that was indeed the key.
Thx Emma, i owe you one!
Question: Why " pinMode(13, OUTPUT); " ?
system
December 1, 2010, 10:24am
19
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
emapign
December 2, 2010, 9:05am
20
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