MMA8452 accelerometer with PIC16F1946

cancel
Showing results for 
Search instead for 
Did you mean: 

MMA8452 accelerometer with PIC16F1946

1,153 Views
Contributor II

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!

9 Replies

223 Views
Contributor II

Hi

This might be helpful  MM8451 Project (SW/HW)

--jim

223 Views
Contributor II

Hello Jim

Thank You.

0 Kudos

223 Views
Contributor II

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!

0 Kudos

223 Views
NXP TechSupport
NXP TechSupport

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

0 Kudos

223 Views
Contributor II

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!

0 Kudos

223 Views
Contributor II

That worked!!! Thank you Tomas

0 Kudos

223 Views
NXP TechSupport
NXP TechSupport

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.

223 Views
Contributor II

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; 
}  

0 Kudos

223 Views
NXP TechSupport
NXP TechSupport

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