MMA8452Q - Reading values most of the time are correct, but sometimes strange

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MMA8452Q - Reading values most of the time are correct, but sometimes strange

Jump to solution
1,499 Views
鑫勇汪
Contributor I

Hi,

   I am using MMA8452 in one of the projects,  most of the time ,I found the reading values of x,y,z axis are correct ,but sometimes one of them has a strange value , for instance,when the sensor is laying,the z-axis value is about 400mg,  but at sometime, the z-axis value will become 500mg  ,In the next second, the z-axis value is still about 400mg,I don't know why there will be a strange value?

Thank you in advance.

无标题.png

Labels (1)
0 Kudos
Reply
1 Solution
1,160 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

Could you please post here your complete source code or at least the initialization and data reading/processing routines so that we can more easily analyze where the problem might be? Is the device sitting motionless on your desk while you are running your test? How many boards have you tested so far and on how many of them you are observing this „strange“ readings?

You might also find useful my example code written for the MMA8652FC.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

View solution in original post

5 Replies
1,161 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

Could you please post here your complete source code or at least the initialization and data reading/processing routines so that we can more easily analyze where the problem might be? Is the device sitting motionless on your desk while you are running your test? How many boards have you tested so far and on how many of them you are observing this „strange“ readings?

You might also find useful my example code written for the MMA8652FC.

Regards,

Tomas

PS: If my answer helps to solve your question, please mark it as "Correct" or “Helpful”. Thank you.

1,160 Views
鑫勇汪
Contributor I

Hi,

      The following source code is all about the MMA8452  , thank you for you help!

void SensMma8452Config (void)

{

  MMA8452_WriteReg(0x2A,0x01);

    MMA8452_WriteReg(0x2B,0x02);

}

void I2C_Start (void)

{

    SCL_H;

    SDA_H;

    delay_nus(I2C_DALAY);

    SDA_L;

    delay_nus(I2C_DALAY);

}

void I2C_Stop(void)

{

      SDA_L;

    SCL_L;

      SCL_H;

      delay_nus(I2C_DALAY);

      SDA_H;

      delay_nus(I2C_DALAY);

}

unsigned char I2C_SlaveAck(void)

{

    uint16_t ts=0;

    SCL_L;

      MMA_SDA_IOIN();                 

      delay_nus (I2C_DALAY);

      SCL_H;

    delay_nus (I2C_DALAY);

    while(SDA_STATE != 0)

    {

         ts++;

         if(ts>200){

                     MMA_SDA_IOOUT();                

                     SCL_L;

                 return MMA_ERROR;       

         }

     }

         SCL_L;        

         MMA_SDA_IOOUT();                

     delay_nus(I2C_DALAY);

     return MMA_OK;                

}

void I2C_WriteByte(unsigned char a)

{

    unsigned char i;

    for(i=0; i<8; i++){         

        SCL_L;

        delay_nus(I2C_DALAY);

        if((a&0x80)!=0)

            SDA_H;

    else

            SDA_L;

        a <<= 1;

        delay_nus(I2C_DALAY);

        SCL_H;

        delay_nus(I2C_DALAY);

    }  

     SCL_L;

   if(I2C_SlaveAck()== MMA_ERROR)     

   {

     return ;

   }

}

unsigned char I2C_ReadByte (void)

{

      unsigned char a =0;

      unsigned char i;

   

      MMA_SDA_IOIN();                 

  

      for(i=0; i<8; i++){

             a <<= 1; 

              SCL_H;

              delay_nus(I2C_DALAY);

            if(SDA_STATE)

                    a |= 0x01;

                delay_nus(I2C_DALAY);

                SCL_L;

                delay_nus(I2C_DALAY);

                           

      }

        MMA_SDA_IOOUT();                

       

      return a;

}

void SensMMA8452Read (void)

{  

    uint8_t  i,j;

      uint8_t MMA8452_Data[6] = {0};

   

    int     temp;

      int     x_acc_sum = 0;

      int     y_acc_sum = 0;

      int     z_acc_sum = 0;

    int     x_acc_single[10] = {0};

    int     y_acc_single[10] = {0};

    int     z_acc_single[10] = {0};

        for (i = 0; i < 10; i++) {           

            MMA8452_Begin();

           

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x01);                 

        I2C_Start();                         

        I2C_WriteByte(SlaveAddress+1);     

        MMA8452_Data[0] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();                      

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress);         

        I2C_WriteByte(0x02);                

        I2C_Start();                       

        I2C_WriteByte(SlaveAddress+1);      

        MMA8452_Data[1] = I2C_ReadByte();   

        I2C_SlaveAck();

        I2C_Stop();

        

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress);        

        I2C_WriteByte(0x03);                  

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress+1);     

        MMA8452_Data[2] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

        I2C_Start();                     

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x04);                  

        I2C_Start();                       

        I2C_WriteByte(SlaveAddress+1);    

        MMA8452_Data[3] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x05);                 

        I2C_Start();                      

        I2C_WriteByte(SlaveAddress+1);       

        MMA8452_Data[4] = I2C_ReadByte();    

        I2C_SlaveAck();

        I2C_Stop();

       

            I2C_Start();                     

        I2C_WriteByte(SlaveAddress);       

        I2C_WriteByte(0x06);                

        I2C_Start();                        

        I2C_WriteByte(SlaveAddress+1);       

        MMA8452_Data[5] = I2C_ReadByte();  

        I2C_SlaveAck();

        I2C_Stop();

       

            x_acc_single[i] = (MMA8452_Data[0] << 4) + (MMA8452_Data[1] >> 4);

            y_acc_single[i] = (MMA8452_Data[2] << 4) + (MMA8452_Data[3] >> 4);

            z_acc_single[i] = (MMA8452_Data[4] << 4) + (MMA8452_Data[5] >> 4);

   

               

                if (x_acc_single[i] >= 0x800) {           

                    x_acc_single[i] &= 0x7FF;

            x_acc_single[i] = 1999*x_acc_single[i]/2047 - 2000;                   

                } else {

                      x_acc_single[i] = 1999*x_acc_single[i]/2047;

                }

               

                if (y_acc_single[i] >= 0x800) {           

                    y_acc_single[i] &= 0x7FF;

            y_acc_single[i] = 1999*y_acc_single[i]/2047 - 2000;                   

                } else {

                      y_acc_single[i] = 1999*y_acc_single[i]/2047;

                }

               

                if (z_acc_single[i] >= 0x800) {         

                    z_acc_single[i] &= 0x7FF;

            z_acc_single[i] = 1999*z_acc_single[i]/2047 - 2000;                   

                } else {

                      z_acc_single[i] = 1999*z_acc_single[i]/2047;

                }

               

                x_acc_sum += x_acc_single[i];

          y_acc_sum += y_acc_single[i];

            z_acc_sum += z_acc_single[i];   

               

          }

               

            x_acc = x_acc_sum/10;

        y_acc = y_acc_sum/10;

            z_acc = z_acc_sum/10;   

           

}

void MMA8452_Begin (void)

{

    MMA8452_WriteReg(0x2A,0x01);                           //standby mode

      MMA8452_WriteReg(0x2B,0x02);                           //No Sleep Count

}

uint8_t MMA8452_GetResult (unsigned char Regs_Addr)

{

   uint8_t  ret;

 

   ret = MMA8452_ReadReg(Regs_Addr);

   while (ret&0x40) {

       ret=MMA8452_ReadReg(Regs_Addr);          

   }

   return ret;

}

static unsigned char MMA8452_ReadReg (unsigned char Regs_Addr)

{

    unsigned char ret;

  

   

    I2C_Start();  

    I2C_WriteByte(SlaveAddress);    

    I2C_WriteByte(Regs_Addr);           

  

    I2C_Start();

    I2C_WriteByte(SlaveAddress+1);     

    ret=I2C_ReadByte();                   

    I2C_SlaveAck();

    I2C_Stop();                     

  

    return ret;

}

static void MMA8452_WriteReg (unsigned char Regs_Addr, unsigned char Regs_Data)

    I2C_Start();

    I2C_WriteByte(SlaveAddress);    

    I2C_WriteByte(Regs_Addr);           

    I2C_WriteByte(Regs_Data);           

    I2C_Stop();                         

}

static void MMA_SDA_IOOUT(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = SDA ;           

  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_Out_OD;             

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;            

  GPIO_Init(GPIOB, &GPIO_InitStructure);                       

}

static void MMA_SDA_IOIN(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           

  GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IN_FLOATING;   

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               

  GPIO_Init(GPIOB, &GPIO_InitStructure);                    

}

0 Kudos
Reply
1,160 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hi,

It looks like you are not converting correctly the raw values from registers 0x01 – 0x06 to signed 12-bit values.

You should use something like this:

x_acc_single[i] = ((int) (MMA8452_Data[0] << 8 + MMA8452_Data[1])) >> 4;

y_acc_single[i] = ((int) (MMA8452_Data[2] << 8 + MMA8452_Data[3])) >> 4;

z_acc_single[i] = ((int) (MMA8452_Data[4] << 8 + MMA8452_Data[5])) >> 4;

Please let me know whether or not it helps.

Regards,

Tomas

0 Kudos
Reply
1,160 Views
鑫勇汪
Contributor I

Hi,

       The problem has been resolved, the  reason is that reading values not in the right time. Thank you for your help!

0 Kudos
Reply
1,160 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Thanks for the update and glad it is solved.

Regards,

Tomas

0 Kudos
Reply