Hello!
I want to light a LED when i move the MMA8452 accelerometer, could you help me with an example of C program.
Thank you!
Hello Jim
Thank You.
Hello Tomas,
That worked, Thank you so much.
I have two small problem :
-1- Now, when i put power, Leds Turn ON and when i touch my card Leds Turn OFF.
I want to inverse, when i put power Leds stay OFF and when i touch Leds Turn ON.
I tried to change bit 0 of CTRL_REG3 register, but no change.
-2- How can i improve the sensitivity of my accelerometer. i want that my Led Turn ON at any small motion?
I my case, i have to press two or three times to work.
Thank you so much Sir!
Hi Achref,
1. It is not related to the MMA8452Q, but it sounds like your LED is connected with its cathode to your output pin, so to switch it on, you need to write a ´0´ (output_low(LED)).
2. To increase the sensitivity, decrease the threshold value in the FF_MT_THS register. Its resolution is 62.5mg/LSB, so your current threshold is 62.5mg x 48 (0x30) = 3g. Try to decrease it to e.g. 1.5g (0x18) or lower.
Hope it helps.
Best regards,
Tomas
Hello Tomas
Thank you so much, that worked.
Please, a last question, is it normal that LED turn ON only when i touch the interrupt PIN (RB0) of PIC 16F1946 ?
LED doesn't turn ON, if i touch anywhere or if i move my card.
This is my configuration :
//Configuring of Motion detection
write_Reg(I2C_WRITE_ADDR,CTRL_REG1,0x18); //Put the device into Standby Mode
write_Reg(I2C_WRITE_ADDR,FF_MT_CFG_REG,0xD8); //Configurion of motion detection
write_Reg(I2C_WRITE_ADDR,FT_MT_THS_REG,0x18); //reglage seuil >1.5g
write_Reg(I2C_WRITE_ADDR,FF_MT_COUNT_REG,0x0A); //reglage compteur
write_Reg(I2C_WRITE_ADDR,CTRL_REG3,0x00);
write_Reg(I2C_WRITE_ADDR,CTRL_REG4,0x04); //Enable Motion to INT1 PIN
write_Reg(I2C_WRITE_ADDR,CTRL_REG5,0x04); //route the motion to INT1
write_Reg(I2C_WRITE_ADDR,CTRL_REG1,0x19); //Put the device into Active Mode
In my case, I want that LED turn ON when i move the MMA8452Q card, I think that i haven't choose the best operatiog mode, that meets my needs.
Thank you!
That worked!!! Thank you Tomas
Hi Achref,
You can use an embedded transient detection function that compares whether any of the enabled axes has exceeded a set change in acceleration disregarding the static acceleration (gravity). There is also the motion detection function, but it analyses change in acceleration considering both static and dynamic acceleration.
For more information including example codes please take a closer look at AN4071 and AN4070. You might also find useful my simple example code illustrating the use of the transient detection function.
Hope it helps.
Best regards,
Tomas
PS: If my answer helps to solve your question, please mark it as "Correct". Thank you.
Hi Tomas,
Thank you for your quick reply.
I have followed steps on page 11 of Motion detection using MMA8452 accelerometer.
My C code is :
#include "16F1946.h"
#use delay (clock=16000000)
#fuses HS, NOWDT, NOPUT, NOPROTECT, BROWNOUT,INTRC_IO
#Use i2c(master,SCL=PIN_D6 ,SDA=PIN_D5 , FAST=400000)
void Init(void) {
T1CON = 0b00000000;
INTCON = 0b11011011;
TMR1ON = 0;
TMR1IF = 0;
TMR1IE = 1;
T1CON = 0b00001101;
}
#INT_TIMER1
void INTERRUP_TIMER1() {
timecount++;
TMR1IF = 0; //clear INT0 interrupt flag
}
main()
{
init();
write_Reg(CTRL_REG1,0x18);
write_Reg(FF_MT_CFG_REG,0xD8);
write_Reg(FT_MT_THS_REG,0x30);
write_Reg(FF_MT_COUNT_REG,0x0A);
write_Reg(CTRL_REG4,0x04);
write_Reg(CTRL_REG5,0x04);
write_Reg(CTRL_REG1,0x19);
while(True)
{
if (TimeCount % 1000 == 0)
{
write_Reg(I2C_WRITE_ADDR, INT_SOURCE_REG);
Intsourcesystem = read_reg(INT_SOURCE_REG);
if ((Intsourcesystem & 0x04)==0x04)
{
n++;
write_Reg1(I2C_WRITE_ADDR, FF_MT_SRC_REG);
read_Reg1(FF_MT_SRC_REG);
}
}
if (input(Int_acc)==1) {
output_high(LED); }
else {
output_low(LED); }
}
}
void Write_Reg(byte address, byte reg,byte val)
{
i2c_Start(); // Send Start
i2c_Write(address); // Send IIC "Write" Address
i2c_Write(reg); // Send Register
i2c_write(val); // Send Value
i2c_Stop(); // Send Stop
}
byte Read_Reg(byte address, byte reg)
{
byte b;
i2c_Start(); // Send Start
i2c_Write(address); // Send IIC "Write" Address
i2c_Write(reg); // Send Register
i2c_Start(); // Send Repeat Start
i2c_Write(address+1); // Send IIC "Read" Address
b = i2c_Read(1); // *** Dummy read: reads "IIC_ReadAddress" value ***
/b = i2c_Read(1); // Read Register Value
i2c_Stop(); // Send Stop
return b;
}
Hi Achref,
Your code seems to be correct. If you are experiencing any problems, please describe them, so that we can follow up.
Best regards,
Tomas