eCompass (6-axes electronic compass) / Electronic Compass with Three-axis Magnetic Field Sensor and Three-axis Accelerometer by Bosch Sensortech
Dependents: BLE_EddystoneBeacon_w_ACC_TY51822
Diff: BMC050.h
- Revision:
- 0:8de5e2fd5c48
- Child:
- 1:b022f8d7884d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMC050.h Sun Jul 20 13:16:25 2014 +0000 @@ -0,0 +1,268 @@ +/* + * mbed library program + * BMC050 COMPASS 6 AXIS, made by Bosch Sensortec + * http://jp.bosch-sensortec.com/content/language1/html/5033.htm + * + * Copyright (c) 2014 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * Created: July 19th, 2014 + * Revised: July 20th, 2014 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef BMC050_H +#define BMC050_H + +#include "mbed.h" + +////////////// ADDRESS DEFINITION ///////////////////////////////////////////// +// BMC050 Address/accelerometer +// 7bit address = 0b001100x(0x18 or 0x19 depends on SDO) +// -> 8bit = 0b001100x0(0x30,0x32) -> 0x31,0x33(Read) or 0x30,0x32(Write) +#define BMC050_A_G_CHIP_ADDR 0x30 // SDO pin = Ground +#define BMC050_A_V_CHIP_ADDR 0x32 // SDO pin = Vdd +// BMC050 Address/magnetometer +// 7bit address = 0b001000x(0x10,0x11,0x12 or 0x13 depends on SDO and CSB2) +// -> 8bit = 0b00100xx0(0x20,0x22,0x24,0x26) +#define BMC050_M_GG_CHIP_ADDR 0x20 // CSB2 pin = Ground, SDO pin = Ground +#define BMC050_M_GV_CHIP_ADDR 0x22 // CSB2 pin = Ground, SDO pin = Vdd +#define BMC050_M_VG_CHIP_ADDR 0x24 // CSB2 pin = Vdd, SDO pin = Ground +#define BMC050_M_VV_CHIP_ADDR 0x26 // CSB2 pin = Vdd, SDO pin = Vdd + +// BMC050 ACC ID +#define I_AM_BMC050_ACC 0x03 +// BMC050 ACC ID +#define I_AM_BMC050_MAG 0x32 + +////////////// REGISTER DEFINITION //////////////////////////////////////////// +// accelerometer +#define BMC050_A_WHO_AM_I 0x00 +// reserved +#define BMC050_A_OUT_X_L 0x02 +#define BMC050_A_OUT_X_H 0x03 +#define BMC050_A_OUT_Y_L 0x04 +#define BMC050_A_OUT_Y_H 0x05 +#define BMC050_A_OUT_Z_L 0x06 +#define BMC050_A_OUT_Z_H 0x07 +#define BMC050_A_OUT_TEMP 0x08 +#define BMC050_A_STATUS_REG0 0x09 +#define BMC050_A_STATUS_REG1 0x0a +#define BMC050_A_STATUS_REG2 0x0b +#define BMC050_A_STATUS_REG3 0x0c +// reserved +// reserved +#define BMC050_A_G_RANGE 0x0f +#define BMC050_A_BANDWIDTH 0x10 +#define BMC050_A_POWER_MODE 0x11 +// reserved +#define BMC050_A_FILTER 0x13 +#define BMC050_A_SW_RESET 0x14 +// not implement yet 0x15 to 0x35 +#define BMC050_A_OFST_COMP0 0x36 +#define BMC050_A_OFST_COMP1 0x37 +#define BMC050_A_OFST_COMP_DX 0x38 +#define BMC050_A_OFST_COMP_DY 0x39 +#define BMC050_A_OFST_COMP_DZ 0x3a +#define BMC050_A_OFST_COMP_DX_UF 0x3b +#define BMC050_A_OFST_COMP_DY_UF 0x3c +#define BMC050_A_OFST_COMP_DZ_UF 0x3d + +// magnetometer +#define BMC050_M_WHO_AM_I 0x40 +// reserved +#define BMC050_M_OUT_X_L 0x42 +#define BMC050_M_OUT_X_H 0x43 +#define BMC050_M_OUT_Y_L 0x44 +#define BMC050_M_OUT_Y_H 0x45 +#define BMC050_M_OUT_Z_L 0x46 +#define BMC050_M_OUT_Z_H 0x47 +#define BMC050_M_HALL_L 0x48 +#define BMC050_M_HALL_H 0x49 +#define BMC050_M_INTERRUPT 0x4a +#define BMC050_M_POWER_MODE 0x4b +#define BMC050_M_OPERATION 0x4c +// not implement yet 0x4d to 0x50 +#define BMC050_M_REPETITION_XY 0x51 +#define BMC050_M_REPETITION_Z 0x51 + +////////////// CONTROL DEFINITION ///////////////////////////////////////////// +// Full Scale +#define BMC050_FS_2G 0x03 +#define BMC050_FS_4G 0x05 +#define BMC050_FS_8G 0x08 +#define BMC050_FS_16G 0x0c +// Bandwidth (Low pass) +#define BMC050_NOT_FILTERED 0x00 +#define BMC050_BW_7R81 0x08 +#define BMC050_BW_15R63 0x09 +#define BMC050_BW_31R25 0x0a +#define BMC050_BW_62R5 0x0b +#define BMC050_BW_125 0x0c +#define BMC050_BW_250 0x0d +#define BMC050_BW_500 0x0e +#define BMC050_BW_1000 0x0f + +// Output Data Rate (ODR) +#define BMC050_DR_10 0 +#define BMC050_DR_2 1 +#define BMC050_DR_6 2 +#define BMC050_DR_8 3 +#define BMC050_DR_15 4 +#define BMC050_DR_20 5 +#define BMC050_DR_25 6 +#define BMC050_DR_30 7 + +// definition for Nomalization +#define GRAVITY (9.80665F) +#define BMC050_GAIN (3.91F) + +////////////// DATA TYPE DEFINITION /////////////////////////////////////////// +typedef struct { + uint8_t addr; + uint8_t g_range; + uint8_t bandwith; + uint8_t filter; +} BMC050ACC_TypeDef; + +typedef struct { + uint8_t addr; + uint8_t data_rate; +} BMC050MAG_TypeDef; + +/** Interface for Bosch Sensortec COMPASS 6 AXIS + * Chip: BMC050, two chips configuration (Accelerometer 3axis & Magnetometer 3axis) + * + * @code + * #include "mbed.h" + * + * const BMC050ACC_TypeDef acc_parameter = { + * BMC050_A_G_CHIP_ADDR, // I2C Address + * BMC050_FS_2G, // G-range slection + * BMC050_BW_250, // Bandwidth + * }; + * + * const BMC050MAG_TypeDef mag_parameter = { + * BMC050_M_GG_CHIP_ADDR,// I2C Address + * BMC050_DR_10 // Data Rate + * }; + * + * // I2C Communication + * I2C i2c(dp5,dp27); // SDA, SCL + * BMC050 bmc050(i2c, &acc_parameter, &mag_parameter); + * + * int main() { + * float fa[3]; + * float fg[3]; + * + * if (bmc050.read_id_acc() == BMC050_A_G_CHIP_ADDR){ + * bmc050.read_data_acc(fa); + * } + * if (bmc050.read_id_mag() == BMC050_M_GG_CHIP_ADDR){ + * bmc050.read_data_mag(fg); + * } + * } + * @endcode + */ + +class BMC050{ +public: + /** Configure data pin + * @param data SDA and SCL pins + * @param parameter address for acc (BMC050ACC_TypeDef) + * @param parameter address for mag (BMC050MAG_TypeDef) + */ + BMC050(PinName p_sda, PinName p_scl, + const BMC050ACC_TypeDef *acc_parameter, const BMC050MAG_TypeDef *mag_parameter); + + /** Configure data pin (with other devices on I2C line) + * @param I2C previous definition + * @param other parameters -> please see BMC050(PinName p_sda, PinName p_scl,...) + */ + BMC050(I2C& p_i2c, + const BMC050ACC_TypeDef *acc_parameter, const BMC050MAG_TypeDef *mag_parameter); + + /** Read a float type data from accelerometer + * @param float type of three arry's address, e.g. float dt[3]; + * @return acc motion data unit: m/s/s + * @return dt[0]->x, dt[1]->y, dt[2]->z + */ + void read_data_acc(float *dt); + + /** Read a float type data from magnetometer + * @param float type of three arry's address, e.g. float dt[3]; + * @return magnettic field data unit: uT(micro T) + * @return dt[0]->x, dt[1]->y, dt[2]->z + */ + void read_data_mag(float *dt); + + /** Read temperature data + * @param none + * @return temperature unit: deg.C + */ + float read_temp(); + + /** Read a acc chip ID number + * @param none + * @return should be I_AM_BMC050_ACC(0x03) + */ + uint8_t read_id_acc(); + + /** Read a mag chip ID number + * @param none + * @return should be I_AM_BMC050_MAG(0x32) + */ + uint8_t read_id_mag(); + + /** Read Data Ready flag /Acc + * @param none + * @return 1 = Ready + */ + uint8_t data_ready_acc(); + + /** Read Data Ready flag /Mag + * @param none + * @return 1 = Ready + */ + uint8_t data_ready_mag(); + + /** Read register (general purpose) + * @param register's address + * @return register data + */ + uint8_t read_reg_acc(uint8_t addr); + uint8_t read_reg_mag(uint8_t addr); + + /** Write register (general purpose) + * @param register's address + * @param data + * @return none + */ + void write_reg_acc(uint8_t addr, uint8_t data); + void write_reg_mag(uint8_t addr, uint8_t data); + +protected: + void initialize(const BMC050ACC_TypeDef *acc_parameter, + const BMC050MAG_TypeDef *mag_parameter); + void i2c_read_n_bytes(int, char*, int); + void i2c_write_n_bytes(int, char*, int); + + I2C i2c; + +private: + float fs_factor_acc;// full scale factor + char dbf[2]; // working buffer + uint8_t acc_addr; // acc sensor address + uint8_t acc_id; // acc ID + uint8_t acc_ready; // acc is on I2C line = 1, not = 0 + uint8_t mag_addr; // mag sensor address + uint8_t mag_id; // mag ID + uint8_t mag_ready; // mag is on I2C line = 1, not = 0 +}; + +#endif // BMC050_H