Hey Tomas,
Thank you very much for the code. I was trying a few things in the mean time but couldn't make it working for Arduino.
I can see the INC_SOURCE is cleared after reading TRANS_SOURCE. Still the interrupt holds high after the first one is fired.
I'm sending out the whole code here. Can you please have a look at it?
//------------------------------------------------------------------------------------------------------------------------------------------------//
#include <boards.h>
#include <SPI.h>
#include <Wire.h>
#include <services.h>
/*==============================================================================
* MACROS
*============================================================================*/
// Bit-wise macros
#define SETBIT(x,y) (x |= (y)) //Set bit y in byte x
#define CLEARBIT(x,y) (x &= (~y)) //Clear bit Y in byte x
#define CHECKBIT(x,y) (x & (y)) //True if bit y of byte x=1.
/*==============================================================================
* ACCELEROMETER GLOBAL VARIABLES + CONSTANTS
*============================================================================*/
// The SparkFun breakout board defaults to 1, set to 0 if SA0 jumper on the bottom of the board is set
#define MMA8452_ADDRESS 0x1D // 0x1D if SA0 is high, 0x1C if low
// Define a few of the registers that we will be accessing on the MMA8452
#define OUT_X_MSB 0x01
#define XYZ_DATA_CFG 0x0E
#define WHO_AM_I 0x0D
// Control registers
#define CTRL_REG1 0x2A
#define CTRL_REG2 0x2B
#define CTRL_REG3 0x2C
#define CTRL_REG4 0x2D
#define CTRL_REG5 0x2E
#define ASLP_COUNT 0x29
// Iniitial values of Control Registers
#define ASLP_12_5_HZ 0x40
#define ODR_50_HZ 0x20
#define LNOISE_DEFAULT 0x00
#define F_READ_DEFAULT 0x00
#define SLPE 0x04
#define SMODS_LOW_POW 0x18
#define MODS_NORMAL_POW 0x00
#define ST_DEFAULT 0x00
#define RST_DEFAULT 0x00
#define WAKE_FF_MT 0x08
#define WAKE_TRANS 0x40
#define IPOL_DEFAULT 0x00
#define PP_OD_DEFAULT 0x00
#define INT_EN_FF_MT 0x04
#define INT_EN_TRANS 0x20
#define INT_EN_ASLP 0x80
#define INT_CFG_FF_MT 0x04
#define INT_CFG_TRANS 0x20
#define ASLP_COUNT_50_HZ_960_MS 0x03
#define ELE 0x80
#define OAE_MOTION 0x40
#define XYZ_EFE 0x18
#define DBCNTM_MOTION 0x00
#define THS_0_2_G 0x0B
#define FF_MT_DEBOUNCE_50_HZ_20_MS 0x0A
#define ELE 0x10
#define XYZ_EFE 0x06
#define HPF_BYP 0x00
#define DBCNTM_TRANS 0x00
#define TRANS_THS_0_5_G 0x05
#define TRANS_DEBOUNCE_50_HZ_20_MS 0x03
//The SRC registers for clearing and reading status of interrupts
#define SYSMOD 0x0B
#define TRANSIENT_SRC 0x1E
#define FF_MT_SRC 0x16
// Motion Detection registers
#define FF_MT_CFG 0x15
#define FF_MT_SRC 0x16
#define FF_MT_THS 0x17
#define FF_MT_COUNT 0x18
//Transient registers
#define TRANSIENT_CFG 0x1D
#define TRANSIENT_THS 0x1F
#define TRANSIENT_COUNT 0x20
#define INT_SOURCE 0x0C
#define GSCALE 2 // Sets full-scale range to +/-2, 4, or 8g. Used to calc real g values.
/* Interrupt Status */
volatile unsigned int int_status1 = 0;
volatile unsigned int int_status2 = 0;
float threshX = 0.5;
float threshY = 0.3;
float threshZ = 0.5;
boolean accelConfgd = false;
boolean deviceSecurityEnabled = true;
int accelCount[3]; // Stores the 12-bit signed value
float initAccelG[3];
// Now we'll calculate the accleration value into actual g's
float accelG[3]; // Stores the real accel value in g's
int baudRate = 9600;
/*==============================================================================
* SETUP()
*============================================================================*/
// Interrupt Service Routines
void int0_bh()
{
int_status1 = 1;
}
void int1_bh()
{
int_status2 = 1;
}
void setup()
{
// Enable serial debug
Serial.begin(baudRate);
Wire.begin(); //Join the bus as a master
initMMA8452(); //Test and intialize the MMA8452
// Attach Interrupts for accelerometer
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
attachInterrupt(0, int0_bh, CHANGE);
attachInterrupt(1, int1_bh, CHANGE);
}
void readAndSaveAccelValues()
{
memset(accelCount,0,sizeof(accelCount));
readAccelData(accelCount); // Read the x/y/z adc values
for (int i = 0 ; i < 3 ; i++) {
accelG[i] = (float) accelCount[i] / ((1<<12)/(2*GSCALE)); // get actual g value, this depends on scale being set
}
}
void printAccelValues()
{
Serial.print(accelG[0]);
Serial.print('|');
Serial.print(accelG[1]);
Serial.print(':');
Serial.println(accelG[2]);
}
/*==============================================================================
* LOOP()
*============================================================================*/
void loop()
{
static byte val = 0;
static byte val1 = 0;
static byte val2 = 0;
if (int_status1 > 0) {
readRegisters(TRANSIENT_SRC, sizeof(byte), &val1);
readRegisters(INT_SOURCE, sizeof(byte), &val2);
Serial.print("TRANSIENT_SRC: ");
Serial.println(val1);
Serial.print("IIIIINT_SOURCE1: ");
Serial.println(val2);
readRegisters(CTRL_REG4, sizeof(byte), &val);
Serial.print("CTRL_REG4: ");
Serial.println(val);
readRegisters(CTRL_REG5, sizeof(byte), &val);
Serial.print("CTRL_REG5: ");
Serial.println(val);
readAndSaveAccelValues();
printAccelValues();
int_status1=0;
}
if (int_status2 > 0) {
readRegisters(SYSMOD, sizeof(byte), &val);
readRegisters(INT_SOURCE, sizeof(byte), &val);
Serial.print("SYSMOD: ");
Serial.println(val1);
Serial.print("IIIINT_SOURCE2: ");
Serial.println(val2);
int_status2=0;
}
delay(100);
}
/*==============================================================================
* ACCELEROMETER METHODS
*============================================================================*/
void readAccelData(int *destination)
{
byte rawData[6]; // x/y/z accel register data stored here
readRegisters(OUT_X_MSB, 6, rawData); // Read the six raw data registers into data array
// Loop to calculate 12-bit ADC and g value for each axis
for (int i = 0; i < 3 ; i++) {
int gCount = (rawData[i*2] << 8) | rawData[(i*2)+1]; //Combine the two 8 bit registers into one 12-bit number
gCount >>= 4; //The registers are left align, here we right align the 12-bit integer
// If the number is negative, we have to make it so manually (no 12-bit data type)
if (rawData[i*2] > 0x7F) {
gCount = ~gCount + 1;
gCount *= -1; // Transform into negative 2's complement #
}
destination[i] = gCount; //Record this gCount into the 3 int array
}
}
// Initialize the MMA8452 registers
// See the many application notes for more info on setting all of these registers:
// http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=MMA8452Q
void initMMA8452()
{
byte val = readRegister(WHO_AM_I); // Read WHO_AM_I register
if (val == 0x2A) // WHO_AM_I should always be 0x2A
{
Serial.println("M is online...");
}
else
{
Serial.print("Could not connect to MMA8452Q: 0x");
Serial.println(val, HEX);
while(1) ; // Loop forever if communication doesn't happen
}
MMA8452Standby(); // Must be in standby to change registers
// Initialize GSCALE
val = GSCALE;
if (val > 8) val = 8; //Easy error check
val >>= 2; // Neat trick, see page 22. 00 = 2G, 01 = 4A, 10 = 8G
writeRegister(XYZ_DATA_CFG, val);
val = (ASLP_12_5_HZ | ODR_50_HZ | LNOISE_DEFAULT | F_READ_DEFAULT);
writeRegister(CTRL_REG1, val);
val = (ST_DEFAULT | RST_DEFAULT | SMODS_LOW_POW | SLPE | MODS_NORMAL_POW);
writeRegister(CTRL_REG2, val);
val = (WAKE_TRANS | 0x02 | PP_OD_DEFAULT);
writeRegister(CTRL_REG3, val);
//interrupt INT TRANS comes on pin 2
val = 0; //INT_CFG_TRANS;
writeRegister(CTRL_REG5, val);
val = ASLP_COUNT_50_HZ_960_MS;
writeRegister(ASLP_COUNT, val);
val = (ELE | XYZ_EFE | HPF_BYP);
writeRegister(TRANSIENT_CFG, val);
val = 0; //(DBCNTM_TRANS | TRANS_THS_0_5_G);
writeRegister(TRANSIENT_THS, val);
val = 0; //TRANS_DEBOUNCE_50_HZ_20_MS;
writeRegister(TRANSIENT_COUNT, val);
val = (INT_EN_TRANS);
writeRegister(CTRL_REG4, val);
------------------------------------------------------------------------------------------------------------------------------------------------
MMA8452Active(); // Set to active to start reading
}
// Sets the MMA8452 to standby mode. It must be in standby to change most register settings
void MMA8452Standby()
{
byte c = readRegister(CTRL_REG1);
writeRegister(CTRL_REG1, c & ~(0x01)); //Clear the active bit to go into standby
}
// Sets the MMA8452 to active mode. Needs to be in this mode to output data
void MMA8452Active()
{
byte c = readRegister(CTRL_REG1);
writeRegister(CTRL_REG1, c | 0x01); //Set the active bit to begin detection
}
// Read bytesToRead sequentially, starting at addressToRead into the dest byte array
void readRegisters(byte addressToRead, int bytesToRead, byte * dest)
{
Wire.beginTransmission(MMA8452_ADDRESS);
Wire.write(addressToRead);
Wire.endTransmission(false); //endTransmission but keep the connection active
Wire.requestFrom(MMA8452_ADDRESS, bytesToRead); //Ask for bytes, once done, bus is released by default
while (Wire.available() < bytesToRead); //Hang out until we get the # of bytes we expect
for (int x = 0 ; x < bytesToRead ; x++) {
dest[x] = Wire.read();
}
Wire.endTransmission(true); //endTransmission but keep the connection active
}
// Read a single byte from addressToRead and return it as a byte
byte readRegister(byte addressToRead)
{
Wire.beginTransmission(MMA8452_ADDRESS);
Wire.write(addressToRead);
Wire.endTransmission(false); //endTransmission but keep the connection active
Wire.requestFrom(MMA8452_ADDRESS, 1); //Ask for 1 byte, once done, bus is released by default
while(!Wire.available()) ; //Wait for the data to come back
return Wire.read(); //Return this one byte
}
// Writes a single byte (dataToWrite) into addressToWrite
void writeRegister(byte addressToWrite, byte dataToWrite)
{
Wire.beginTransmission(MMA8452_ADDRESS);
Wire.write(addressToWrite);
Wire.write(dataToWrite);
Wire.endTransmission(); //Stop transmitting
}
//------------------------------------------------------------------------------------------------------------------------------------------------//
Thanks,
Sree