FXOS8700CQ Magnetometer Not Working Properly!

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

FXOS8700CQ Magnetometer Not Working Properly!

Jump to solution
2,285 Views
Amit_Kumar1
Senior Contributor II

Hi

I am using FXOS8700CQ ACC+ Mag with K60 custom made board. The accelerometer is fine but the magnetometer is not working properly. The value of magnetometer changes when I change the orientation but after placing it back to its initial state , the values doesn't recover. Attached is the value and the code snippet. I have made the code in Codewarrior 10.6 with PE. Please look into the matter and help me resolve the issue. The setup was tested on wooden table , Considering the external mag field should not effect much. After I did Power on Reset, the values returned to earlier state . I regenerated the issue multiple times.

 

Main.c

 

 

#include "FXOS8700CQ.h"

uint8_t adata[11];

 

uint8_t adata[13];

int16_t ax, ay, az, mx, my, mz;

float accx, accy, accz, mag_vect ,magx, magy, magz;

bool flag = FALSE;

#define CTL_1_Standby 0x00 // Standby mode

#define CTL_1_Active_lownoise 0x1D // LOw noise, 50Hz ODR, Active

#define FOUR_G 0x01 // 4G mode

#define CTL_2_highres 0x10 // high resolution

 

 

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

/* Write your local variable definition here */

 

/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

PE_low_level_init();

/*** End of Processor Expert internal initialization. ***/

 

AINT1 = AMINT1_Init(NULL);

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG1, CTL_1_Standby); // Standby for configuration

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG2, CTL_2_highres); // high resolution

GI2C2_WriteByteAddress8(FX_I2C_ADD, XYZ_DATA_CFG, FOUR_G); // 4G configuration enabled

 

int magThreshold = 1000; // 1000 counts --> 100.0uT

int magThresholdHi = (magThreshold & 0XFF00) >> 8;

int magThresholdLo = (magThreshold & 0XFF);

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, M_VECM_THS_MSB, 0x80 | magThresholdHi); // Setting the mag threshold

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, M_VECM_THS_LSB, magThresholdLo);

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, M_VECM_CNT, 0x01); // 20 ms debounce time period = M_VECM_CN /ODR 08-->400Hz

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, M_VECM_CFG, 0x7A); // Enable magnetic Vector magnitude detection, INT2 enable

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG3, 0x02); // Interrupt polarity set to high 02

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG4, 0x01); // Interrupt for DR

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG5, 0x01); // Interrupt for DR on intr1

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, M_CTRL_REG1, 0xDF); // Hybrid mode OS = 2, Auto cal degausing -->DF

 

GI2C2_WriteByteAddress8(FX_I2C_ADD, CTRL_REG1, 0x25); // Low noise,

 

for(;;)

{

if(flag)

{

 

ax = ((short)((adata[0]<<8) | adata[1])>>2);

ay = ((short)((adata[2]<<8) | adata[3])>>2);

az = ((short)((adata[4]<<8) | adata[5])>>2);

 

mx = (uint16_t)((adata[6]<<8) | adata[7]);

my = (uint16_t)((adata[8]<<8) | adata[9]);

mz = (uint16_t)((adata[10]<<8) | adata[11]);

 

magx = (float)mx/10;

magy = (float)my/10;

magz = (float)mz/10;

 

printf("%03.03f ,%03.03f ,%03.03f\n",magx, magy, magz);

 

flag = FALSE;

 

}

}

}

 

 

Events.c

 

#define FX_I2C_ADD (0x1F)

 

#define OUT_X_MSB 0x01

#define OUT_X_LSB 0x02

#define OUT_Y_MSB 0x03

#define OUT_Y_LSB 0x04

#define OUT_Z_MSB 0x05

#define OUT_Z_LSB 0x06

 

#define M_DR_STATUS 0x32

#define M_OUT_X_MSB 0x33

#define M_OUT_X_LSB 0x34

#define M_OUT_Y_MSB 0x35

#define M_OUT_Y_LSB 0x36

#define M_OUT_Z_MSB 0x37

#define M_OUT_Z_LSB 0x38

 

extern bool flag;

 

extern uint8_t adata[13];

 

 

void AMINT1_OnInterrupt(LDD_TUserData *UserDataPtr)

{

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_X_MSB, &adata[0]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_X_LSB, &adata[1]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_Y_MSB, &adata[2]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_Y_LSB, &adata[3]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_Z_MSB, &adata[4]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, OUT_Z_LSB, &adata[5]);

 

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_X_MSB, &adata[6]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_X_LSB, &adata[7]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_Y_MSB, &adata[8]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_Y_LSB, &adata[9]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_Z_MSB, &adata[10]);

GI2C2_ReadByteAddress8(FX_I2C_ADD, M_OUT_Z_LSB, &adata[11]);

 

flag = TRUE;

}

Original Attachment has been moved to: FXOS8700CQ.h.zip

Original Attachment has been moved to: Magnetometer.csv.zip

1 Solution
1,300 Views
iliketux
Contributor II

Hello Amit Kumar,

I've tried to reproduce the behavior of the sensor and found a hot candidate for the culprit.

I think that the continuous autocalibration changes the offsets which accumulate over time (cf. chapter 10.17.1, table 196 first row in the datasheet).

I've set the M_CTRL_REG1 to 0x5F instead of 0xDF and it seemed to work fine then.

To be sure that you get rid of all unwanted offsets you can reboot the sensor by writing 0x40 to CTRL_REG2 and wait for 1ms before you configure it.

Regards

    Tobi

View solution in original post

4 Replies
1,301 Views
iliketux
Contributor II

Hello Amit Kumar,

I've tried to reproduce the behavior of the sensor and found a hot candidate for the culprit.

I think that the continuous autocalibration changes the offsets which accumulate over time (cf. chapter 10.17.1, table 196 first row in the datasheet).

I've set the M_CTRL_REG1 to 0x5F instead of 0xDF and it seemed to work fine then.

To be sure that you get rid of all unwanted offsets you can reboot the sensor by writing 0x40 to CTRL_REG2 and wait for 1ms before you configure it.

Regards

    Tobi

1,300 Views
Amit_Kumar1
Senior Contributor II

Hi Tobias

Thanks for quick and correct reply. It worked. I Did those settings to get rid of soft iron/hard iron errors. Any ways now atleast it is working. Thanks a lot.

Regards

Amit Kumar

0 Kudos
Reply
1,300 Views
iliketux
Contributor II

Hello Amit Kumar,

I played around with this sensor on my FRDM K64F board and had similar problems.

The problem was caused by the fact, that I did not put delays between different write operations to the configuration registers.

The datasheet states that you have to wait at least 1.6µs between a stop and a start condition.

Therefore my data was partly not written to the sensor and the sensor was missconfigured.

Therefore I think that your code will work if you put 2µs delays between your calls to GI2C2_WriteByteAddress8().

Regards,
   iliketux

1,300 Views
Amit_Kumar1
Senior Contributor II

Hi Tobias

Thanks for the reply. I tried with the delay also, but the result was the same.

Regards

Amit Kumar

0 Kudos
Reply