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
已解决! 转到解答。
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
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
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
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