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:
Sun Sep 07 07:15:37 2014 +0000
Revision:
1:b022f8d7884d
Parent:
0:8de5e2fd5c48
Child:
2:93141eb80862
modified n-byte read/write function,  added clock frequency change function

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 0:8de5e2fd5c48 6 * Copyright (c) 2014 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 1:b022f8d7884d 10 * Revised: September 7th, 2014
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 0:8de5e2fd5c48 21 BMC050::BMC050 (PinName p_sda, PinName p_scl,
kenjiArai 0:8de5e2fd5c48 22 const BMC050ACC_TypeDef *acc_parameter, const BMC050MAG_TypeDef *mag_parameter) :
kenjiArai 0:8de5e2fd5c48 23 i2c(p_sda, p_scl) {
kenjiArai 0:8de5e2fd5c48 24 initialize (acc_parameter, mag_parameter);
kenjiArai 0:8de5e2fd5c48 25 }
kenjiArai 0:8de5e2fd5c48 26
kenjiArai 0:8de5e2fd5c48 27 BMC050::BMC050 (I2C& p_i2c,
kenjiArai 0:8de5e2fd5c48 28 const BMC050ACC_TypeDef *acc_parameter, const BMC050MAG_TypeDef *mag_parameter) : i2c(p_i2c) {
kenjiArai 0:8de5e2fd5c48 29 initialize (acc_parameter, mag_parameter);
kenjiArai 0:8de5e2fd5c48 30 }
kenjiArai 0:8de5e2fd5c48 31
kenjiArai 0:8de5e2fd5c48 32 void BMC050::initialize (const BMC050ACC_TypeDef *acc_parameter,
kenjiArai 0:8de5e2fd5c48 33 const BMC050MAG_TypeDef *mag_parameter) {
kenjiArai 0:8de5e2fd5c48 34 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 35 // after power-on, mag chip is keeping "Suspend mode"!!
kenjiArai 0:8de5e2fd5c48 36 // -> Need to go "Normal mode" via "Sleep mode"
kenjiArai 0:8de5e2fd5c48 37 // step 1/start
kenjiArai 0:8de5e2fd5c48 38 mag_addr = mag_parameter->addr;
kenjiArai 1:b022f8d7884d 39 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 40 dbf[0] = BMC050_M_POWER_MODE;
kenjiArai 1:b022f8d7884d 41 dbf[1] = 0x01; // Power control bit on
kenjiArai 1:b022f8d7884d 42 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 43 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 44 dbf[1] = 0;
kenjiArai 1:b022f8d7884d 45 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 46 }
kenjiArai 0:8de5e2fd5c48 47 /////////////// Accelerometer configuration ////////////////
kenjiArai 0:8de5e2fd5c48 48 // Check acc chip is available of not
kenjiArai 0:8de5e2fd5c48 49 // step 1/start
kenjiArai 0:8de5e2fd5c48 50 acc_addr = acc_parameter->addr;
kenjiArai 0:8de5e2fd5c48 51 dbf[0] = BMC050_A_WHO_AM_I;
kenjiArai 1:b022f8d7884d 52 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 53 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 54 if (dbf[0] == I_AM_BMC050_ACC){ acc_ready = 1;
kenjiArai 0:8de5e2fd5c48 55 } else { acc_ready = 0; }
kenjiArai 0:8de5e2fd5c48 56 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 57 // after power-on, mag chip is keeping "Suspend mode"!!
kenjiArai 0:8de5e2fd5c48 58 // -> Need to go "Normal mode" via "Sleep mode"
kenjiArai 0:8de5e2fd5c48 59 // step 2
kenjiArai 1:b022f8d7884d 60 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 61 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 62 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 63 dbf[1] = 0;
kenjiArai 1:b022f8d7884d 64 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 65 }
kenjiArai 0:8de5e2fd5c48 66 /////////////// Accelerometer configuration ////////////////
kenjiArai 0:8de5e2fd5c48 67 // step 2/last
kenjiArai 0:8de5e2fd5c48 68 if ( acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 69 // set g-range
kenjiArai 0:8de5e2fd5c48 70 dbf[0] = BMC050_A_G_RANGE;
kenjiArai 0:8de5e2fd5c48 71 dbf[1] = acc_parameter->g_range;
kenjiArai 0:8de5e2fd5c48 72 switch (dbf[1]){
kenjiArai 0:8de5e2fd5c48 73 case BMC050_FS_2G:
kenjiArai 0:8de5e2fd5c48 74 fs_factor_acc = 256;
kenjiArai 0:8de5e2fd5c48 75 break;
kenjiArai 0:8de5e2fd5c48 76 case BMC050_FS_4G:
kenjiArai 0:8de5e2fd5c48 77 fs_factor_acc = 128;
kenjiArai 0:8de5e2fd5c48 78 break;
kenjiArai 0:8de5e2fd5c48 79 case BMC050_FS_8G:
kenjiArai 0:8de5e2fd5c48 80 fs_factor_acc = 64;
kenjiArai 0:8de5e2fd5c48 81 break;
kenjiArai 0:8de5e2fd5c48 82 case BMC050_FS_16G:
kenjiArai 0:8de5e2fd5c48 83 fs_factor_acc = 32;
kenjiArai 0:8de5e2fd5c48 84 break;
kenjiArai 0:8de5e2fd5c48 85 default:
kenjiArai 0:8de5e2fd5c48 86 fs_factor_acc = 256;
kenjiArai 0:8de5e2fd5c48 87 dbf[1] = BMC050_FS_2G;
kenjiArai 0:8de5e2fd5c48 88 }
kenjiArai 1:b022f8d7884d 89 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 90 // set bandwidth
kenjiArai 0:8de5e2fd5c48 91 dbf[1] = acc_parameter->bandwith;
kenjiArai 0:8de5e2fd5c48 92 if (dbf[1] == BMC050_NOT_FILTERED){
kenjiArai 0:8de5e2fd5c48 93 dbf[0] = BMC050_A_FILTER;
kenjiArai 0:8de5e2fd5c48 94 dbf[1] = 0x80;
kenjiArai 0:8de5e2fd5c48 95 } else {
kenjiArai 0:8de5e2fd5c48 96 dbf[0] = BMC050_A_BANDWIDTH;
kenjiArai 0:8de5e2fd5c48 97 }
kenjiArai 1:b022f8d7884d 98 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 99 }
kenjiArai 0:8de5e2fd5c48 100 /////////////// Magnetometer Configuration /////////////////
kenjiArai 0:8de5e2fd5c48 101 // Check mag chip is available of not
kenjiArai 0:8de5e2fd5c48 102 // step 3/last
kenjiArai 1:b022f8d7884d 103 if (mag_addr != BMC050_MAG_NOT_USED_ADDR) {
kenjiArai 1:b022f8d7884d 104 dbf[0] = BMC050_M_WHO_AM_I;
kenjiArai 1:b022f8d7884d 105 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 106 i2c.read(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 107 if (dbf[0] == I_AM_BMC050_MAG){ mag_ready = 1;
kenjiArai 1:b022f8d7884d 108 } else { mag_ready = 0; }
kenjiArai 1:b022f8d7884d 109 if ( mag_ready == 1){
kenjiArai 1:b022f8d7884d 110 // set output data rate
kenjiArai 1:b022f8d7884d 111 dbf[0] = BMC050_M_OPERATION;
kenjiArai 1:b022f8d7884d 112 dbf[1] = mag_parameter->data_rate;
kenjiArai 1:b022f8d7884d 113 i2c.write(mag_addr, dbf, 2);
kenjiArai 1:b022f8d7884d 114 }
kenjiArai 0:8de5e2fd5c48 115 }
kenjiArai 0:8de5e2fd5c48 116 }
kenjiArai 0:8de5e2fd5c48 117
kenjiArai 1:b022f8d7884d 118 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 119 void BMC050::read_data_acc(float *dt) {
kenjiArai 0:8de5e2fd5c48 120 char data[6];
kenjiArai 0:8de5e2fd5c48 121
kenjiArai 0:8de5e2fd5c48 122 if (acc_ready == 0){
kenjiArai 0:8de5e2fd5c48 123 dt[0] = dt[1] = dt[2] = 0;
kenjiArai 0:8de5e2fd5c48 124 return;
kenjiArai 0:8de5e2fd5c48 125 }
kenjiArai 1:b022f8d7884d 126 // X,Y &Z
kenjiArai 0:8de5e2fd5c48 127 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 128 i2c.write(acc_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 129 i2c.read(acc_addr, data, 6, false);
kenjiArai 0:8de5e2fd5c48 130 // change data type
kenjiArai 0:8de5e2fd5c48 131 dt[0] = float((short(data[1] << 8 | data[0] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 132 dt[1] = float((short(data[3] << 8 | data[2] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 133 dt[2] = float((short(data[5] << 8 | data[4] & 0xc0))>> 6) * GRAVITY / fs_factor_acc;
kenjiArai 0:8de5e2fd5c48 134 }
kenjiArai 0:8de5e2fd5c48 135
kenjiArai 1:b022f8d7884d 136 /////////////// Accelerometer ///////////////////
kenjiArai 1:b022f8d7884d 137 void BMC050::read_mg_acc(float *dt) {
kenjiArai 1:b022f8d7884d 138 char data[6];
kenjiArai 1:b022f8d7884d 139
kenjiArai 1:b022f8d7884d 140 if (acc_ready == 0){
kenjiArai 1:b022f8d7884d 141 dt[0] = 0;
kenjiArai 1:b022f8d7884d 142 dt[1] = 0;
kenjiArai 1:b022f8d7884d 143 dt[2] = 0;
kenjiArai 1:b022f8d7884d 144 return;
kenjiArai 1:b022f8d7884d 145 }
kenjiArai 1:b022f8d7884d 146 // X,Y &Z
kenjiArai 1:b022f8d7884d 147 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 148 i2c.write(acc_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 149 i2c.read(acc_addr, data, 6, false);
kenjiArai 1:b022f8d7884d 150 // change data type
kenjiArai 1:b022f8d7884d 151 dt[0] = float((short(data[1] << 8 | data[0] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 152 dt[1] = float((short(data[3] << 8 | data[2] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 153 dt[2] = float((short(data[5] << 8 | data[4] & 0xc0))>> 6) / fs_factor_acc;
kenjiArai 1:b022f8d7884d 154 }
kenjiArai 1:b022f8d7884d 155
kenjiArai 1:b022f8d7884d 156 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 157 void BMC050::read_data_mag(float *dt) {
kenjiArai 0:8de5e2fd5c48 158 char data[6];
kenjiArai 0:8de5e2fd5c48 159
kenjiArai 0:8de5e2fd5c48 160 if (mag_ready == 0){
kenjiArai 0:8de5e2fd5c48 161 dt[0] = dt[1] = dt[2] = 0;
kenjiArai 0:8de5e2fd5c48 162 return;
kenjiArai 0:8de5e2fd5c48 163 }
kenjiArai 1:b022f8d7884d 164 // X,Y &Z
kenjiArai 0:8de5e2fd5c48 165 dbf[0] = BMC050_M_OUT_X_L;
kenjiArai 1:b022f8d7884d 166 i2c.write(mag_addr, dbf, 1, true);
kenjiArai 1:b022f8d7884d 167 i2c.read(mag_addr, data, 6, false);
kenjiArai 0:8de5e2fd5c48 168 // change data type
kenjiArai 0:8de5e2fd5c48 169 dt[0] = float((short(data[1] << 8 | data[0] & 0xf8))>> 3);
kenjiArai 0:8de5e2fd5c48 170 dt[1] = float((short(data[3] << 8 | data[2] & 0xf8))>> 3);
kenjiArai 0:8de5e2fd5c48 171 dt[2] = float((short(data[5] << 8 | data[4] & 0xfe))>> 1);
kenjiArai 0:8de5e2fd5c48 172 }
kenjiArai 0:8de5e2fd5c48 173
kenjiArai 1:b022f8d7884d 174 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 175 float BMC050::read_temp() {
kenjiArai 0:8de5e2fd5c48 176 dbf[0] = BMC050_A_OUT_TEMP;
kenjiArai 1:b022f8d7884d 177 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 178 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 179 return ((float)dbf[0] * 0.5 + 24.0);
kenjiArai 0:8de5e2fd5c48 180 }
kenjiArai 0:8de5e2fd5c48 181
kenjiArai 1:b022f8d7884d 182 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 183 uint8_t BMC050::read_id_acc() {
kenjiArai 0:8de5e2fd5c48 184 dbf[0] = BMC050_A_WHO_AM_I;
kenjiArai 1:b022f8d7884d 185 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 186 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 187 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 188 }
kenjiArai 0:8de5e2fd5c48 189
kenjiArai 1:b022f8d7884d 190 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 191 uint8_t BMC050::read_id_mag() {
kenjiArai 0:8de5e2fd5c48 192 dbf[0] = BMC050_M_WHO_AM_I;
kenjiArai 1:b022f8d7884d 193 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 194 i2c.read(mag_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 195 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 196 }
kenjiArai 0:8de5e2fd5c48 197
kenjiArai 1:b022f8d7884d 198 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 199 uint8_t BMC050::data_ready_acc() {
kenjiArai 0:8de5e2fd5c48 200 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 201 dbf[0] = BMC050_A_OUT_X_L;
kenjiArai 1:b022f8d7884d 202 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 203 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 204 if (!(dbf[0] & 0x01)){
kenjiArai 0:8de5e2fd5c48 205 return 0;
kenjiArai 0:8de5e2fd5c48 206 }
kenjiArai 0:8de5e2fd5c48 207 }
kenjiArai 0:8de5e2fd5c48 208 return 1;
kenjiArai 0:8de5e2fd5c48 209 }
kenjiArai 0:8de5e2fd5c48 210
kenjiArai 1:b022f8d7884d 211 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 212 uint8_t BMC050::data_ready_mag() {
kenjiArai 0:8de5e2fd5c48 213 if (mag_ready == 1){
kenjiArai 0:8de5e2fd5c48 214 dbf[0] = BMC050_M_HALL_L;
kenjiArai 1:b022f8d7884d 215 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 216 i2c.read(mag_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 217 if (!(dbf[0] & 0x01)){
kenjiArai 0:8de5e2fd5c48 218 return 0;
kenjiArai 0:8de5e2fd5c48 219 }
kenjiArai 0:8de5e2fd5c48 220 }
kenjiArai 0:8de5e2fd5c48 221 return 1;
kenjiArai 0:8de5e2fd5c48 222 }
kenjiArai 0:8de5e2fd5c48 223
kenjiArai 1:b022f8d7884d 224 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 225 uint8_t BMC050::read_reg_acc(uint8_t addr) {
kenjiArai 0:8de5e2fd5c48 226 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 227 dbf[0] = addr;
kenjiArai 1:b022f8d7884d 228 i2c.write(acc_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 229 i2c.read(acc_addr, dbf, 1);
kenjiArai 0:8de5e2fd5c48 230 } else {
kenjiArai 0:8de5e2fd5c48 231 dbf[0] = 0xff;
kenjiArai 0:8de5e2fd5c48 232 }
kenjiArai 0:8de5e2fd5c48 233 return (uint8_t)dbf[0];
kenjiArai 0:8de5e2fd5c48 234 }
kenjiArai 0:8de5e2fd5c48 235
kenjiArai 1:b022f8d7884d 236 /////////////// Magnetometer ////////////////////
kenjiArai 1:b022f8d7884d 237 uint8_t BMC050::read_reg_mag(uint8_t addr) {
kenjiArai 1:b022f8d7884d 238 if (mag_ready == 1){
kenjiArai 1:b022f8d7884d 239 dbf[0] = addr;
kenjiArai 1:b022f8d7884d 240 i2c.write(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 241 i2c.read(mag_addr, dbf, 1);
kenjiArai 1:b022f8d7884d 242 } else {
kenjiArai 1:b022f8d7884d 243 dbf[0] = 0xff;
kenjiArai 1:b022f8d7884d 244 }
kenjiArai 1:b022f8d7884d 245 return (uint8_t)dbf[0];
kenjiArai 1:b022f8d7884d 246 }
kenjiArai 1:b022f8d7884d 247
kenjiArai 1:b022f8d7884d 248 /////////////// Accelerometer ///////////////////
kenjiArai 0:8de5e2fd5c48 249 void BMC050::write_reg_acc(uint8_t addr, uint8_t data) {
kenjiArai 0:8de5e2fd5c48 250 if (acc_ready == 1){
kenjiArai 0:8de5e2fd5c48 251 dbf[0] = addr;
kenjiArai 0:8de5e2fd5c48 252 dbf[1] = data;
kenjiArai 1:b022f8d7884d 253 i2c.write(acc_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 254 }
kenjiArai 0:8de5e2fd5c48 255 }
kenjiArai 0:8de5e2fd5c48 256
kenjiArai 1:b022f8d7884d 257 /////////////// Magnetometer ////////////////////
kenjiArai 0:8de5e2fd5c48 258 void BMC050::write_reg_mag(uint8_t addr, uint8_t data) {
kenjiArai 0:8de5e2fd5c48 259 if (mag_ready == 1){
kenjiArai 0:8de5e2fd5c48 260 dbf[0] = addr;
kenjiArai 0:8de5e2fd5c48 261 dbf[1] = data;
kenjiArai 1:b022f8d7884d 262 i2c.write(mag_addr, dbf, 2);
kenjiArai 0:8de5e2fd5c48 263 }
kenjiArai 0:8de5e2fd5c48 264 }
kenjiArai 0:8de5e2fd5c48 265
kenjiArai 1:b022f8d7884d 266 /////////////// Common //////////////////////////
kenjiArai 1:b022f8d7884d 267 void BMC050::frequency(int hz) {
kenjiArai 1:b022f8d7884d 268 i2c.frequency(hz);
kenjiArai 0:8de5e2fd5c48 269 }