Pages: [1]   Go Down
Author Topic: ARDUINO only detects FIRST interrupt from MMA7660 accelerometer  (Read 1131 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi guys,

I've been working with the MMA7660 from freesccale. I was able to read and write the registers. My goal is sleep the arduino and the wake it up when the MMA7660 detects tap or shake.
I wired the pin 5 from MMA7660 to ARDUINO's pin 2(INT0)
SET pin 2 as INPUT and write it HIGH to activate the internal pull-up

THE PROBLEM IS:
IF I attach the interrupt as FALLING or RISING arduino only wakes up once. (Only with the first interrupt).
IF I set it as LOW it wakes up with every interrupt but sometimes It wakes up twice with only one tap or shake.


here is my code:

Code:
#include <Wire.h>
#include <avr/sleep.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
#define   PDET        0x09
#define   INT0        2

boolean sleep = true;

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();
  pinMode(INT0 , INPUT); 
 
}

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

void loop()
{
  if(sleep)
  {
    sleepNow();
  }
  else
  {
    checkTILT();
  }
}

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

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

    SLAVE_I2C_SEND(INTSU,0x4E);
    delay(2);
   
    SLAVE_I2C_SEND(PDET,0x77); // TAP DETECTION ON Z-AXIS AND 11000 OUT OF 11111 OF SENSITIVITY
    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 ,0x41); //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
{
  int reg;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x00);  // register to read
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS,4); // read a byte

   while(Wire.available()){
    reg =Wire.receive();
   }
   
    Serial.print("Register 0x03 : ");
    //Serial.println(i, HEX);
    Serial.println(reg, HEX);
}

int getTilt() //READ TILT REGISTER
{
  int reg=0;
  Wire.beginTransmission(I2C_ADDRESS);
  Wire.send(0x00);  // register to read
  Wire.endTransmission();
  Wire.requestFrom(I2C_ADDRESS,4); // read a byte

   while(Wire.available()){
    reg =Wire.receive();
   }   
    return reg;
}

void wakeUp()
{
  sleep = false;
}

void checkTILT()
{
  Serial.println("JUST WOKE UP");
  int tilt;
  tilt = getTilt();
  Serial.println(tilt, HEX);
  delay(250);
  sleep = true;
}



void sleepNow()
{
  Serial.println("SLEEP MODE ENABLED");
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // sleep mode is set here
  sleep_enable();
 
  digitalWrite(INT0, HIGH);
  attachInterrupt(0,wakeUp, FALLING); // use interrupt 0 (pin 2) and run function
                                       // wakeUpNow when pin 2 gets LOW

    sleep_mode();            // here the device is actually put to sleep!!
                             // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP

    sleep_disable();         // first thing after waking from sleep:
                             // disable sleep...
    detachInterrupt(0);    // disables interrupt 0 on pin 2 so the
                             // wakeUpNow code will not be executed
                             // during normal running time.
 
}

As I mentioned before I have wired it directly like this:
ARDUINO PIN 2 <---------> PIN 5 MMA7660

Using arduino's internal pull-up resistor.
Logged

0
Offline Offline
Shannon Member
****
Karma: 221
Posts: 12710
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Have you read the MMA7660 datasheet fully?  It is quite likely that you have to clear the interrupt status before it will re-interrupt - that's the way most devices work.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes I read the document. Although there was a Note didn't understand:

Quote
The active interrupt condition is released during the acknowledge bit of the slave address
transmission of the first subsequent I2C to the device after the interrupt was asserted.
Logged

0
Offline Offline
Shannon Member
****
Karma: 221
Posts: 12710
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It means the interrupt isn't cleared unless you do an I2C interaction - so make the interrupt routine read the status register or something harmless like that - this is usual practice, many devices have an interrupt bit for each kind of interrupt in a status register.

The interrupt routine is supposed to read the interrupt status register to work out what kind of interrupt happened and thereby signal that the interrupt is being handled - this re-enables that specific interrupt.
Logged

[ I won't respond to messages, use the forum please ]

Pages: [1]   Go Up
Jump to: