FXOS8700 data appears very noisy

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

FXOS8700 data appears very noisy

Jump to solution
1,672 Views
kaslewis
Contributor III

Hello,

 

I am using the FXOS8700 as well as the FXAS21002 to log data at 50Hz. The issue I am having is the noise/error with the FXOS8700C. As a simple test I have the unit (FRDM-KL25Z with FRDM-STBC-AGM01 mounted) sitting on my desk not in any motion other than some typing on a keyboard now and then. HOwever under these conditions the accelerometer is reading anywhere from -8g ~ 1g on ALL axis. I an understand 1g on the Z axis but 8g on any channel to me means something is incorrect. I have included graphes of the X, Y and Z axis plotted using GNUPlot and each value multiplied by 0.976mg.

 

54855_54855.pngX - Axis.png54856_54856.pngY - Axis.png54869_54869.pngZ - Axis.png

I have also attached my raw data file below with data from the X, Y and Z axis in semi raw form (the two bytes have been concatenated and shifted to get a 14 bit signed number). If the raw hex data would be more helpful I can obtain that and post that file as well. I do not believe it is an issue in my conversions as the Gyro data is almost noiseless (on the 250 dps scale its jumping between 0 ~ 0.25 dps)

 

If someone can please explain how to resolve this issue it would be very much appreciated. I have also included my full mbed code incase someone may feel there is an issue there.

 

Thankfully

Kas

 

#include "mbed.h" #include "SDFileSystem.h"   //FXOS8700CQ #define FXOS_ADDRESS_W              0x3C #define FXOS_ADDRESS_R              0x3D #define FXOS_STATUS                 0x00 #define FXOS_OUT_X_MSB              0x01 #define FXOS_F_SETUP                0x09 #define FXOS_TRIG_CFG               0x0A #define FXOS_SYS_MOD                0x0B #define FXOS_INT_SOURCE             0x0C #define FXOS_WHO_AM_I               0x0D #define FXOS_ID                     0xC7 #define FXOS_XYZ_DATA_CFG           0x0E #define FXOS_TRANSIENT_CFG          0x1D #define FXOS_TRANSIENT_SRC          0x1E #define FXOS_ASLP_COUNT             0x29 #define FXOS_CTRL_REG_1             0x2A #define FXOS_CTRL_REG_2             0x2B #define FXOS_CTRL_REG_3             0x2C #define FXOS_CTRL_REG_4             0x2D #define FXOS_CTRL_REG_5             0x2E #define FXOS_OFF_X                  0x2F #define FXOS_OFF_Y                  0x30 #define FXOS_OFF_Z                  0x31 #define FXOS_TEMP                   0x51 #define FXOS_M_CTRL_REG_1           0x5B #define FXOS_M_CTRL_REG_2           0x5C #define FXOS_M_CTRL_REG_3           0x5D   //FXAS21002C #define FXAS_ADDRESS_W              0x40 #define FXAS_ADDRESS_R              0x41 #define FXAS_STATUS                 0x00 #define FXAS_OUT_X_MSB              0x01 #define FXAS_F_SETUP                0x09 #define FXAS_F_EVENT                0x0A #define FXAS_INT_SRC_FLAG           0x0B #define FXAS_WHO_AM_I               0x0C #define FXAS_ID                     0xD7 #define FXAS_CTRL_REG_0             0x0D #define FXAS_RT_CFG                 0x0E #define FXAS_TEMP                   0x12 #define FXAS_CTRL_REG_1             0x13 #define FXAS_CTRL_REG_2             0x14 #define FXAS_CTRL_REG_3             0x15   //Global variables int FXAS_FIFO_FULL_FLAG = 0; int FXOS_FIFO_FULL_FLAG = 0; char fxos_data_1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; char fxas_data_1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};     //Setup UART to PC Serial pc(USBTX, USBRX);   //Setup I2C I2C sensors(PTE0, PTE1);   //FXOS8700C Control Pins InterruptIn fxos_int1_8700(PTD4); //INT1-8700 InterruptIn fxos_int2_8700(PTA4); //INT2-8700   //FXAS21002C Control Pins InterruptIn fxas_int1_21002(PTA5);  //INT1-21002 InterruptIn fxas_int2_21002(PTA13); //INT2-21002   //SD File System SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd");   ////LED Setup                                DigitalOut led_1(LED1, 1); //red DigitalOut led_2(LED2, 1); //green //DigitalOut led_3(LED3, 1); //blue         <- NB!! Wont play nice with SDFileSystem     //****************************************************************// //Functions int i2c_write(char address, char device_register, char data){     sensors.start();     sensors.write((char)address);     sensors.write((char)device_register);     sensors.write((char)data);     sensors.stop();     return 0; }   int i2c_write(char address, char device_register, int stop){     sensors.start();     sensors.write((char)address);     sensors.write((char)device_register);     if(stop == 1){         sensors.stop();     }     return 0; }   char i2c_read(char address, char device_register){     char data;          sensors.start();     sensors.write(address);     sensors.write(device_register);     sensors.start();     sensors.write(address | 0x01);     data = (char)sensors.read(0);     sensors.stop();     return data; }   int i2c_write_verify(char address, char device_register, char data){     char return_data;     int return_val;          sensors.start();     sensors.write((char)address);     sensors.write((char)device_register);     sensors.write((char)data);     sensors.stop();          sensors.start();     sensors.write(address);     sensors.write(device_register);     sensors.start();     sensors.write(address | 0x01);     return_data = sensors.read(0);     sensors.stop();          if (return_data == data){         return_val = 0;     }     else{         return_val = -1;     }     return return_val; }   int fxas_init() {     int return_val = 0;     int sensor_id = 0;        sensor_id = i2c_read(FXAS_ADDRESS_W, FXAS_WHO_AM_I); //    pc.printf("Expected ID from FXAS21002C is 0xD7\n\r"); //    pc.printf("Returned value: %X\n\n\r", sensor_id);          if (sensor_id == FXAS_ID){         return_val = 0;         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_1, 0x00);         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_F_SETUP, 0x00);         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_F_SETUP, 0x54);         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_0, 0x03);                  return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_2, 0xC2);         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_3, 0x00);         return_val += i2c_write_verify(FXAS_ADDRESS_W, FXAS_CTRL_REG_1, 0x13);            }     else{         return_val = -1;         }         return return_val; }      int fxos_init() {     int return_val = 0;     int sensor_id = 0;           sensor_id = i2c_read(FXOS_ADDRESS_W, FXOS_WHO_AM_I); //    pc.printf("Expected ID from FXOS8700CQ is 0xC7\n\r"); //    pc.printf("Returned value: %X\n\n\r", sensor_id);          if (sensor_id == FXOS_ID){         return_val = 0;         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_1, 0x00);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_F_SETUP, 0x00);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_F_SETUP, 0x54);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_ASLP_COUNT, 0xFF);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_XYZ_DATA_CFG, 0x02);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_2, 0x00);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_3, 0x02);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_4, 0x41);  //Enable FIFO & DRDY Interrupts         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_5, 0x40);  //FIFO -> Int_1, DRDY -> Imt_2         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_M_CTRL_REG_1, 0x00);         return_val += i2c_write_verify(FXOS_ADDRESS_W, FXOS_CTRL_REG_1, 0x21);     }     else{         return_val = -1;         }      return return_val; }   //Interrupt for FXAS21002 INT_1 void read_fxas_data(){ //    //Read data from FXAS21002 sensor     if(FXAS_FIFO_FULL_FLAG != 2){         FXAS_FIFO_FULL_FLAG = 1;     } }   //Interrupt for FXOS8700S INT_1 void read_fxos_data(){     //Read data from FXOS8700C sensor     if(FXOS_FIFO_FULL_FLAG != 2){         FXOS_FIFO_FULL_FLAG = 1;     } }   int main() {     int initilised = 0;     int index = 0;     int test_index = 0;     int fxos_data_flag_1 = 0;     int fxas_data_flag_1 = 0;          //Configure interrupts     fxas_int1_21002.rise(&read_fxas_data);//FIFO -> Int_1 //    fxas_int2_21002.rise(&read_fxas_data);//DRDY -> Int_2     fxos_int1_8700.rise(&read_fxos_data);//FIFO -> Int_1 //    fxos_int2_8700.rise(&read_fxos_data);//DRDY -> Int_2          sensors.frequency(450000);     pc.baud(115200);            mkdir("/sd/sensor_data", 0777);     FILE *fp = fopen("/sd/sensor_data/data.txt", "w");     if(fp == NULL) {         error("Could not open file for write\n");     }     fprintf(fp, "Gyro X,\tGyro Y,\tGyro Z,\t\tAcc X,\tACC Y,\tACC Z\n\r\n\r\n\r\n\r");     fclose(fp);           //Initlilise the FXOS8700CQ Accelorometer & the FXAS21002C Gyroscope     initilised = fxas_init() & fxos_init(); //    pc.printf("Returned value: %d\n\n\r", initilised);        while(1) {         if (FXOS_FIFO_FULL_FLAG == 1){//0.976mg * (fxos_data >> 2) = total g force (8g scale)             FXOS_FIFO_FULL_FLAG = 0;             i2c_write(FXOS_ADDRESS_W, FXOS_STATUS, 0);             sensors.read(FXOS_ADDRESS_R, fxos_data_1, 139, false);//Reads the status register on every pass 0x06 -> 0x00             fxos_data_flag_1 = 1;         }                  if (FXAS_FIFO_FULL_FLAG == 1){//7.8125mdps * fxas_data = total degrees per second (250dps scale)             FXAS_FIFO_FULL_FLAG = 0;             i2c_write(FXAS_ADDRESS_W, FXAS_STATUS, 0);             sensors.read(FXAS_ADDRESS_R, fxas_data_1, 139, false);//Reads the status register on the first if set to otherwise 0x06 -> 0x01             fxas_data_flag_1 = 1;         }                           if ((fxos_data_flag_1 == 1) && (fxas_data_flag_1 == 1)){         //Store data on SD card                 if (test_index == 0){// <--------- Just till a proper file closing system can be implemented                 fp = fopen("/sd/sensor_data/data.txt", "a");                 if(fp == NULL) {                     error("Could not open file for write\n");                 }             }                          for (index = 0; index < 139; index += 7){                 //move data to SD card                  fprintf(fp, "%d\t%d\t%d\t\t", ((int16_t)((fxos_data_1[(index + 1)] << 8) | fxos_data_1[(index + 2)]) >> 2),                     ((int16_t)((fxos_data_1[(index + 3)] << 8) | fxos_data_1[(index + 4)]) >> 2),                     ((int16_t)((fxos_data_1[(index + 5)] << 8) | fxos_data_1[(index + 6)]) >> 2));                                      fprintf(fp, "%d\t%d\t%d\n\r\n\r", ((int16_t)((fxas_data_1[(index + 1)] << 8) | fxas_data_1[(index + 2)])),                     ((int16_t)((fxas_data_1[(index + 3)] << 8) | fxas_data_1[(index + 4)])),                     ((int16_t)((fxas_data_1[(index + 5)] << 8) | fxas_data_1[(index + 6)])));             }                          fxos_data_flag_1 = 0;             fxas_data_flag_1 = 0;             test_index++; //            fprintf(fp, "\n\r\n\r\n\r\n\r\n\r\n\r");             if (test_index == 30){// <--------- Just till a proper file closing system can be implemented                 fclose(fp);                 test_index = 0;;             }             for (int i = 0; i < 139; i++){                 fxos_data_1[i] = 0;                 fxas_data_1[i] = 0;             }         }  

Original Attachment has been moved to: data.txt.zip

Labels (2)
1 Solution
966 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hello Kas,

The numbers you are seeing appear to be random. It makes me think that the way you are reading the FIFO is not correct. You should use something like this:

I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 120, AccelData);

The auto-increment address of the OUT_Z_LSB register is actually 0x01 and not 0x00, that is why I am reading 120 bytes (20 X, Y and Z data samples = 20 x 3 x 2) and not 139.

Attached you can find my example code reproducing your settings and the following screenshots illustrate correct behavior.

FXOS8700CQ FIFO Data.JPG

ODR is set to 50 Hz, so the FIFO interrupt happens every 400 ms (20 ms x 20 samples):

FXOS8700CQ FIFO Timing.JPG

Let me know whether or not this helps, or if you have any other questions.

Regards,

Tomas

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

View solution in original post

3 Replies
967 Views
TomasVaverka
NXP TechSupport
NXP TechSupport

Hello Kas,

The numbers you are seeing appear to be random. It makes me think that the way you are reading the FIFO is not correct. You should use something like this:

I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 120, AccelData);

The auto-increment address of the OUT_Z_LSB register is actually 0x01 and not 0x00, that is why I am reading 120 bytes (20 X, Y and Z data samples = 20 x 3 x 2) and not 139.

Attached you can find my example code reproducing your settings and the following screenshots illustrate correct behavior.

FXOS8700CQ FIFO Data.JPG

ODR is set to 50 Hz, so the FIFO interrupt happens every 400 ms (20 ms x 20 samples):

FXOS8700CQ FIFO Timing.JPG

Let me know whether or not this helps, or if you have any other questions.

Regards,

Tomas

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

966 Views
kaslewis
Contributor III

Hello Tomas,

Thank you for your response, if I am understanding your comment correctly there is a mistake in the FXOS8700CQ data sheet. On page 25 for OUT_Z_LSB it says auto increments to either 0x00 0r 0x33 depending on CTRL_REG2 [hyb_autoinc_mode].

2015-07-27 08_56_37-cache.freescale.com_files_sensors_doc_data_sheet_FXOS8700CQ.pdf.png

If this is the case then this is a simple issue to resolve and as you said it will fix both issues at the same time. If you could please confirm the error in the data sheet that would be helpful.

Thankfully

Kas

0 Kudos
966 Views
kaslewis
Contributor III

It appears from my limited testing that in fact the DATASHEET is INCORRECT and it is as Tomas says that the auto increment for the FXOS is to 0x01 and NOT 0x00 as stated in the data sheet.

Freescale please fix the data sheet so as not to cause further confusion to others.

Thankfully

Kas

0 Kudos