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

Committer:
kenjiArai
Date:
Wed Jun 01 12:30:38 2016 +0000
Revision:
2:93141eb80862
Parent:
1:b022f8d7884d
Child:
3:24aa4d5fa7de
modified I2C read/write method

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kenjiArai 0:8de5e2fd5c48 1 /*
kenjiArai 0:8de5e2fd5c48 2 * mbed library program
kenjiArai 0:8de5e2fd5c48 3 * BMC050 COMPASS 6 AXIS, made by Bosch Sensortec
kenjiArai 0:8de5e2fd5c48 4 * http://jp.bosch-sensortec.com/content/language1/html/5033.htm
kenjiArai 0:8de5e2fd5c48 5 *
kenjiArai 2:93141eb80862 6 * Copyright (c) 2014, 2016 Kenji Arai / JH1PJL
kenjiArai 0:8de5e2fd5c48 7 * http://www.page.sannet.ne.jp/kenjia/index.html
kenjiArai 0:8de5e2fd5c48 8 * http://mbed.org/users/kenjiArai/
kenjiArai 0:8de5e2fd5c48 9 * Created: July 19th, 2014
kenjiArai 2:93141eb80862 10 * Revised: June 1st, 2016
kenjiArai 0:8de5e2fd5c48 11 *
kenjiArai 0:8de5e2fd5c48 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
kenjiArai 0:8de5e2fd5c48 13 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
kenjiArai 0:8de5e2fd5c48 14 * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kenjiArai 0:8de5e2fd5c48 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kenjiArai 0:8de5e2fd5c48 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kenjiArai 0:8de5e2fd5c48 17 */
kenjiArai 0:8de5e2fd5c48 18
kenjiArai 0:8de5e2fd5c48 19 #include "BMC050.h"
kenjiArai 0:8de5e2fd5c48 20
kenjiArai 2:93141eb80862 21 BMC050::BMC050 (
kenjiArai 2:93141eb80862 22 PinName p_sda, PinName p_scl,
kenjiArai 2:93141eb80862 23 const BMC050ACC_TypeDef *acc_parameter,
kenjiArai 2:93141eb80862 24 const BMC050MAG_TypeDef *mag_parameter) :
kenjiArai 2:93141eb80862 25 i2c(p_sda, p_scl)
kenjiArai 2:93141eb80862 26 {
kenjiArai 0:8de5e2fd5c48 27 initialize (acc_parameter, mag_parameter);
kenjiArai 0:8de5e2fd5c48 28 }
kenjiArai 0:8de5e2fd5c48 29
kenjiArai 2:93141eb80862 30 BMC050::BMC050 (
kenjiArai 2:93141eb80862 31 I2C& p_i2c,
kenjiArai 2:93141eb80862 32 const BMC050ACC_TypeDef *acc_parameter,
kenjiArai 2:93141eb80862 33 const BMC050MAG_TypeDef *mag_parameter) :
kenjiArai 2:93141eb80862 34 i2c(p_i2c)
kenjiArai 2:93141eb80862 35 {
kenjiArai 0:8de5e2fd5c48 36 initialize (acc_parameter, mag_parameter);
kenjiArai 0:8de5e2fd5c48 37 }
kenjiArai 0:8de5e2fd5c48 38
kenjiArai 2:93141eb80862 39 void BMC050::initialize (
kenjiArai 2:93141eb80862 40 const BMC050ACC_TypeDef *acc_parameter,
kenjiArai 2:93141eb80862 41 const BMC050MAG_TypeDef *mag_parameter)
kenjiArai 2:93141eb80862 42 {
kenjiArai 0:8de5e2fd5c48 43 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 44 // after power-on, mag chip is keeping "Suspend mode"!!
kenjiArai 0:8de5e2fd5c48 45 // -> Need to go "Normal mode" via "Sleep mode"
kenjiArai 0:8de5e2fd5c48 46 // step 1/start
kenjiArai 0:8de5e2fd5c48 47 mag_addr = mag_parameter->addr;
kenjiArai 1:b022f8d7884d 48 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 49 dbf[0] = BMC050_M_POWER_MODE;
kenjiArai 1:b022f8d7884d 50 dbf[1] = 0x01; // Power control bit on
kenjiArai 1:b022f8d7884d 51 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 52 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 53 dbf[1] = 0;
kenjiArai 1:b022f8d7884d 54 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 55 }
kenjiArai 0:8de5e2fd5c48 56 /////////////// Accelerometer configuration ////////////////
kenjiArai 0:8de5e2fd5c48 57 // Check acc chip is available of not
kenjiArai 0:8de5e2fd5c48 58 // step 1/start
kenjiArai 0:8de5e2fd5c48 59 acc_addr = acc_parameter->addr;
kenjiArai 0:8de5e2fd5c48 60 dbf[0] = BMC050_A_WHO_AM_I;
kenjiArai 1:b022f8d7884d 61 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 62 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 63 if (dbf[0] == I_AM_BMC050_ACC){ acc_ready = 1;
kenjiArai 0:8de5e2fd5c48 64 } else { acc_ready = 0; }
kenjiArai 0:8de5e2fd5c48 65 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 66 // after power-on, mag chip is keeping "Suspend mode"!!
kenjiArai 0:8de5e2fd5c48 67 // -> Need to go "Normal mode" via "Sleep mode"
kenjiArai 0:8de5e2fd5c48 68 // step 2
kenjiArai 1:b022f8d7884d 69 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 70 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 71 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 72 dbf[1] = 0;
kenjiArai 1:b022f8d7884d 73 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 74 }
kenjiArai 0:8de5e2fd5c48 75 /////////////// Accelerometer configuration ////////////////
kenjiArai 0:8de5e2fd5c48 76 // step 2/last
kenjiArai 0:8de5e2fd5c48 77 if ( acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 78 // set g-range
kenjiArai 0:8de5e2fd5c48 79 dbf[0] = BMC050_A_G_RANGE;
kenjiArai 0:8de5e2fd5c48 80 dbf[1] = acc_parameter->g_range;
kenjiArai 0:8de5e2fd5c48 81 switch (dbf[1]){
kenjiArai 0:8de5e2fd5c48 82 case BMC050_FS_2G:
kenjiArai 0:8de5e2fd5c48 83 fs_factor_acc = 256;
kenjiArai 0:8de5e2fd5c48 84 break;
kenjiArai 0:8de5e2fd5c48 85 case BMC050_FS_4G:
kenjiArai 0:8de5e2fd5c48 86 fs_factor_acc = 128;
kenjiArai 0:8de5e2fd5c48 87 break;
kenjiArai 0:8de5e2fd5c48 88 case BMC050_FS_8G:
kenjiArai 0:8de5e2fd5c48 89 fs_factor_acc = 64;
kenjiArai 0:8de5e2fd5c48 90 break;
kenjiArai 0:8de5e2fd5c48 91 case BMC050_FS_16G:
kenjiArai 0:8de5e2fd5c48 92 fs_factor_acc = 32;
kenjiArai 0:8de5e2fd5c48 93 break;
kenjiArai 0:8de5e2fd5c48 94 default:
kenjiArai 0:8de5e2fd5c48 95 fs_factor_acc = 256;
kenjiArai 0:8de5e2fd5c48 96 dbf[1] = BMC050_FS_2G;
kenjiArai 0:8de5e2fd5c48 97 }
kenjiArai 1:b022f8d7884d 98 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 99 // set bandwidth
kenjiArai 0:8de5e2fd5c48 100 dbf[1] = acc_parameter->bandwith;
kenjiArai 0:8de5e2fd5c48 101 if (dbf[1] == BMC050_NOT_FILTERED){
kenjiArai 0:8de5e2fd5c48 102 dbf[0] = BMC050_A_FILTER;
kenjiArai 0:8de5e2fd5c48 103 dbf[1] = 0x80;
kenjiArai 0:8de5e2fd5c48 104 } else {
kenjiArai 0:8de5e2fd5c48 105 dbf[0] = BMC050_A_BANDWIDTH;
kenjiArai 0:8de5e2fd5c48 106 }
kenjiArai 1:b022f8d7884d 107 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 108 }
kenjiArai 0:8de5e2fd5c48 109 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 110 // Check mag chip is available of not
kenjiArai 0:8de5e2fd5c48 111 // step 3/last
kenjiArai 1:b022f8d7884d 112 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 113 dbf[0] = BMC050_M_WHO_AM_I;
kenjiArai 1:b022f8d7884d 114 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 115 i2c.read(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 116 if (dbf[0] == I_AM_BMC050_MAG){ mag_ready = 1;
kenjiArai 1:b022f8d7884d 117 } else { mag_ready = 0; }
kenjiArai 1:b022f8d7884d 118 if ( mag_ready == 1){
kenjiArai 1:b022f8d7884d 119 // set output data rate
kenjiArai 1:b022f8d7884d 120 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 121 dbf[1] = mag_parameter->data_rate;
kenjiArai 1:b022f8d7884d 122 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 123 }
kenjiArai 0:8de5e2fd5c48 124 }
kenjiArai 0:8de5e2fd5c48 125 }
kenjiArai 0:8de5e2fd5c48 126
kenjiArai 1:b022f8d7884d 127 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 128 void BMC050::read_data_acc(float *dt) {
kenjiArai 0:8de5e2fd5c48 129 char data[6];
kenjiArai 0:8de5e2fd5c48 130
kenjiArai 0:8de5e2fd5c48 131 if (acc_ready == 0){
kenjiArai 0:8de5e2fd5c48 132 dt[0] = dt[1] = dt[2] = 0;
kenjiArai 0:8de5e2fd5c48 133 return;
kenjiArai 0:8de5e2fd5c48 134 }
kenjiArai 1:b022f8d7884d 135 // X,Y &Z
kenjiArai 0:8de5e2fd5c48 136 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 137 i2c.write(acc_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 138 i2c.read(acc_addr, data, 6, false);
kenjiArai 0:8de5e2fd5c48 139 // change data type
kenjiArai 0:8de5e2fd5c48 140 dt[0] = float((short(data[1] << 8 | data[0] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 141 dt[1] = float((short(data[3] << 8 | data[2] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 142 dt[2] = float((short(data[5] << 8 | data[4] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 143 }
kenjiArai 0:8de5e2fd5c48 144
kenjiArai 1:b022f8d7884d 145 /////////////// Accelerometer ///////////////////
kenjiArai 1:b022f8d7884d 146 void BMC050::read_mg_acc(float *dt) {
kenjiArai 1:b022f8d7884d 147 char data[6];
kenjiArai 1:b022f8d7884d 148
kenjiArai 1:b022f8d7884d 149 if (acc_ready == 0){
kenjiArai 1:b022f8d7884d 150 dt[0] = 0;
kenjiArai 1:b022f8d7884d 151 dt[1] = 0;
kenjiArai 1:b022f8d7884d 152 dt[2] = 0;
kenjiArai 1:b022f8d7884d 153 return;
kenjiArai 1:b022f8d7884d 154 }
kenjiArai 1:b022f8d7884d 155 // X,Y &Z
kenjiArai 1:b022f8d7884d 156 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 157 i2c.write(acc_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 158 i2c.read(acc_addr, data, 6, false);
kenjiArai 1:b022f8d7884d 159 // change data type
kenjiArai 1:b022f8d7884d 160 dt[0] = float((short(data[1] << 8 | data[0] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 161 dt[1] = float((short(data[3] << 8 | data[2] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 162 dt[2] = float((short(data[5] << 8 | data[4] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 163 }
kenjiArai 1:b022f8d7884d 164
kenjiArai 1:b022f8d7884d 165 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 166 void BMC050::read_data_mag(float *dt) {
kenjiArai 0:8de5e2fd5c48 167 char data[6];
kenjiArai 0:8de5e2fd5c48 168
kenjiArai 0:8de5e2fd5c48 169 if (mag_ready == 0){
kenjiArai 0:8de5e2fd5c48 170 dt[0] = dt[1] = dt[2] = 0;
kenjiArai 0:8de5e2fd5c48 171 return;
kenjiArai 0:8de5e2fd5c48 172 }
kenjiArai 1:b022f8d7884d 173 // X,Y &Z
kenjiArai 0:8de5e2fd5c48 174 dbf[0] = BMC050_M_OUT_X_L;
kenjiArai 1:b022f8d7884d 175 i2c.write(mag_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 176 i2c.read(mag_addr, data, 6, false);
kenjiArai 0:8de5e2fd5c48 177 // change data type
kenjiArai 0:8de5e2fd5c48 178 dt[0] = float((short(data[1] << 8 | data[0] & 0xf8))>> 3);
kenjiArai 0:8de5e2fd5c48 179 dt[1] = float((short(data[3] << 8 | data[2] & 0xf8))>> 3);
kenjiArai 0:8de5e2fd5c48 180 dt[2] = float((short(data[5] << 8 | data[4] & 0xfe))>> 1);
kenjiArai 0:8de5e2fd5c48 181 }
kenjiArai 0:8de5e2fd5c48 182
kenjiArai 1:b022f8d7884d 183 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 184 float BMC050::read_temp() {
kenjiArai 0:8de5e2fd5c48 185 dbf[0] = BMC050_A_OUT_TEMP;
kenjiArai 1:b022f8d7884d 186 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 187 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 188 return ((float)dbf[0] * 0.5 + 24.0);
kenjiArai 0:8de5e2fd5c48 189 }
kenjiArai 0:8de5e2fd5c48 190
kenjiArai 1:b022f8d7884d 191 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 192 uint8_t BMC050::read_id_acc() {
kenjiArai 0:8de5e2fd5c48 193 dbf[0] = BMC050_A_WHO_AM_I;
kenjiArai 1:b022f8d7884d 194 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 195 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 196 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 197 }
kenjiArai 0:8de5e2fd5c48 198
kenjiArai 1:b022f8d7884d 199 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 200 uint8_t BMC050::read_id_mag() {
kenjiArai 0:8de5e2fd5c48 201 dbf[0] = BMC050_M_WHO_AM_I;
kenjiArai 1:b022f8d7884d 202 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 203 i2c.read(mag_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 204 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 205 }
kenjiArai 0:8de5e2fd5c48 206
kenjiArai 1:b022f8d7884d 207 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 208 uint8_t BMC050::data_ready_acc() {
kenjiArai 0:8de5e2fd5c48 209 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 210 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 211 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 212 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 213 if (!(dbf[0] & 0x01)){
kenjiArai 0:8de5e2fd5c48 214 return 0;
kenjiArai 0:8de5e2fd5c48 215 }
kenjiArai 0:8de5e2fd5c48 216 }
kenjiArai 0:8de5e2fd5c48 217 return 1;
kenjiArai 0:8de5e2fd5c48 218 }
kenjiArai 0:8de5e2fd5c48 219
kenjiArai 1:b022f8d7884d 220 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 221 uint8_t BMC050::data_ready_mag() {
kenjiArai 0:8de5e2fd5c48 222 if (mag_ready == 1){
kenjiArai 0:8de5e2fd5c48 223 dbf[0] = BMC050_M_HALL_L;
kenjiArai 1:b022f8d7884d 224 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 225 i2c.read(mag_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 226 if (!(dbf[0] & 0x01)){
kenjiArai 0:8de5e2fd5c48 227 return 0;
kenjiArai 0:8de5e2fd5c48 228 }
kenjiArai 0:8de5e2fd5c48 229 }
kenjiArai 0:8de5e2fd5c48 230 return 1;
kenjiArai 0:8de5e2fd5c48 231 }
kenjiArai 0:8de5e2fd5c48 232
kenjiArai 1:b022f8d7884d 233 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 234 uint8_t BMC050::read_reg_acc(uint8_t addr) {
kenjiArai 0:8de5e2fd5c48 235 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 236 dbf[0] = addr;
kenjiArai 1:b022f8d7884d 237 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 238 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 239 } else {
kenjiArai 0:8de5e2fd5c48 240 dbf[0] = 0xff;
kenjiArai 0:8de5e2fd5c48 241 }
kenjiArai 0:8de5e2fd5c48 242 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 243 }
kenjiArai 0:8de5e2fd5c48 244
kenjiArai 1:b022f8d7884d 245 /////////////// Magnetometer ////////////////////
kenjiArai 1:b022f8d7884d 246 uint8_t BMC050::read_reg_mag(uint8_t addr) {
kenjiArai 1:b022f8d7884d 247 if (mag_ready == 1){
kenjiArai 1:b022f8d7884d 248 dbf[0] = addr;
kenjiArai 1:b022f8d7884d 249 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 250 i2c.read(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 251 } else {
kenjiArai 1:b022f8d7884d 252 dbf[0] = 0xff;
kenjiArai 1:b022f8d7884d 253 }
kenjiArai 1:b022f8d7884d 254 return (uint8_t)dbf[0];
kenjiArai 1:b022f8d7884d 255 }
kenjiArai 1:b022f8d7884d 256
kenjiArai 1:b022f8d7884d 257 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 258 void BMC050::write_reg_acc(uint8_t addr, uint8_t data) {
kenjiArai 0:8de5e2fd5c48 259 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 260 dbf[0] = addr;
kenjiArai 0:8de5e2fd5c48 261 dbf[1] = data;
kenjiArai 1:b022f8d7884d 262 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 263 }
kenjiArai 0:8de5e2fd5c48 264 }
kenjiArai 0:8de5e2fd5c48 265
kenjiArai 1:b022f8d7884d 266 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 267 void BMC050::write_reg_mag(uint8_t addr, uint8_t data) {
kenjiArai 0:8de5e2fd5c48 268 if (mag_ready == 1){
kenjiArai 0:8de5e2fd5c48 269 dbf[0] = addr;
kenjiArai 0:8de5e2fd5c48 270 dbf[1] = data;
kenjiArai 1:b022f8d7884d 271 i2c.write(mag_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 272 }
kenjiArai 0:8de5e2fd5c48 273 }
kenjiArai 0:8de5e2fd5c48 274
kenjiArai 1:b022f8d7884d 275 /////////////// Common //////////////////////////
kenjiArai 1:b022f8d7884d 276 void BMC050::frequency(int hz) {
kenjiArai 1:b022f8d7884d 277 i2c.frequency(hz);
kenjiArai 0:8de5e2fd5c48 278 }