AnsweredAssumed Answered

FXOS8700CQ interrupt and data reading is not stable

Question asked by tungdao on Jul 21, 2015
Latest reply on Aug 1, 2015 by tungdao

Hi, I followed the example on this article FXOS8700CQ - Bare metal example project  to write similar code to run with the TI CC3200. However I have experienced unstable interrupt and data reading. The interrupt (INT1) is not always available, regardless how hard I move the board around to change the acceleration and magnetic field. Also data reading hangs after a few ( 4 to 7) reads and then I would not be able to read the magnetic data at all, until I cycle power the sensor. So I have few problems I would need help with:

 

1. Is there a way to reset the sensor without cycling power?

2. Did I do anything wrong in setting up the sensor? (Code is at the end of this post)

3. My application is fairly simple: if there's a magnetic change in the environment, sends an interrupt signal to the MCU to read the magnetic data. Then wait until the magnetic signal is stabilize (i.e. no changes in magnetic within 10s) and activate interrupt listener again. What would be the best way to use the FXOS8700CQ for this application?

 

The current code I have on CC3200:

 

void I2C_Init() {
  I2C_Open(I2C_MASTER_MODE_STD);
  
  GPIO_IF_LedConfigure(LED1|LED2|LED3);

  Fxos8700cqInit();
}

 

static void Fxos8700cqInit (void) {
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG2, 0x40); // Reset all registers to POR values

  MAP_UtilsDelay(16000); // ~1ms delay.

  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_XYZ_DATA_CFG_REG, 0x00); // +/-2g range with 0.244mg/LSB

  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_M_CTRL_REG1, 0x1F); // Hybrid mode (accelerometer + magnetometer), max OSR
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_M_CTRL_REG2, 0x20); // M_OUT_X_MSB register 0x33 follows the OUT_Z_LSB register 0x06 (used for burst read)

  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG2, 0x02);     // High Resolution mode
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG3, 0x00); // Push-pull, active low interrupt
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG4, 0x01); // Enable DRDY interrupt
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG5, 0x01); // DRDY interrupt routed to INT1 - PTD4
  WriteSingle(FXOS8700CQ_I2C_ADDRESS, FX_CTRL_REG1, 0x35); // ODR = 3.125Hz, Reduced noise, Active mode
}

 

static void I2C_HandleDataReadyInterrupt()
{
  DisableGpioInterruptHandler(INT_TEST_SW3);     //disable INT1 interrupt handler

  GPIO_IF_LedToggle(MCU_RED_LED_GPIO);

  _dataReady = 1;
}

 

static void ResetDataInterrupt()
{
   _dataReady = 0;

  MAP_UtilsDelay(16000);

  InitGpioInterruptHandler(I2C_HandleDataReadyInterrupt, INT_TEST_SW3);     //set interrupt handler for INT1
}

 

int main(void)
{
  ResetDataInterrupt();

  while (1)
  {
  if (_dataReady) // Is a new set of data ready?
  {
  ReadMulti(FXOS8700CQ_I2C_ADDRESS, FX_OUT_X_MSB_REG, 12, AccelMagData); // Read data output registers 0x01-0x06 and 0x33 - 0x38

  // 14-bit accelerometer data
  Xout_Accel_14_bit = ((short) (AccelMagData[0] << 8 | AccelMagData[1])) >> 2; // Compute 14-bit X-axis acceleration output value
  Yout_Accel_14_bit = ((short) (AccelMagData[2] << 8 | AccelMagData[3])) >> 2; // Compute 14-bit Y-axis acceleration output value
  Zout_Accel_14_bit = ((short) (AccelMagData[4] << 8 | AccelMagData[5])) >> 2; // Compute 14-bit Z-axis acceleration output value

  // Accelerometer data converted to g's
  Xout_g = ((float) Xout_Accel_14_bit) / FX_SENSITIVITY_2G; // Compute X-axis output value in g's
  Yout_g = ((float) Yout_Accel_14_bit) / FX_SENSITIVITY_2G; // Compute Y-axis output value in g's
  Zout_g = ((float) Zout_Accel_14_bit) / FX_SENSITIVITY_2G; // Compute Z-axis output value in g's

  // 16-bit magnetometer data
  Xout_Mag_16_bit = (short) (AccelMagData[6] << 8 | AccelMagData[7]); // Compute 16-bit X-axis magnetic output value
  Yout_Mag_16_bit = (short) (AccelMagData[8] << 8 | AccelMagData[9]); // Compute 16-bit Y-axis magnetic output value
  Zout_Mag_16_bit = (short) (AccelMagData[10] << 8 | AccelMagData[11]); // Compute 16-bit Z-axis magnetic output value

  // Magnetometer data converted to microteslas
  Xout_uT = (float) (Xout_Mag_16_bit) / FX_SENSITIVITY_MAG; // Compute X-axis output magnetic value in uT
  Yout_uT = (float) (Yout_Mag_16_bit) / FX_SENSITIVITY_MAG; // Compute Y-axis output magnetic value in uT
  Zout_uT = (float) (Zout_Mag_16_bit) / FX_SENSITIVITY_MAG; // Compute Z-axis output magnetic value in uT

  Heading = atan2(Yout_uT, Xout_uT) * 180 / PI; // Compute Yaw angle

  printf("Mag(uT) - X:%f Y:%f Z:%f Heading:%f \n\r", Xout_uT, Yout_uT, Zout_uT, Heading);

  ResetDataInterrupt();
  }
  }
}

Outcomes