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 <cmath> 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 float FXOS8700CQ::get_pitch_angle(){ 00120 Data values = get_values(); 00121 float numerator = -1 * values.ax ; 00122 float squared_den = (values.ay * values.ay) + (values.az * values.az); 00123 float denomenator = sqrt(squared_den); 00124 float pitch_angle_radians = atan2(numerator , denomenator); 00125 float pitch_angle_degrees = pitch_angle_radians * (180 / 3.14159); 00126 return pitch_angle_degrees; 00127 } 00128 float FXOS8700CQ::get_roll_angle(){ 00129 Data values = get_values(); 00130 float roll_angle_radians = atan2(values.ay , values.az); 00131 float roll_angle_degrees = roll_angle_radians * (180 / 3.14159); 00132 return roll_angle_degrees; 00133 } 00134 00135 void FXOS8700CQ::send_byte_to_reg(char byte,char reg) 00136 { 00137 char data[2]; 00138 data[0] = reg; 00139 data[1] = byte; 00140 // send the register address, followed by the data 00141 int nack = i2c->write(FXOS8700CQ_ADDR,data,2); 00142 if (nack) 00143 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00144 00145 } 00146 00147 // reads a byte from a specific register 00148 char FXOS8700CQ::read_byte_from_reg(char reg) 00149 { 00150 int nack = i2c->write(FXOS8700CQ_ADDR,®,1,true); // send the register address to the slave 00151 // true as need to send repeated start condition (5.10.1 datasheet) 00152 // http://www.i2c-bus.org/repeated-start-condition/ 00153 if (nack) 00154 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00155 00156 char rx; 00157 nack = i2c->read(FXOS8700CQ_ADDR,&rx,1); // read a byte from the register and store in buffer 00158 if (nack) 00159 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00160 00161 return rx; 00162 } 00163 00164 // reads a series of bytes, starting from a specific register 00165 void FXOS8700CQ::read_bytes_from_reg(char reg,int number_of_bytes,char bytes[]) 00166 { 00167 int nack = i2c->write(FXOS8700CQ_ADDR,®,1,true); // send the slave write address and the configuration register address 00168 // true as need to send repeated start condition (5.10.1 datasheet) 00169 // http://www.i2c-bus.org/repeated-start-condition/ 00170 00171 if (nack) 00172 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00173 00174 nack = i2c->read(FXOS8700CQ_ADDR,bytes,number_of_bytes); // read bytes 00175 if (nack) 00176 error("No acknowledgement received!"); // if we don't receive acknowledgement, send error message 00177 00178 }
Generated on Mon Aug 8 2022 23:21:53 by
