Spikes on Accelerometer Data

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

Spikes on Accelerometer Data

1,480 Views
moisesferber
Contributor I

Hello! I 'm developing a motion detection application using MMA8453Q and I2C for communication between the microcontroller and the accelerometer. Occasionally, like once every five or ten seconds, there 's a spike in the data. For example, the z-axis acceleration is at around 1.0g and suddenly it drops to almost 0.0g and goes back to 1.0g. All of that happens in 3 samples, at 800Hz.


Is this a "normal" situation or there's something I'm missing? One of my colleagues thinks it's a problem with the I2C, but I doubt it.

Labels (1)
0 Kudos
2 Replies

1,039 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hello Moises,

It sounds like a timing issue, the first thing I would recommend to try is using a lower ODR and/or a higher I2C clock speed.

Do you have a logic analyzer or an oscilloscope to know what is going on on the I2C bus and interrupt pins (if used)?

It might also be helpful to see your source code (at least the initialization and data processing routines).


Regards,

Tomas


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

1,039 Views
moisesferber
Contributor I

Dear Tomas Vaverka,

thank you for your reply. I reduced the ODR to 100Hz and set the High Resolution mode. The number of spikes reduced significantly. However, there are still about 2 spikes every 5 minutes. Do you think I should reduce even more the ODR or this time increase the I2C clock, so that this problem will disappear definitely?

Some parts of the source code:

// ---------- I2C INIT ---------- //

void I2C0Init( void )

{

  LPC_SC->PCONP |= (1 << 7);

  /* set PIO0.27 and PIO0.28 to I2C0 SDA and SCL */

  /* function to 01 on both SDA and SCL. */

  LPC_PINCON->PINSEL1 &= ~((0x03<<22)|(0x03<<24));

  LPC_PINCON->PINSEL1 |= ((0x01<<22)|(0x01<<24));   

  /*--- Clear flags ---*/

  LPC_I2C0->I2CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC | I2CONCLR_I2ENC;

  /*--- Reset registers ---*/

#if FAST_MODE_PLUS

  LPC_PINCON->I2CPADCFG |= ((0x1<<0)|(0x1<<2));

  LPC_I2C0->I2SCLL   = I2SCLL_HS_SCLL;

  LPC_I2C0->I2SCLH   = I2SCLH_HS_SCLH;

#else

  LPC_PINCON->I2CPADCFG &= ~((0x1<<0)|(0x1<<2));

  LPC_I2C0->I2SCLL   = I2SCLL_SCLL;

  LPC_I2C0->I2SCLH   = I2SCLH_SCLH;

#endif

  /* Install interrupt handler */

  NVIC_EnableIRQ(I2C0_IRQn);

  LPC_I2C0->I2CONSET = I2CONSET_I2EN;

  return;

}

// ---------- I2C INIT ---------- //

// ---------- WRITE IN REGISTER ---------- //

void ACEL_EscreveRegistrador(uint8_t registrador, uint8_t dado)

{

  //uint32_t PORT_USED = 0;

  I2CMasterBuffer[0][0] = 0x3A; //write

  I2CMasterBuffer[0][1] = registrador;

  I2CMasterBuffer[0][2] = dado; //dado a ser escrito no registrador

  I2CWriteLength[0] = 3;

  I2CReadLength[0] = 0;

  I2CEngine(0);

}

// ---------- WRITE IN REGISTER ---------- //

// ---------- ACCELEROMETER INIT ---------- //

  // High Resolution

  ACEL_EscreveRegistrador(ACEL_REG_CTRL_REG2, 0b00010010); //0x2B: CTRL_REG2

  // ODR = 100 Hz, page 35 do datasheet

  ACEL_EscreveRegistrador(ACEL_REG_CTRL_REG1, 0b00011000); //0x2A: CTRL_REG1

// ---------- ACCELEROMETER INIT ---------- //

// ---------- READING FUNCTION OF THE ACCELEROMETER ---------- //

void ACEL_LeDadosFormatoG(uint16_t *dados)

{

  uint16_t counts[6];

  uint16_t temp;

  // uint8_t i;

  uint8_t divisor = 0;

  uint8_t range = 0;

  //verifica qual o range (2g, 4g ou 8g) para selecionar o divisor

  range = ACEL_LeRegistrador(ACEL_REG_XYZ_DATA_CFG);

  switch (range & 0b11)

  {

    case 0b00: //2g

      divisor = 8;

      break;

    case 0b01: //4g

      divisor = 7;

      break;

    case 0b10: //8g

      divisor = 6;

      break;

  }

  ACEL_LeDadosFormatoCounts(counts);

  //copia os sinais

  dados[0] = counts[0];

  dados[2] = counts[2];

  dados[4] = counts[4];

  temp = ((counts[1] & 0x1FF) * 1000 + 512) >> divisor;

  dados[1] = temp;

  temp = ((counts[3] & 0x1FF) * 1000 + 512) >> divisor;

  dados[3] = temp;

  temp = ((counts[5] & 0x1FF) * 1000 + 512) >> divisor;

  dados[5] = temp;

}

// ---------- READING FUNCTION OF THE ACCELEROMETER ---------- //

0 Kudos