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

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