curtis63 5 Posted May 6, 2016 Share Posted May 6, 2016 I need to configure a MMA8653FCR1 accelerometer to cause an interrupt when a certain level of movement is detected. I was looking at the datasheet for it and there was a ton of minutia. Just wondering if somebody has already implemented a library for this device for use with Energia. If you know where I might find some source code for this, I'd greatly appreciate it. Before I get too many flames, I have searched google and the forums for this, but I am unable to find a satisfactory solution. Any assistance here would be greatly appreciated. Quote Link to post Share on other sites
chicken 630 Posted May 6, 2016 Share Posted May 6, 2016 The code presented here might work for Energia too: http://forum.arduino.cc/index.php?topic=227011.0 PS: Searching for Arduino and the IC (using the headline name/number from the datasheet, not the full part number) will typically find some code examples. Quote Link to post Share on other sites
Fmilburn 445 Posted May 6, 2016 Share Posted May 6, 2016 I agree with chicken's suggestion and have had pretty good luck porting Arduino code to Energia as long as there isn't extensive AVR specific code. Quote Link to post Share on other sites
chicken 630 Posted May 6, 2016 Share Posted May 6, 2016 Sorry, carefully reading your question might help me to actually answer it Looking at the datasheet of the MMA8653, I think the relevant chapters are 6.7 (freefall / motion detect registers) and 6.9.3 through 6.9.5 (CTRL_REG3-5, interrupt configuration registers). In the linked Arduino code, ctrl_reg3-5 are already available. Add values for the motion detect registers. int ff_mt_cfg = 0x15; // Freefall/motion configuration register int ff_mt_src = 0x16; // Freefall/motion source register int ff_mt_ths = 0x17; // Freefall/motion threshold register int ff_mt_count = 0x18; // Freefall/motion debounce register (Personally I'd use #define reg_name reg_address for this, but I will stick with the style of the Arduino code linked above) You can use the I2C_SEND function in the Arduino code to set the registers to the desired values. I'd expand on the example's ACC_INIT function. 1. Set the desired detection mode with the bits in FF_MT_CFG. Set bit 6 to 1 (OAE, detect mode, 0 = freefall, 1 = motion). Motion means, any axis measures above the threshold Set bits 3, 4, 5 to 1 for the axis you want to detect on (XEFE, YEFE, ZEFE, representing x, y, z respectively). Leave the other bits at 0. 0x78 looks like a reasonable value. You may need to exclude the axis of gravity when trying to detect motion < 1g. 2. Set the desired threshold at which motion is detected in FF_MT_THS Set this register to a value between 0 and 127, representing 0 to 8g. The register also has a flag (bit 7, DBCNTM) that determines how debouncing works. I think leaving it at 0 is fine. 0x20 would set about 2g as trigger level, be careful with values < 1g to avoid detecting gravity as motion. 3. Set how many samples are needed to trigger the motion detection in FF_MT_COUNT Set this register to a value between 0 and 255. The duration depends on the update rate (ODR), which the Arduino example set to 800Hz. So each sample represents a 1/800th of a second. I'd experiment with values around 10 and lower it when reaction is too sluggish or increase it if detection is triggered randomly. 0x0a represents a debounce counter value of 10. 4. Optional: Set the interrupt pin we want to wiggle in CTRL_REG5 Bit 2 controls the interrupt pin for motion detection, either INT1 (1) or INT2 (0). Default is INT2, so we only need to write to this register if we want to use the INT1 pin. 5. Optional: Set how the pin wiggles CTRL_REG3 Bit 1 (IPOL) selects, whether the pin goes high to low or low to high when an interrupt occurs. Default is going from high to low. You will also need to look into this register if you use the sleep modes of the accelerometer. 0x01 will make the interrupt pin go high when motion is detected 6. Enable interrupt from motion detection in CTRL_REG4 Bit 2 enables the freefall/motion interrupt. 0x02 will enable the interrupt. So in summary: I2C_SEND(ff_mt_cfg, 0x78); // motion detection, x, y, z I2C_SEND(ff_mt_ths, 0x20); // 2g I2C_SEND(ff_mt_count, 0x0a); // debounce over 10 readings I2C_SEND(ctrl_reg4, 0x02); // enable motion interrupt (default is INT2 pin) When you connect INT2 pin of the accelerometer to the MSP430, you can then use DigitalRead or AttachInterrupt to react to the signal. All the above is just theoretical as I don't have this chip at hand. But I obviously had too much time at hand Fmilburn, curtis63 and dubnet 3 Quote Link to post Share on other sites
curtis63 5 Posted May 7, 2016 Author Share Posted May 7, 2016 It's working !!! Here are the settings I have in my initialization function: void MMA8653::initialize() { i2cSend(CTRL_REG1, 0x00); i2cSend(XYZ_DATA_CFG, 0x00); // 2G full range mode i2cSend(FF_MT_CFG, 0x78); // motion detection, x, y, z i2cSend(FF_MT_THS, 0x15); // 1.5g i2cSend(FF_MT_COUNT, 0x05); // debounce over 5 readings i2cSend(CTRL_REG1, 0x01); } Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.