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