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:
#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.