Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
FXOS8700CQ.cpp
00001 /* FXOS8700CQ Library 00002 00003 Sample code from ELEC2645 - demonstrates how to create a library 00004 for the K64F on-board accelerometer and magnetometer 00005 00006 (c) Craig A. Evans, University of Leeds, Jan 2017 00007 00008 */ 00009 00010 #include "FXOS8700CQ.h" 00011 00012 // constructor is called when the object is created - use it to set pins and frequency 00013 FXOS8700CQ::FXOS8700CQ(PinName sda, PinName scl) 00014 { 00015 i2c = new I2C(sda,scl); // create new I2C instance and initialise 00016 } 00017 00018 // destructor is called when the object goes out of scope 00019 FXOS8700CQ::~FXOS8700CQ() 00020 { 00021 delete i2c; // free memory 00022 } 00023 00024 // based on 13.4 in datasheet - 200 Hz hybrid mode (both acc and mag) 00025 void FXOS8700CQ::init() 00026 { 00027 // i2c fast-mode - 10.1.1 data sheet 00028 i2c->frequency(400000); // I2C Fast Mode - 400kHz 00029 00030 // the device has an ID number so we check the value to ensure the correct 00031 // drive is on the i2c bus 00032 char data = read_byte_from_reg(FXOS8700CQ_WHO_AM_I); 00033 if (data != FXOS8700CQ_WHO_AM_I_VAL) { // if correct ID not found, hang and flash error message 00034 error("Incorrect ID!"); 00035 } 00036 00037 // write 0000 0000 = 0x00 to accelerometer control register 1 to place 00038 // FXOS8700CQ into standby 00039 // [7-1] = 0000 000 00040 // [0]: active=0 00041 data = 0x00; 00042 send_byte_to_reg(data,FXOS8700CQ_CTRL_REG1); 00043 00044 // write 0001 1111 = 0x1F to magnetometer control register 1 00045 // [7]: m_acal=0: auto calibration disabled 00046 // [6]: m_rst=0: no one-shot magnetic reset 00047 // [5]: m_ost=0: no one-shot magnetic measurement 00048 // [4-2]: m_os=111=7: 8x oversampling (for 200Hz) to reduce magnetometer noise 00049 // [1-0]: m_hms=11=3: select hybrid mode with accel and magnetometer active 00050 data = 0x1F; 00051 send_byte_to_reg(data,FXOS8700CQ_M_CTRL_REG1); 00052 00053 // write 0010 0000 = 0x20 to magnetometer control register 2 00054 // [7]: reserved 00055 // [6]: reserved 00056 // [5]: hyb_autoinc_mode=1 to map the magnetometer registers to follow 00057 // the accelerometer registers 00058 // [4]: m_maxmin_dis=0 to retain default min/max latching even though not used 00059 // [3]: m_maxmin_dis_ths=0 00060 // [2]: m_maxmin_rst=0 00061 // [1-0]: m_rst_cnt=00 to enable magnetic reset each cycle 00062 data = 0x20; 00063 send_byte_to_reg(data,FXOS8700CQ_M_CTRL_REG2); 00064 00065 // write 0000 0001= 0x01 to XYZ_DATA_CFG register 00066 // [7]: reserved 00067 // [6]: reserved 00068 // [5]: reserved 00069 // [4]: hpf_out=0 00070 // [3]: reserved 00071 // [2]: reserved 00072 // [1-0]: fs=01 for accelerometer range of +/-4g range with 0.488mg/LSB 00073 data = 0x01; 00074 send_byte_to_reg(data,FXOS8700CQ_XYZ_DATA_CFG); 00075 00076 // write 0000 1101 = 0x0D to accelerometer control register 1 00077 // [7-6]: aslp_rate=00 00078 // [5-3]: dr=001 for 200Hz data rate (when in hybrid mode) 00079 // [2]: lnoise=1 for low noise mode 00080 // [1]: f_read=0 for normal 16 bit reads 00081 // [0]: active=1 to take the part out of standby and enable sampling 00082 data = 0x0D; 00083 send_byte_to_reg(data,FXOS8700CQ_CTRL_REG1); 00084 00085 } 00086 00087 Data FXOS8700CQ::get_values() 00088 { 00089 // 13 bytes - status plus 6 channels (2 bytes each) 00090 // x,y,z for accelerometer and magnetometer 00091 char data[FXOS8700CQ_READ_LEN]; 00092 read_bytes_from_reg(FXOS8700CQ_STATUS,FXOS8700CQ_READ_LEN,data); 00093 00094 // copy the 14 bit accelerometer byte data into 16 bit words 00095 int acc_x = (int16_t)(((data[1] << 8) | data[2]))>> 2; 00096 int acc_y = (int16_t)(((data[3] << 8) | data[4]))>> 2; 00097 int acc_z = (int16_t)(((data[5] << 8) | data[6]))>> 2; 00098 00099 // copy the magnetometer byte data into 16 bit words 00100 int mag_x = (int16_t) (data[7] << 8) | data[8]; 00101 int mag_y = (int16_t) (data[9] << 8) | data[10]; 00102 int mag_z = (int16_t) (data[11] << 8) | data[12]; 00103 00104 Data values; // struct to hold values 00105 00106 // 0.488 mg/LSB in 4 g mode (8.1 data sheet) 00107 values.ax = 0.488e-3*acc_x; 00108 values.ay = 0.488e-3*acc_y; 00109 values.az = 0.488e-3*acc_z; 00110 00111 // the magnetometer sensitivity is fixed at 0.1 μT/LSB 00112 values.mx = 0.1e-6*mag_x; 00113 values.my = 0.1e-6*mag_y; 00114 values.mz = 0.1e-6*mag_z; 00115 00116 return values; 00117 } 00118 00119 void FXOS8700CQ::send_byte_to_reg(char byte,char reg) 00120 { 00121 char data[2]; 00122 data[0] = reg; 00123 data[1] = byte; 00124 // send the register address, followed by the data 00125 int nack = i2c->write(FXOS8700CQ_ADDR,data,2); 00126 if (nack) 00127 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00128 00129 } 00130 00131 // reads a byte from a specific register 00132 char FXOS8700CQ::read_byte_from_reg(char reg) 00133 { 00134 int nack = i2c->write(FXOS8700CQ_ADDR,®,1,true); // send the register address to the slave 00135 // true as need to send repeated start condition (5.10.1 datasheet) 00136 // http://www.i2c-bus.org/repeated-start-condition/ 00137 if (nack) 00138 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00139 00140 char rx; 00141 nack = i2c->read(FXOS8700CQ_ADDR,&rx,1); // read a byte from the register and store in buffer 00142 if (nack) 00143 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00144 00145 return rx; 00146 } 00147 00148 // reads a series of bytes, starting from a specific register 00149 void FXOS8700CQ::read_bytes_from_reg(char reg,int number_of_bytes,char bytes[]) 00150 { 00151 int nack = i2c->write(FXOS8700CQ_ADDR,®,1,true); // send the slave write address and the configuration register address 00152 // true as need to send repeated start condition (5.10.1 datasheet) 00153 // http://www.i2c-bus.org/repeated-start-condition/ 00154 00155 if (nack) 00156 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00157 00158 nack = i2c->read(FXOS8700CQ_ADDR,bytes,number_of_bytes); // read bytes 00159 if (nack) 00160 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00161 00162 } 00163 00164 float FXOS8700CQ::get_roll_angle() 00165 { 00166 Data values = get_values(); 00167 float roll_rad = atan2(values.ay,values.az); 00168 return roll_rad*(360/3.14159265); 00169 } 00170 00171 float FXOS8700CQ::get_pitch_angle() 00172 { 00173 Data values = get_values(); 00174 float pitch_rad = atan2(-values.ax,sqrt((values.ay * values.ay) + (values.az * values.az))); 00175 return pitch_rad*(360/3.14159265); 00176 }
Generated on Wed Jul 13 2022 09:05:52 by
1.7.2