IOTON boards API using mbed SDK - http://ioton.cc/plataforma-ton

Dependents:   ton-bot_teste ton-bot_seguidor_linha ton-bot_seguidor_parede

Fork of IOTON-API by Kleber Silva

Committer:
krebyy
Date:
Tue Nov 08 00:17:12 2016 +0000
Revision:
0:cbba28a205fa
Child:
2:b3c3bf0b9101
First commit - to use with the mbed online compiler

Who changed what in which revision?

UserRevisionLine numberNew contents of line
krebyy 0:cbba28a205fa 1 /* IMU chipset BMX055 Library
krebyy 0:cbba28a205fa 2 * Copyright (c) 2016 Ioton Technology
krebyy 0:cbba28a205fa 3 *
krebyy 0:cbba28a205fa 4 * Licensed under the Apache License, Version 2.0 (the "License");
krebyy 0:cbba28a205fa 5 * you may not use this file except in compliance with the License.
krebyy 0:cbba28a205fa 6 * You may obtain a copy of the License at
krebyy 0:cbba28a205fa 7 *
krebyy 0:cbba28a205fa 8 * http://www.apache.org/licenses/LICENSE-2.0
krebyy 0:cbba28a205fa 9 *
krebyy 0:cbba28a205fa 10 * Unless required by applicable law or agreed to in writing, software
krebyy 0:cbba28a205fa 11 * distributed under the License is distributed on an "AS IS" BASIS,
krebyy 0:cbba28a205fa 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
krebyy 0:cbba28a205fa 13 * See the License for the specific language governing permissions and
krebyy 0:cbba28a205fa 14 * limitations under the License.
krebyy 0:cbba28a205fa 15 */
krebyy 0:cbba28a205fa 16
krebyy 0:cbba28a205fa 17 #ifndef BMX055_H_
krebyy 0:cbba28a205fa 18 #define BMX055_H_
krebyy 0:cbba28a205fa 19
krebyy 0:cbba28a205fa 20 /* Includes ------------------------------------------------------------------*/
krebyy 0:cbba28a205fa 21 #include "mbed.h"
krebyy 0:cbba28a205fa 22
krebyy 0:cbba28a205fa 23
krebyy 0:cbba28a205fa 24 #ifndef M_PI
krebyy 0:cbba28a205fa 25 #define M_PI 3.1415927
krebyy 0:cbba28a205fa 26 #endif
krebyy 0:cbba28a205fa 27
krebyy 0:cbba28a205fa 28 // Accelerometer registers
krebyy 0:cbba28a205fa 29 #define BMX055_ACC_WHOAMI 0x00 // should return 0xFA
krebyy 0:cbba28a205fa 30 //#define BMX055_ACC_Reserved 0x01
krebyy 0:cbba28a205fa 31 #define BMX055_ACC_D_X_LSB 0x02
krebyy 0:cbba28a205fa 32 #define BMX055_ACC_D_X_MSB 0x03
krebyy 0:cbba28a205fa 33 #define BMX055_ACC_D_Y_LSB 0x04
krebyy 0:cbba28a205fa 34 #define BMX055_ACC_D_Y_MSB 0x05
krebyy 0:cbba28a205fa 35 #define BMX055_ACC_D_Z_LSB 0x06
krebyy 0:cbba28a205fa 36 #define BMX055_ACC_D_Z_MSB 0x07
krebyy 0:cbba28a205fa 37 #define BMX055_ACC_D_TEMP 0x08
krebyy 0:cbba28a205fa 38 #define BMX055_ACC_INT_STATUS_0 0x09
krebyy 0:cbba28a205fa 39 #define BMX055_ACC_INT_STATUS_1 0x0A
krebyy 0:cbba28a205fa 40 #define BMX055_ACC_INT_STATUS_2 0x0B
krebyy 0:cbba28a205fa 41 #define BMX055_ACC_INT_STATUS_3 0x0C
krebyy 0:cbba28a205fa 42 //#define BMX055_ACC_Reserved 0x0D
krebyy 0:cbba28a205fa 43 #define BMX055_ACC_FIFO_STATUS 0x0E
krebyy 0:cbba28a205fa 44 #define BMX055_ACC_PMU_RANGE 0x0F
krebyy 0:cbba28a205fa 45 #define BMX055_ACC_PMU_BW 0x10
krebyy 0:cbba28a205fa 46 #define BMX055_ACC_PMU_LPW 0x11
krebyy 0:cbba28a205fa 47 #define BMX055_ACC_PMU_LOW_POWER 0x12
krebyy 0:cbba28a205fa 48 #define BMX055_ACC_D_HBW 0x13
krebyy 0:cbba28a205fa 49 #define BMX055_ACC_BGW_SOFTRESET 0x14
krebyy 0:cbba28a205fa 50 //#define BMX055_ACC_Reserved 0x15
krebyy 0:cbba28a205fa 51 #define BMX055_ACC_INT_EN_0 0x16
krebyy 0:cbba28a205fa 52 #define BMX055_ACC_INT_EN_1 0x17
krebyy 0:cbba28a205fa 53 #define BMX055_ACC_INT_EN_2 0x18
krebyy 0:cbba28a205fa 54 #define BMX055_ACC_INT_MAP_0 0x19
krebyy 0:cbba28a205fa 55 #define BMX055_ACC_INT_MAP_1 0x1A
krebyy 0:cbba28a205fa 56 #define BMX055_ACC_INT_MAP_2 0x1B
krebyy 0:cbba28a205fa 57 //#define BMX055_ACC_Reserved 0x1C
krebyy 0:cbba28a205fa 58 //#define BMX055_ACC_Reserved 0x1D
krebyy 0:cbba28a205fa 59 #define BMX055_ACC_INT_SRC 0x1E
krebyy 0:cbba28a205fa 60 //#define BMX055_ACC_Reserved 0x1F
krebyy 0:cbba28a205fa 61 #define BMX055_ACC_INT_OUT_CTRL 0x20
krebyy 0:cbba28a205fa 62 #define BMX055_ACC_INT_RST_LATCH 0x21
krebyy 0:cbba28a205fa 63 #define BMX055_ACC_INT_0 0x22
krebyy 0:cbba28a205fa 64 #define BMX055_ACC_INT_1 0x23
krebyy 0:cbba28a205fa 65 #define BMX055_ACC_INT_2 0x24
krebyy 0:cbba28a205fa 66 #define BMX055_ACC_INT_3 0x25
krebyy 0:cbba28a205fa 67 #define BMX055_ACC_INT_4 0x26
krebyy 0:cbba28a205fa 68 #define BMX055_ACC_INT_5 0x27
krebyy 0:cbba28a205fa 69 #define BMX055_ACC_INT_6 0x28
krebyy 0:cbba28a205fa 70 #define BMX055_ACC_INT_7 0x29
krebyy 0:cbba28a205fa 71 #define BMX055_ACC_INT_8 0x2A
krebyy 0:cbba28a205fa 72 #define BMX055_ACC_INT_9 0x2B
krebyy 0:cbba28a205fa 73 #define BMX055_ACC_INT_A 0x2C
krebyy 0:cbba28a205fa 74 #define BMX055_ACC_INT_B 0x2D
krebyy 0:cbba28a205fa 75 #define BMX055_ACC_INT_C 0x2E
krebyy 0:cbba28a205fa 76 #define BMX055_ACC_INT_D 0x2F
krebyy 0:cbba28a205fa 77 #define BMX055_ACC_FIFO_CONFIG_0 0x30
krebyy 0:cbba28a205fa 78 //#define BMX055_ACC_Reserved 0x31
krebyy 0:cbba28a205fa 79 #define BMX055_ACC_PMU_SELF_TEST 0x32
krebyy 0:cbba28a205fa 80 #define BMX055_ACC_TRIM_NVM_CTRL 0x33
krebyy 0:cbba28a205fa 81 #define BMX055_ACC_BGW_SPI3_WDT 0x34
krebyy 0:cbba28a205fa 82 //#define BMX055_ACC_Reserved 0x35
krebyy 0:cbba28a205fa 83 #define BMX055_ACC_OFC_CTRL 0x36
krebyy 0:cbba28a205fa 84 #define BMX055_ACC_OFC_SETTING 0x37
krebyy 0:cbba28a205fa 85 #define BMX055_ACC_OFC_OFFSET_X 0x38
krebyy 0:cbba28a205fa 86 #define BMX055_ACC_OFC_OFFSET_Y 0x39
krebyy 0:cbba28a205fa 87 #define BMX055_ACC_OFC_OFFSET_Z 0x3A
krebyy 0:cbba28a205fa 88 #define BMX055_ACC_TRIM_GPO 0x3B
krebyy 0:cbba28a205fa 89 #define BMX055_ACC_TRIM_GP1 0x3C
krebyy 0:cbba28a205fa 90 //#define BMX055_ACC_Reserved 0x3D
krebyy 0:cbba28a205fa 91 #define BMX055_ACC_FIFO_CONFIG_1 0x3E
krebyy 0:cbba28a205fa 92 #define BMX055_ACC_FIFO_DATA 0x3F
krebyy 0:cbba28a205fa 93
krebyy 0:cbba28a205fa 94 // BMX055 Gyroscope Registers
krebyy 0:cbba28a205fa 95 #define BMX055_GYRO_WHOAMI 0x00 // should return 0x0F
krebyy 0:cbba28a205fa 96 //#define BMX055_GYRO_Reserved 0x01
krebyy 0:cbba28a205fa 97 #define BMX055_GYRO_RATE_X_LSB 0x02
krebyy 0:cbba28a205fa 98 #define BMX055_GYRO_RATE_X_MSB 0x03
krebyy 0:cbba28a205fa 99 #define BMX055_GYRO_RATE_Y_LSB 0x04
krebyy 0:cbba28a205fa 100 #define BMX055_GYRO_RATE_Y_MSB 0x05
krebyy 0:cbba28a205fa 101 #define BMX055_GYRO_RATE_Z_LSB 0x06
krebyy 0:cbba28a205fa 102 #define BMX055_GYRO_RATE_Z_MSB 0x07
krebyy 0:cbba28a205fa 103 //#define BMX055_GYRO_Reserved 0x08
krebyy 0:cbba28a205fa 104 #define BMX055_GYRO_INT_STATUS_0 0x09
krebyy 0:cbba28a205fa 105 #define BMX055_GYRO_INT_STATUS_1 0x0A
krebyy 0:cbba28a205fa 106 #define BMX055_GYRO_INT_STATUS_2 0x0B
krebyy 0:cbba28a205fa 107 #define BMX055_GYRO_INT_STATUS_3 0x0C
krebyy 0:cbba28a205fa 108 //#define BMX055_GYRO_Reserved 0x0D
krebyy 0:cbba28a205fa 109 #define BMX055_GYRO_FIFO_STATUS 0x0E
krebyy 0:cbba28a205fa 110 #define BMX055_GYRO_RANGE 0x0F
krebyy 0:cbba28a205fa 111 #define BMX055_GYRO_BW 0x10
krebyy 0:cbba28a205fa 112 #define BMX055_GYRO_LPM1 0x11
krebyy 0:cbba28a205fa 113 #define BMX055_GYRO_LPM2 0x12
krebyy 0:cbba28a205fa 114 #define BMX055_GYRO_RATE_HBW 0x13
krebyy 0:cbba28a205fa 115 #define BMX055_GYRO_BGW_SOFTRESET 0x14
krebyy 0:cbba28a205fa 116 #define BMX055_GYRO_INT_EN_0 0x15
krebyy 0:cbba28a205fa 117 #define BMX055_GYRO_INT_EN_1 0x16
krebyy 0:cbba28a205fa 118 #define BMX055_GYRO_INT_MAP_0 0x17
krebyy 0:cbba28a205fa 119 #define BMX055_GYRO_INT_MAP_1 0x18
krebyy 0:cbba28a205fa 120 #define BMX055_GYRO_INT_MAP_2 0x19
krebyy 0:cbba28a205fa 121 #define BMX055_GYRO_INT_SRC_1 0x1A
krebyy 0:cbba28a205fa 122 #define BMX055_GYRO_INT_SRC_2 0x1B
krebyy 0:cbba28a205fa 123 #define BMX055_GYRO_INT_SRC_3 0x1C
krebyy 0:cbba28a205fa 124 //#define BMX055_GYRO_Reserved 0x1D
krebyy 0:cbba28a205fa 125 #define BMX055_GYRO_FIFO_EN 0x1E
krebyy 0:cbba28a205fa 126 //#define BMX055_GYRO_Reserved 0x1F
krebyy 0:cbba28a205fa 127 //#define BMX055_GYRO_Reserved 0x20
krebyy 0:cbba28a205fa 128 #define BMX055_GYRO_INT_RST_LATCH 0x21
krebyy 0:cbba28a205fa 129 #define BMX055_GYRO_HIGH_TH_X 0x22
krebyy 0:cbba28a205fa 130 #define BMX055_GYRO_HIGH_DUR_X 0x23
krebyy 0:cbba28a205fa 131 #define BMX055_GYRO_HIGH_TH_Y 0x24
krebyy 0:cbba28a205fa 132 #define BMX055_GYRO_HIGH_DUR_Y 0x25
krebyy 0:cbba28a205fa 133 #define BMX055_GYRO_HIGH_TH_Z 0x26
krebyy 0:cbba28a205fa 134 #define BMX055_GYRO_HIGH_DUR_Z 0x27
krebyy 0:cbba28a205fa 135 //#define BMX055_GYRO_Reserved 0x28
krebyy 0:cbba28a205fa 136 //#define BMX055_GYRO_Reserved 0x29
krebyy 0:cbba28a205fa 137 //#define BMX055_GYRO_Reserved 0x2A
krebyy 0:cbba28a205fa 138 #define BMX055_GYRO_SOC 0x31
krebyy 0:cbba28a205fa 139 #define BMX055_GYRO_A_FOC 0x32
krebyy 0:cbba28a205fa 140 #define BMX055_GYRO_TRIM_NVM_CTRL 0x33
krebyy 0:cbba28a205fa 141 #define BMX055_GYRO_BGW_SPI3_WDT 0x34
krebyy 0:cbba28a205fa 142 //#define BMX055_GYRO_Reserved 0x35
krebyy 0:cbba28a205fa 143 #define BMX055_GYRO_OFC1 0x36
krebyy 0:cbba28a205fa 144 #define BMX055_GYRO_OFC2 0x37
krebyy 0:cbba28a205fa 145 #define BMX055_GYRO_OFC3 0x38
krebyy 0:cbba28a205fa 146 #define BMX055_GYRO_OFC4 0x39
krebyy 0:cbba28a205fa 147 #define BMX055_GYRO_TRIM_GP0 0x3A
krebyy 0:cbba28a205fa 148 #define BMX055_GYRO_TRIM_GP1 0x3B
krebyy 0:cbba28a205fa 149 #define BMX055_GYRO_BIST 0x3C
krebyy 0:cbba28a205fa 150 #define BMX055_GYRO_FIFO_CONFIG_0 0x3D
krebyy 0:cbba28a205fa 151 #define BMX055_GYRO_FIFO_CONFIG_1 0x3E
krebyy 0:cbba28a205fa 152
krebyy 0:cbba28a205fa 153 // BMX055 magnetometer registers
krebyy 0:cbba28a205fa 154 #define BMX055_MAG_WHOAMI 0x40 // should return 0x32
krebyy 0:cbba28a205fa 155 #define BMX055_MAG_Reserved 0x41
krebyy 0:cbba28a205fa 156 #define BMX055_MAG_XOUT_LSB 0x42
krebyy 0:cbba28a205fa 157 #define BMX055_MAG_XOUT_MSB 0x43
krebyy 0:cbba28a205fa 158 #define BMX055_MAG_YOUT_LSB 0x44
krebyy 0:cbba28a205fa 159 #define BMX055_MAG_YOUT_MSB 0x45
krebyy 0:cbba28a205fa 160 #define BMX055_MAG_ZOUT_LSB 0x46
krebyy 0:cbba28a205fa 161 #define BMX055_MAG_ZOUT_MSB 0x47
krebyy 0:cbba28a205fa 162 #define BMX055_MAG_ROUT_LSB 0x48
krebyy 0:cbba28a205fa 163 #define BMX055_MAG_ROUT_MSB 0x49
krebyy 0:cbba28a205fa 164 #define BMX055_MAG_INT_STATUS 0x4A
krebyy 0:cbba28a205fa 165 #define BMX055_MAG_PWR_CNTL1 0x4B
krebyy 0:cbba28a205fa 166 #define BMX055_MAG_PWR_CNTL2 0x4C
krebyy 0:cbba28a205fa 167 #define BMX055_MAG_INT_EN_1 0x4D
krebyy 0:cbba28a205fa 168 #define BMX055_MAG_INT_EN_2 0x4E
krebyy 0:cbba28a205fa 169 #define BMX055_MAG_LOW_THS 0x4F
krebyy 0:cbba28a205fa 170 #define BMX055_MAG_HIGH_THS 0x50
krebyy 0:cbba28a205fa 171 #define BMX055_MAG_REP_XY 0x51
krebyy 0:cbba28a205fa 172 #define BMX055_MAG_REP_Z 0x52
krebyy 0:cbba28a205fa 173 /* Trim Extended Registers */
krebyy 0:cbba28a205fa 174 #define BMM050_DIG_X1 0x5D // needed for magnetic field calculation
krebyy 0:cbba28a205fa 175 #define BMM050_DIG_Y1 0x5E
krebyy 0:cbba28a205fa 176 #define BMM050_DIG_Z4_LSB 0x62
krebyy 0:cbba28a205fa 177 #define BMM050_DIG_Z4_MSB 0x63
krebyy 0:cbba28a205fa 178 #define BMM050_DIG_X2 0x64
krebyy 0:cbba28a205fa 179 #define BMM050_DIG_Y2 0x65
krebyy 0:cbba28a205fa 180 #define BMM050_DIG_Z2_LSB 0x68
krebyy 0:cbba28a205fa 181 #define BMM050_DIG_Z2_MSB 0x69
krebyy 0:cbba28a205fa 182 #define BMM050_DIG_Z1_LSB 0x6A
krebyy 0:cbba28a205fa 183 #define BMM050_DIG_Z1_MSB 0x6B
krebyy 0:cbba28a205fa 184 #define BMM050_DIG_XYZ1_LSB 0x6C
krebyy 0:cbba28a205fa 185 #define BMM050_DIG_XYZ1_MSB 0x6D
krebyy 0:cbba28a205fa 186 #define BMM050_DIG_Z3_LSB 0x6E
krebyy 0:cbba28a205fa 187 #define BMM050_DIG_Z3_MSB 0x6F
krebyy 0:cbba28a205fa 188 #define BMM050_DIG_XY2 0x70
krebyy 0:cbba28a205fa 189 #define BMM050_DIG_XY1 0x71
krebyy 0:cbba28a205fa 190
krebyy 0:cbba28a205fa 191 // Using SDO1 = SDO2 = CSB3 = GND as designed
krebyy 0:cbba28a205fa 192 // Seven-bit device addresses are ACC = 0x18, GYRO = 0x68, MAG = 0x10
krebyy 0:cbba28a205fa 193 #define BMX055_ACC_ADDRESS 0x18 << 1 // Address of BMX055 accelerometer
krebyy 0:cbba28a205fa 194 #define BMX055_GYRO_ADDRESS 0x68 << 1 // Address of BMX055 gyroscope
krebyy 0:cbba28a205fa 195 #define BMX055_MAG_ADDRESS 0x10 << 1 // Address of BMX055 magnetometer
krebyy 0:cbba28a205fa 196
krebyy 0:cbba28a205fa 197 // Set initial input parameters
krebyy 0:cbba28a205fa 198 // define BMX055 ACC full scale options
krebyy 0:cbba28a205fa 199 #define AFS_2G 0x03
krebyy 0:cbba28a205fa 200 #define AFS_4G 0x05
krebyy 0:cbba28a205fa 201 #define AFS_8G 0x08
krebyy 0:cbba28a205fa 202 #define AFS_16G 0x0C
krebyy 0:cbba28a205fa 203
krebyy 0:cbba28a205fa 204 enum ACCBW { // define BMX055 accelerometer bandwidths
krebyy 0:cbba28a205fa 205 ABW_8Hz, // 7.81 Hz, 64 ms update time
krebyy 0:cbba28a205fa 206 ABW_16Hz, // 15.63 Hz, 32 ms update time
krebyy 0:cbba28a205fa 207 ABW_31Hz, // 31.25 Hz, 16 ms update time
krebyy 0:cbba28a205fa 208 ABW_63Hz, // 62.5 Hz, 8 ms update time
krebyy 0:cbba28a205fa 209 ABW_125Hz, // 125 Hz, 4 ms update time
krebyy 0:cbba28a205fa 210 ABW_250Hz, // 250 Hz, 2 ms update time
krebyy 0:cbba28a205fa 211 ABW_500Hz, // 500 Hz, 1 ms update time
krebyy 0:cbba28a205fa 212 ABW_100Hz // 1000 Hz, 0.5 ms update time
krebyy 0:cbba28a205fa 213 };
krebyy 0:cbba28a205fa 214
krebyy 0:cbba28a205fa 215 enum Gscale {
krebyy 0:cbba28a205fa 216 GFS_2000DPS = 0,
krebyy 0:cbba28a205fa 217 GFS_1000DPS,
krebyy 0:cbba28a205fa 218 GFS_500DPS,
krebyy 0:cbba28a205fa 219 GFS_250DPS,
krebyy 0:cbba28a205fa 220 GFS_125DPS
krebyy 0:cbba28a205fa 221 };
krebyy 0:cbba28a205fa 222
krebyy 0:cbba28a205fa 223 enum GODRBW {
krebyy 0:cbba28a205fa 224 G_2000Hz523Hz = 0, // 2000 Hz ODR and unfiltered (bandwidth 523Hz)
krebyy 0:cbba28a205fa 225 G_2000Hz230Hz,
krebyy 0:cbba28a205fa 226 G_1000Hz116Hz,
krebyy 0:cbba28a205fa 227 G_400Hz47Hz,
krebyy 0:cbba28a205fa 228 G_200Hz23Hz,
krebyy 0:cbba28a205fa 229 G_100Hz12Hz,
krebyy 0:cbba28a205fa 230 G_200Hz64Hz,
krebyy 0:cbba28a205fa 231 G_100Hz32Hz // 100 Hz ODR and 32 Hz bandwidth
krebyy 0:cbba28a205fa 232 };
krebyy 0:cbba28a205fa 233
krebyy 0:cbba28a205fa 234 enum MODR {
krebyy 0:cbba28a205fa 235 MODR_10Hz = 0, // 10 Hz ODR
krebyy 0:cbba28a205fa 236 MODR_2Hz , // 2 Hz ODR
krebyy 0:cbba28a205fa 237 MODR_6Hz , // 6 Hz ODR
krebyy 0:cbba28a205fa 238 MODR_8Hz , // 8 Hz ODR
krebyy 0:cbba28a205fa 239 MODR_15Hz , // 15 Hz ODR
krebyy 0:cbba28a205fa 240 MODR_20Hz , // 20 Hz ODR
krebyy 0:cbba28a205fa 241 MODR_25Hz , // 25 Hz ODR
krebyy 0:cbba28a205fa 242 MODR_30Hz // 30 Hz ODR
krebyy 0:cbba28a205fa 243 };
krebyy 0:cbba28a205fa 244
krebyy 0:cbba28a205fa 245 enum Mmode {
krebyy 0:cbba28a205fa 246 lowPower = 0, // rms noise ~1.0 microTesla, 0.17 mA power
krebyy 0:cbba28a205fa 247 Regular , // rms noise ~0.6 microTesla, 0.5 mA power
krebyy 0:cbba28a205fa 248 enhancedRegular , // rms noise ~0.5 microTesla, 0.8 mA power
krebyy 0:cbba28a205fa 249 highAccuracy // rms noise ~0.3 microTesla, 4.9 mA power
krebyy 0:cbba28a205fa 250 };
krebyy 0:cbba28a205fa 251
krebyy 0:cbba28a205fa 252 // Set up I2C, (SDA,SCL)
krebyy 0:cbba28a205fa 253 I2C i2c2(PB_11, PB_10);
krebyy 0:cbba28a205fa 254
krebyy 0:cbba28a205fa 255 // Specify sensor full scale
krebyy 0:cbba28a205fa 256 uint8_t Ascale = AFS_2G;
krebyy 0:cbba28a205fa 257 uint8_t Gscale = GFS_125DPS;
krebyy 0:cbba28a205fa 258 float aRes, gRes, mRes; // scale resolutions per LSB for the sensors
krebyy 0:cbba28a205fa 259
krebyy 0:cbba28a205fa 260 // Parameters to hold BMX055 trim values
krebyy 0:cbba28a205fa 261 int8_t dig_x1;
krebyy 0:cbba28a205fa 262 int8_t dig_y1;
krebyy 0:cbba28a205fa 263 int8_t dig_x2;
krebyy 0:cbba28a205fa 264 int8_t dig_y2;
krebyy 0:cbba28a205fa 265 uint16_t dig_z1;
krebyy 0:cbba28a205fa 266 int16_t dig_z2;
krebyy 0:cbba28a205fa 267 int16_t dig_z3;
krebyy 0:cbba28a205fa 268 int16_t dig_z4;
krebyy 0:cbba28a205fa 269 uint8_t dig_xy1;
krebyy 0:cbba28a205fa 270 int8_t dig_xy2;
krebyy 0:cbba28a205fa 271 uint16_t dig_xyz1;
krebyy 0:cbba28a205fa 272
krebyy 0:cbba28a205fa 273 // BMX055 variables
krebyy 0:cbba28a205fa 274 int16_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output
krebyy 0:cbba28a205fa 275 int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output
krebyy 0:cbba28a205fa 276 int16_t magCount[3]; // Stores the 13/15-bit signed magnetometer sensor output
krebyy 0:cbba28a205fa 277 float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}, magBias[3] = {0, 0, 0}; // Bias corrections for gyro, accelerometer, mag
krebyy 0:cbba28a205fa 278 float SelfTest[6]; // holds results of gyro and accelerometer self test
krebyy 0:cbba28a205fa 279
krebyy 0:cbba28a205fa 280 // global constants for 9 DoF fusion and AHRS (Attitude and Heading Reference System)
krebyy 0:cbba28a205fa 281 float GyroMeasError = M_PI * (40.0f / 180.0f); // gyroscope measurement error in rads/s (start at 40 deg/s)
krebyy 0:cbba28a205fa 282 float GyroMeasDrift = M_PI * (0.0f / 180.0f); // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s)
krebyy 0:cbba28a205fa 283 // There is a tradeoff in the beta parameter between accuracy and response speed.
krebyy 0:cbba28a205fa 284 // In the original Madgwick study, beta of 0.041 (corresponding to GyroMeasError of 2.7 degrees/s) was found to give optimal accuracy.
krebyy 0:cbba28a205fa 285 // However, with this value, the LSM9SD0 response time is about 10 seconds to a stable initial quaternion.
krebyy 0:cbba28a205fa 286 // Subsequent changes also require a longish lag time to a stable output, not fast enough for a quadcopter or robot car!
krebyy 0:cbba28a205fa 287 // By increasing beta (GyroMeasError) by about a factor of fifteen, the response time constant is reduced to ~2 sec
krebyy 0:cbba28a205fa 288 // I haven't noticed any reduction in solution accuracy. This is essentially the I coefficient in a PID control sense;
krebyy 0:cbba28a205fa 289 // the bigger the feedback coefficient, the faster the solution converges, usually at the expense of accuracy.
krebyy 0:cbba28a205fa 290 // In any case, this is the free parameter in the Madgwick filtering and fusion scheme.
krebyy 0:cbba28a205fa 291 float beta = sqrt(3.0f / 4.0f) * GyroMeasError; // compute beta
krebyy 0:cbba28a205fa 292 float zeta = sqrt(3.0f / 4.0f) * GyroMeasDrift; // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value
krebyy 0:cbba28a205fa 293 #define Kp 2.0f * 5.0f // these are the free parameters in the Mahony filter and fusion scheme, Kp for proportional feedback, Ki for integral
krebyy 0:cbba28a205fa 294 #define Ki 0.0f
krebyy 0:cbba28a205fa 295
krebyy 0:cbba28a205fa 296 // Declination at Sao Paulo, Brazil is -21 degrees 7 minutes on 2016-03-27
krebyy 0:cbba28a205fa 297 #define LOCAL_DECLINATION -21.1f
krebyy 0:cbba28a205fa 298
krebyy 0:cbba28a205fa 299 float deltat = 0.0f; // integration interval for both filter schemes
krebyy 0:cbba28a205fa 300
krebyy 0:cbba28a205fa 301 float q[4] = {1.0f, 0.0f, 0.0f, 0.0f}; // vector to hold quaternion
krebyy 0:cbba28a205fa 302 float eInt[3] = {0.0f, 0.0f, 0.0f}; // vector to hold integral error for Mahony method
krebyy 0:cbba28a205fa 303
krebyy 0:cbba28a205fa 304
krebyy 0:cbba28a205fa 305 class BMX055 {
krebyy 0:cbba28a205fa 306 private:
krebyy 0:cbba28a205fa 307 float pitch, yaw, roll;
krebyy 0:cbba28a205fa 308
krebyy 0:cbba28a205fa 309 void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
krebyy 0:cbba28a205fa 310 {
krebyy 0:cbba28a205fa 311 char data_write[2];
krebyy 0:cbba28a205fa 312 data_write[0] = subAddress;
krebyy 0:cbba28a205fa 313 data_write[1] = data;
krebyy 0:cbba28a205fa 314 i2c2.write(address, data_write, 2, 0);
krebyy 0:cbba28a205fa 315 }
krebyy 0:cbba28a205fa 316
krebyy 0:cbba28a205fa 317 char readByte(uint8_t address, uint8_t subAddress)
krebyy 0:cbba28a205fa 318 {
krebyy 0:cbba28a205fa 319 char data[1]; // `data` will store the register data
krebyy 0:cbba28a205fa 320 char data_write[1];
krebyy 0:cbba28a205fa 321 data_write[0] = subAddress;
krebyy 0:cbba28a205fa 322 i2c2.write(address, data_write, 1, 1); // no stop
krebyy 0:cbba28a205fa 323 i2c2.read(address, data, 1, 0);
krebyy 0:cbba28a205fa 324 return data[0];
krebyy 0:cbba28a205fa 325 }
krebyy 0:cbba28a205fa 326
krebyy 0:cbba28a205fa 327 void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
krebyy 0:cbba28a205fa 328 {
krebyy 0:cbba28a205fa 329 char data[14];
krebyy 0:cbba28a205fa 330 char data_write[1];
krebyy 0:cbba28a205fa 331 data_write[0] = subAddress;
krebyy 0:cbba28a205fa 332 i2c2.write(address, data_write, 1, 1); // no stop
krebyy 0:cbba28a205fa 333 i2c2.read(address, data, count, 0);
krebyy 0:cbba28a205fa 334 for(int ii = 0; ii < count; ii++)
krebyy 0:cbba28a205fa 335 {
krebyy 0:cbba28a205fa 336 dest[ii] = data[ii];
krebyy 0:cbba28a205fa 337 }
krebyy 0:cbba28a205fa 338 }
krebyy 0:cbba28a205fa 339
krebyy 0:cbba28a205fa 340 public:
krebyy 0:cbba28a205fa 341 BMX055()
krebyy 0:cbba28a205fa 342 {
krebyy 0:cbba28a205fa 343 //Set up I2C
krebyy 0:cbba28a205fa 344 i2c2.frequency(400000); // use fast (400 kHz) I2C
krebyy 0:cbba28a205fa 345 }
krebyy 0:cbba28a205fa 346
krebyy 0:cbba28a205fa 347 float getAres(void)
krebyy 0:cbba28a205fa 348 {
krebyy 0:cbba28a205fa 349 switch (Ascale)
krebyy 0:cbba28a205fa 350 {
krebyy 0:cbba28a205fa 351 // Possible accelerometer scales (and their register bit settings) are:
krebyy 0:cbba28a205fa 352 // 2 Gs (0011), 4 Gs (0101), 8 Gs (1000), and 16 Gs (1100).
krebyy 0:cbba28a205fa 353 // BMX055 ACC data is signed 12 bit
krebyy 0:cbba28a205fa 354 case AFS_2G:
krebyy 0:cbba28a205fa 355 aRes = 2.0/2048.0;
krebyy 0:cbba28a205fa 356 break;
krebyy 0:cbba28a205fa 357 case AFS_4G:
krebyy 0:cbba28a205fa 358 aRes = 4.0/2048.0;
krebyy 0:cbba28a205fa 359 break;
krebyy 0:cbba28a205fa 360 case AFS_8G:
krebyy 0:cbba28a205fa 361 aRes = 8.0/2048.0;
krebyy 0:cbba28a205fa 362 break;
krebyy 0:cbba28a205fa 363 case AFS_16G:
krebyy 0:cbba28a205fa 364 aRes = 16.0/2048.0;
krebyy 0:cbba28a205fa 365 break;
krebyy 0:cbba28a205fa 366 }
krebyy 0:cbba28a205fa 367
krebyy 0:cbba28a205fa 368 return aRes;
krebyy 0:cbba28a205fa 369 }
krebyy 0:cbba28a205fa 370
krebyy 0:cbba28a205fa 371 float getGres(void)
krebyy 0:cbba28a205fa 372 {
krebyy 0:cbba28a205fa 373 switch (Gscale)
krebyy 0:cbba28a205fa 374 {
krebyy 0:cbba28a205fa 375 // Possible gyro scales (and their register bit settings) are:
krebyy 0:cbba28a205fa 376 // 125 DPS (100), 250 DPS (011), 500 DPS (010), 1000 DPS (001), and 2000 DPS (000).
krebyy 0:cbba28a205fa 377 case GFS_125DPS:
krebyy 0:cbba28a205fa 378 gRes = 124.87/32768.0; // per data sheet, not exactly 125!?
krebyy 0:cbba28a205fa 379 break;
krebyy 0:cbba28a205fa 380 case GFS_250DPS:
krebyy 0:cbba28a205fa 381 gRes = 249.75/32768.0;
krebyy 0:cbba28a205fa 382 break;
krebyy 0:cbba28a205fa 383 case GFS_500DPS:
krebyy 0:cbba28a205fa 384 gRes = 499.5/32768.0;
krebyy 0:cbba28a205fa 385 break;
krebyy 0:cbba28a205fa 386 case GFS_1000DPS:
krebyy 0:cbba28a205fa 387 gRes = 999.0/32768.0;
krebyy 0:cbba28a205fa 388 break;
krebyy 0:cbba28a205fa 389 case GFS_2000DPS:
krebyy 0:cbba28a205fa 390 gRes = 1998.0/32768.0;
krebyy 0:cbba28a205fa 391 break;
krebyy 0:cbba28a205fa 392 }
krebyy 0:cbba28a205fa 393
krebyy 0:cbba28a205fa 394 return gRes;
krebyy 0:cbba28a205fa 395 }
krebyy 0:cbba28a205fa 396
krebyy 0:cbba28a205fa 397 float getPitch(void)
krebyy 0:cbba28a205fa 398 {
krebyy 0:cbba28a205fa 399 return pitch;
krebyy 0:cbba28a205fa 400 }
krebyy 0:cbba28a205fa 401
krebyy 0:cbba28a205fa 402 float getRoll(void)
krebyy 0:cbba28a205fa 403 {
krebyy 0:cbba28a205fa 404 return roll;
krebyy 0:cbba28a205fa 405 }
krebyy 0:cbba28a205fa 406
krebyy 0:cbba28a205fa 407 float getYaw(void)
krebyy 0:cbba28a205fa 408 {
krebyy 0:cbba28a205fa 409 return yaw;
krebyy 0:cbba28a205fa 410 }
krebyy 0:cbba28a205fa 411
krebyy 0:cbba28a205fa 412 void readAccelData(int16_t * destination)
krebyy 0:cbba28a205fa 413 {
krebyy 0:cbba28a205fa 414 uint8_t rawData[6]; // x/y/z accel register data stored here
krebyy 0:cbba28a205fa 415
krebyy 0:cbba28a205fa 416 // Read the six raw data registers into data array
krebyy 0:cbba28a205fa 417 readBytes(BMX055_ACC_ADDRESS, BMX055_ACC_D_X_LSB, 6, &rawData[0]);
krebyy 0:cbba28a205fa 418 if((rawData[0] & 0x01) && (rawData[2] & 0x01) && (rawData[4] & 0x01))
krebyy 0:cbba28a205fa 419 { // Check that all 3 axes have new data
krebyy 0:cbba28a205fa 420 // Turn the MSB and LSB into a signed 12-bit value
krebyy 0:cbba28a205fa 421 destination[0] = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]) >> 4;
krebyy 0:cbba28a205fa 422 destination[1] = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]) >> 4;
krebyy 0:cbba28a205fa 423 destination[2] = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]) >> 4;
krebyy 0:cbba28a205fa 424 }
krebyy 0:cbba28a205fa 425 }
krebyy 0:cbba28a205fa 426
krebyy 0:cbba28a205fa 427 void readGyroData(int16_t * destination)
krebyy 0:cbba28a205fa 428 {
krebyy 0:cbba28a205fa 429 uint8_t rawData[6]; // x/y/z gyro register data stored here
krebyy 0:cbba28a205fa 430
krebyy 0:cbba28a205fa 431 // Read the six raw data registers sequentially into data array
krebyy 0:cbba28a205fa 432 readBytes(BMX055_GYRO_ADDRESS, BMX055_GYRO_RATE_X_LSB, 6, &rawData[0]);
krebyy 0:cbba28a205fa 433 // Turn the MSB and LSB into a signed 16-bit value
krebyy 0:cbba28a205fa 434 destination[0] = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 435 destination[1] = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]);
krebyy 0:cbba28a205fa 436 destination[2] = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]);
krebyy 0:cbba28a205fa 437 }
krebyy 0:cbba28a205fa 438
krebyy 0:cbba28a205fa 439 void readMagData(int16_t * magData)
krebyy 0:cbba28a205fa 440 {
krebyy 0:cbba28a205fa 441 int16_t mdata_x = 0, mdata_y = 0, mdata_z = 0, temp = 0;
krebyy 0:cbba28a205fa 442 uint16_t data_r = 0;
krebyy 0:cbba28a205fa 443 uint8_t rawData[8]; // x/y/z hall magnetic field data, and Hall resistance data
krebyy 0:cbba28a205fa 444 readBytes(BMX055_MAG_ADDRESS, BMX055_MAG_XOUT_LSB, 8, &rawData[0]); // Read the eight raw data registers sequentially into data array
krebyy 0:cbba28a205fa 445 if(rawData[6] & 0x01) { // Check if data ready status bit is set
krebyy 0:cbba28a205fa 446 mdata_x = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]) >> 3; // 13-bit signed integer for x-axis field
krebyy 0:cbba28a205fa 447 mdata_y = (int16_t) (((int16_t)rawData[3] << 8) | rawData[2]) >> 3; // 13-bit signed integer for y-axis field
krebyy 0:cbba28a205fa 448 mdata_z = (int16_t) (((int16_t)rawData[5] << 8) | rawData[4]) >> 1; // 15-bit signed integer for z-axis field
krebyy 0:cbba28a205fa 449 data_r = (uint16_t) (((uint16_t)rawData[7] << 8) | rawData[6]) >> 2; // 14-bit unsigned integer for Hall resistance
krebyy 0:cbba28a205fa 450
krebyy 0:cbba28a205fa 451 // calculate temperature compensated 16-bit magnetic fields
krebyy 0:cbba28a205fa 452 temp = ((int16_t)(((uint16_t)((((int32_t)dig_xyz1) << 14)/(data_r != 0 ? data_r : dig_xyz1))) - ((uint16_t)0x4000)));
krebyy 0:cbba28a205fa 453 magData[0] = ((int16_t)((((int32_t)mdata_x) *
krebyy 0:cbba28a205fa 454 ((((((((int32_t)dig_xy2) * ((((int32_t)temp) * ((int32_t)temp)) >> 7)) +
krebyy 0:cbba28a205fa 455 (((int32_t)temp) * ((int32_t)(((int16_t)dig_xy1) << 7)))) >> 9) +
krebyy 0:cbba28a205fa 456 ((int32_t)0x100000)) * ((int32_t)(((int16_t)dig_x2) + ((int16_t)0xA0)))) >> 12)) >> 13)) +
krebyy 0:cbba28a205fa 457 (((int16_t)dig_x1) << 3);
krebyy 0:cbba28a205fa 458
krebyy 0:cbba28a205fa 459 temp = ((int16_t)(((uint16_t)((((int32_t)dig_xyz1) << 14)/(data_r != 0 ? data_r : dig_xyz1))) - ((uint16_t)0x4000)));
krebyy 0:cbba28a205fa 460 magData[1] = ((int16_t)((((int32_t)mdata_y) *
krebyy 0:cbba28a205fa 461 ((((((((int32_t)dig_xy2) * ((((int32_t)temp) * ((int32_t)temp)) >> 7)) +
krebyy 0:cbba28a205fa 462 (((int32_t)temp) * ((int32_t)(((int16_t)dig_xy1) << 7)))) >> 9) +
krebyy 0:cbba28a205fa 463 ((int32_t)0x100000)) * ((int32_t)(((int16_t)dig_y2) + ((int16_t)0xA0)))) >> 12)) >> 13)) +
krebyy 0:cbba28a205fa 464 (((int16_t)dig_y1) << 3);
krebyy 0:cbba28a205fa 465 magData[2] = (((((int32_t)(mdata_z - dig_z4)) << 15) - ((((int32_t)dig_z3) * ((int32_t)(((int16_t)data_r) -
krebyy 0:cbba28a205fa 466 ((int16_t)dig_xyz1))))>>2))/(dig_z2 + ((int16_t)(((((int32_t)dig_z1) * ((((int16_t)data_r) << 1)))+(1<<15))>>16))));
krebyy 0:cbba28a205fa 467 }
krebyy 0:cbba28a205fa 468 }
krebyy 0:cbba28a205fa 469
krebyy 0:cbba28a205fa 470 float getTemperature()
krebyy 0:cbba28a205fa 471 {
krebyy 0:cbba28a205fa 472 uint8_t c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_D_TEMP); // Read the raw data register
krebyy 0:cbba28a205fa 473 int16_t tempCount = ((int16_t)((int16_t)c << 8)) >> 8 ; // Turn the byte into a signed 8-bit integer
krebyy 0:cbba28a205fa 474
krebyy 0:cbba28a205fa 475 return ((((float)tempCount) * 0.5) + 23.0); // temperature in degrees Centigrade
krebyy 0:cbba28a205fa 476 }
krebyy 0:cbba28a205fa 477
krebyy 0:cbba28a205fa 478 void fastcompaccelBMX055(float * dest1)
krebyy 0:cbba28a205fa 479 {
krebyy 0:cbba28a205fa 480 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL, 0x80); // set all accel offset compensation registers to zero
krebyy 0:cbba28a205fa 481 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_SETTING, 0x20); // set offset targets to 0, 0, and +1 g for x, y, z axes
krebyy 0:cbba28a205fa 482 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL, 0x20); // calculate x-axis offset
krebyy 0:cbba28a205fa 483
krebyy 0:cbba28a205fa 484 uint8_t c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 485 while(!(c & 0x10))
krebyy 0:cbba28a205fa 486 { // check if fast calibration complete
krebyy 0:cbba28a205fa 487 c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 488 wait_ms(10);
krebyy 0:cbba28a205fa 489 }
krebyy 0:cbba28a205fa 490 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL, 0x40); // calculate y-axis offset
krebyy 0:cbba28a205fa 491
krebyy 0:cbba28a205fa 492 c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 493 while(!(c & 0x10))
krebyy 0:cbba28a205fa 494 { // check if fast calibration complete
krebyy 0:cbba28a205fa 495 c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 496 wait_ms(10);
krebyy 0:cbba28a205fa 497 }
krebyy 0:cbba28a205fa 498 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL, 0x60); // calculate z-axis offset
krebyy 0:cbba28a205fa 499
krebyy 0:cbba28a205fa 500 c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 501 while(!(c & 0x10))
krebyy 0:cbba28a205fa 502 { // check if fast calibration complete
krebyy 0:cbba28a205fa 503 c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL);
krebyy 0:cbba28a205fa 504 wait_ms(10);
krebyy 0:cbba28a205fa 505 }
krebyy 0:cbba28a205fa 506
krebyy 0:cbba28a205fa 507 int8_t compx = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_OFFSET_X);
krebyy 0:cbba28a205fa 508 int8_t compy = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_OFFSET_Y);
krebyy 0:cbba28a205fa 509 int8_t compz = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_OFFSET_Z);
krebyy 0:cbba28a205fa 510
krebyy 0:cbba28a205fa 511 dest1[0] = (float) compx/128.; // accleration bias in g
krebyy 0:cbba28a205fa 512 dest1[1] = (float) compy/128.; // accleration bias in g
krebyy 0:cbba28a205fa 513 dest1[2] = (float) compz/128.; // accleration bias in g
krebyy 0:cbba28a205fa 514 }
krebyy 0:cbba28a205fa 515
krebyy 0:cbba28a205fa 516 void magcalBMX055(float * dest1)
krebyy 0:cbba28a205fa 517 {
krebyy 0:cbba28a205fa 518 uint16_t ii = 0, sample_count = 0;
krebyy 0:cbba28a205fa 519 int32_t mag_bias[3] = {0, 0, 0};
krebyy 0:cbba28a205fa 520 int16_t mag_max[3] = {0, 0, 0}, mag_min[3] = {0, 0, 0};
krebyy 0:cbba28a205fa 521
krebyy 0:cbba28a205fa 522 // ## "Mag Calibration: Wave device in a figure eight until done!" ##
krebyy 0:cbba28a205fa 523 //wait(4);
krebyy 0:cbba28a205fa 524
krebyy 0:cbba28a205fa 525 sample_count = 48;
krebyy 0:cbba28a205fa 526 for(ii = 0; ii < sample_count; ii++)
krebyy 0:cbba28a205fa 527 {
krebyy 0:cbba28a205fa 528 int16_t mag_temp[3] = {0, 0, 0};
krebyy 0:cbba28a205fa 529 readMagData(mag_temp);
krebyy 0:cbba28a205fa 530 for (int jj = 0; jj < 3; jj++)
krebyy 0:cbba28a205fa 531 {
krebyy 0:cbba28a205fa 532 if(mag_temp[jj] > mag_max[jj]) mag_max[jj] = mag_temp[jj];
krebyy 0:cbba28a205fa 533 if(mag_temp[jj] < mag_min[jj]) mag_min[jj] = mag_temp[jj];
krebyy 0:cbba28a205fa 534 }
krebyy 0:cbba28a205fa 535 wait_ms(105); // at 10 Hz ODR, new mag data is available every 100 ms
krebyy 0:cbba28a205fa 536 }
krebyy 0:cbba28a205fa 537
krebyy 0:cbba28a205fa 538 mag_bias[0] = (mag_max[0] + mag_min[0])/2; // get average x mag bias in counts
krebyy 0:cbba28a205fa 539 mag_bias[1] = (mag_max[1] + mag_min[1])/2; // get average y mag bias in counts
krebyy 0:cbba28a205fa 540 mag_bias[2] = (mag_max[2] + mag_min[2])/2; // get average z mag bias in counts
krebyy 0:cbba28a205fa 541
krebyy 0:cbba28a205fa 542 // save mag biases in G for main program
krebyy 0:cbba28a205fa 543 dest1[0] = (float) mag_bias[0]*mRes;
krebyy 0:cbba28a205fa 544 dest1[1] = (float) mag_bias[1]*mRes;
krebyy 0:cbba28a205fa 545 dest1[2] = (float) mag_bias[2]*mRes;
krebyy 0:cbba28a205fa 546
krebyy 0:cbba28a205fa 547 // ## "Mag Calibration done!" ##
krebyy 0:cbba28a205fa 548 }
krebyy 0:cbba28a205fa 549
krebyy 0:cbba28a205fa 550 // Get trim values for magnetometer sensitivity
krebyy 0:cbba28a205fa 551 void trim(void)
krebyy 0:cbba28a205fa 552 {
krebyy 0:cbba28a205fa 553 uint8_t rawData[2]; //placeholder for 2-byte trim data
krebyy 0:cbba28a205fa 554
krebyy 0:cbba28a205fa 555 dig_x1 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_X1);
krebyy 0:cbba28a205fa 556 dig_x2 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_X2);
krebyy 0:cbba28a205fa 557 dig_y1 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_Y1);
krebyy 0:cbba28a205fa 558 dig_y2 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_Y2);
krebyy 0:cbba28a205fa 559 dig_xy1 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_XY1);
krebyy 0:cbba28a205fa 560 dig_xy2 = readByte(BMX055_ACC_ADDRESS, BMM050_DIG_XY2);
krebyy 0:cbba28a205fa 561 readBytes(BMX055_MAG_ADDRESS, BMM050_DIG_Z1_LSB, 2, &rawData[0]);
krebyy 0:cbba28a205fa 562 dig_z1 = (uint16_t) (((uint16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 563 readBytes(BMX055_MAG_ADDRESS, BMM050_DIG_Z2_LSB, 2, &rawData[0]);
krebyy 0:cbba28a205fa 564 dig_z2 = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 565 readBytes(BMX055_MAG_ADDRESS, BMM050_DIG_Z3_LSB, 2, &rawData[0]);
krebyy 0:cbba28a205fa 566 dig_z3 = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 567 readBytes(BMX055_MAG_ADDRESS, BMM050_DIG_Z4_LSB, 2, &rawData[0]);
krebyy 0:cbba28a205fa 568 dig_z4 = (int16_t) (((int16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 569 readBytes(BMX055_MAG_ADDRESS, BMM050_DIG_XYZ1_LSB, 2, &rawData[0]);
krebyy 0:cbba28a205fa 570 dig_xyz1 = (uint16_t) (((uint16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 571 }
krebyy 0:cbba28a205fa 572
krebyy 0:cbba28a205fa 573 /** Initialize device for active mode
krebyy 0:cbba28a205fa 574 * @param Ascale set accel full scale
krebyy 0:cbba28a205fa 575 * @param ACCBW set bandwidth for accelerometer
krebyy 0:cbba28a205fa 576 * @param Gscale set gyro full scale
krebyy 0:cbba28a205fa 577 * @param GODRBW set gyro ODR and bandwidth
krebyy 0:cbba28a205fa 578 * @param Mmode set magnetometer operation mode
krebyy 0:cbba28a205fa 579 * @param MODR set magnetometer data rate
krebyy 0:cbba28a205fa 580 * @see ACCBW, GODRBW and MODR enums
krebyy 0:cbba28a205fa 581 */
krebyy 0:cbba28a205fa 582 void init(uint8_t mAscale = AFS_2G, uint8_t ACCBW = ABW_16Hz,
krebyy 0:cbba28a205fa 583 uint8_t mGscale = GFS_125DPS, uint8_t GODRBW = G_200Hz23Hz,
krebyy 0:cbba28a205fa 584 uint8_t Mmode = Regular, uint8_t MODR = MODR_10Hz)
krebyy 0:cbba28a205fa 585 {
krebyy 0:cbba28a205fa 586 Ascale = mAscale;
krebyy 0:cbba28a205fa 587 Gscale = mGscale;
krebyy 0:cbba28a205fa 588
krebyy 0:cbba28a205fa 589 // Configure accelerometer
krebyy 0:cbba28a205fa 590 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_PMU_RANGE, Ascale & 0x0F); // Set accelerometer full scale
krebyy 0:cbba28a205fa 591 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_PMU_BW, (0x08 | ACCBW) & 0x0F); // Set accelerometer bandwidth
krebyy 0:cbba28a205fa 592 writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_D_HBW, 0x00); // Use filtered data
krebyy 0:cbba28a205fa 593
krebyy 0:cbba28a205fa 594 // Configure Gyro
krebyy 0:cbba28a205fa 595 writeByte(BMX055_GYRO_ADDRESS, BMX055_GYRO_RANGE, Gscale); // set GYRO FS range
krebyy 0:cbba28a205fa 596 writeByte(BMX055_GYRO_ADDRESS, BMX055_GYRO_BW, GODRBW); // set GYRO ODR and Bandwidth
krebyy 0:cbba28a205fa 597
krebyy 0:cbba28a205fa 598 // Configure magnetometer
krebyy 0:cbba28a205fa 599 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_PWR_CNTL1, 0x82); // Softreset magnetometer, ends up in sleep mode
krebyy 0:cbba28a205fa 600 wait_ms(100);
krebyy 0:cbba28a205fa 601 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_PWR_CNTL1, 0x01); // Wake up magnetometer
krebyy 0:cbba28a205fa 602 wait_ms(100);
krebyy 0:cbba28a205fa 603 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_PWR_CNTL2, MODR << 3); // Normal mode
krebyy 0:cbba28a205fa 604
krebyy 0:cbba28a205fa 605 // Set up four standard configurations for the magnetometer
krebyy 0:cbba28a205fa 606 switch (Mmode)
krebyy 0:cbba28a205fa 607 {
krebyy 0:cbba28a205fa 608 case lowPower:
krebyy 0:cbba28a205fa 609 // Low-power
krebyy 0:cbba28a205fa 610 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_XY, 0x01); // 3 repetitions (oversampling)
krebyy 0:cbba28a205fa 611 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_Z, 0x02); // 3 repetitions (oversampling)
krebyy 0:cbba28a205fa 612 break;
krebyy 0:cbba28a205fa 613 case Regular:
krebyy 0:cbba28a205fa 614 // Regular
krebyy 0:cbba28a205fa 615 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_XY, 0x04); // 9 repetitions (oversampling)
krebyy 0:cbba28a205fa 616 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_Z, 0x16); // 15 repetitions (oversampling)
krebyy 0:cbba28a205fa 617 break;
krebyy 0:cbba28a205fa 618 case enhancedRegular:
krebyy 0:cbba28a205fa 619 // Enhanced Regular
krebyy 0:cbba28a205fa 620 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_XY, 0x07); // 15 repetitions (oversampling)
krebyy 0:cbba28a205fa 621 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_Z, 0x22); // 27 repetitions (oversampling)
krebyy 0:cbba28a205fa 622 break;
krebyy 0:cbba28a205fa 623 case highAccuracy:
krebyy 0:cbba28a205fa 624 // High Accuracy
krebyy 0:cbba28a205fa 625 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_XY, 0x17); // 47 repetitions (oversampling)
krebyy 0:cbba28a205fa 626 writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_REP_Z, 0x51); // 83 repetitions (oversampling)
krebyy 0:cbba28a205fa 627 break;
krebyy 0:cbba28a205fa 628 }
krebyy 0:cbba28a205fa 629
krebyy 0:cbba28a205fa 630 // get sensor resolutions, only need to do this once
krebyy 0:cbba28a205fa 631 getAres();
krebyy 0:cbba28a205fa 632 getGres();
krebyy 0:cbba28a205fa 633 // magnetometer resolution is 1 microTesla/16 counts or 1/1.6 milliGauss/count
krebyy 0:cbba28a205fa 634 mRes = 1./1.6;
krebyy 0:cbba28a205fa 635
krebyy 0:cbba28a205fa 636 trim(); // read the magnetometer calibration data
krebyy 0:cbba28a205fa 637
krebyy 0:cbba28a205fa 638 fastcompaccelBMX055(accelBias);
krebyy 0:cbba28a205fa 639 magcalBMX055(magBias);
krebyy 0:cbba28a205fa 640 // TODO: see magcalBMX055(): 128 samples * 105ms = 13.44s
krebyy 0:cbba28a205fa 641 // So far, magnetometer bias is calculated and subtracted here manually, should construct an algorithm to do it automatically
krebyy 0:cbba28a205fa 642 // like the gyro and accelerometer biases
krebyy 0:cbba28a205fa 643 // magBias[0] = -5.; // User environmental x-axis correction in milliGauss
krebyy 0:cbba28a205fa 644 // magBias[1] = -95.; // User environmental y-axis correction in milliGauss
krebyy 0:cbba28a205fa 645 // magBias[2] = -260.; // User environmental z-axis correction in milliGauss
krebyy 0:cbba28a205fa 646
krebyy 0:cbba28a205fa 647 }
krebyy 0:cbba28a205fa 648
krebyy 0:cbba28a205fa 649 // Implementation of Sebastian Madgwick's "...efficient orientation filter for... inertial/magnetic sensor arrays"
krebyy 0:cbba28a205fa 650 // (see http://www.x-io.co.uk/category/open-source/ for examples and more details)
krebyy 0:cbba28a205fa 651 // which fuses acceleration, rotation rate, and magnetic moments to produce a quaternion-based estimate of absolute
krebyy 0:cbba28a205fa 652 // device orientation -- which can be converted to yaw, pitch, and roll. Useful for stabilizing quadcopters, etc.
krebyy 0:cbba28a205fa 653 // The performance of the orientation filter is at least as good as conventional Kalman-based filtering algorithms
krebyy 0:cbba28a205fa 654 // but is much less computationally intensive
krebyy 0:cbba28a205fa 655 void MadgwickQuaternionUpdate(float ax, float ay, float az, float gx, float gy, float gz, float mx, float my, float mz)
krebyy 0:cbba28a205fa 656 {
krebyy 0:cbba28a205fa 657 float q1 = q[0], q2 = q[1], q3 = q[2], q4 = q[3]; // short name local variable for readability
krebyy 0:cbba28a205fa 658 float norm;
krebyy 0:cbba28a205fa 659 float hx, hy, _2bx, _2bz;
krebyy 0:cbba28a205fa 660 float s1, s2, s3, s4;
krebyy 0:cbba28a205fa 661 float qDot1, qDot2, qDot3, qDot4;
krebyy 0:cbba28a205fa 662
krebyy 0:cbba28a205fa 663 // Auxiliary variables to avoid repeated arithmetic
krebyy 0:cbba28a205fa 664 float _2q1mx;
krebyy 0:cbba28a205fa 665 float _2q1my;
krebyy 0:cbba28a205fa 666 float _2q1mz;
krebyy 0:cbba28a205fa 667 float _2q2mx;
krebyy 0:cbba28a205fa 668 float _4bx;
krebyy 0:cbba28a205fa 669 float _4bz;
krebyy 0:cbba28a205fa 670 float _2q1 = 2.0f * q1;
krebyy 0:cbba28a205fa 671 float _2q2 = 2.0f * q2;
krebyy 0:cbba28a205fa 672 float _2q3 = 2.0f * q3;
krebyy 0:cbba28a205fa 673 float _2q4 = 2.0f * q4;
krebyy 0:cbba28a205fa 674 float _2q1q3 = 2.0f * q1 * q3;
krebyy 0:cbba28a205fa 675 float _2q3q4 = 2.0f * q3 * q4;
krebyy 0:cbba28a205fa 676 float q1q1 = q1 * q1;
krebyy 0:cbba28a205fa 677 float q1q2 = q1 * q2;
krebyy 0:cbba28a205fa 678 float q1q3 = q1 * q3;
krebyy 0:cbba28a205fa 679 float q1q4 = q1 * q4;
krebyy 0:cbba28a205fa 680 float q2q2 = q2 * q2;
krebyy 0:cbba28a205fa 681 float q2q3 = q2 * q3;
krebyy 0:cbba28a205fa 682 float q2q4 = q2 * q4;
krebyy 0:cbba28a205fa 683 float q3q3 = q3 * q3;
krebyy 0:cbba28a205fa 684 float q3q4 = q3 * q4;
krebyy 0:cbba28a205fa 685 float q4q4 = q4 * q4;
krebyy 0:cbba28a205fa 686
krebyy 0:cbba28a205fa 687 // Normalise accelerometer measurement
krebyy 0:cbba28a205fa 688 norm = sqrt(ax * ax + ay * ay + az * az);
krebyy 0:cbba28a205fa 689 if (norm == 0.0f) return; // handle NaN
krebyy 0:cbba28a205fa 690 norm = 1.0f/norm;
krebyy 0:cbba28a205fa 691 ax *= norm;
krebyy 0:cbba28a205fa 692 ay *= norm;
krebyy 0:cbba28a205fa 693 az *= norm;
krebyy 0:cbba28a205fa 694
krebyy 0:cbba28a205fa 695 // Normalise magnetometer measurement
krebyy 0:cbba28a205fa 696 norm = sqrt(mx * mx + my * my + mz * mz);
krebyy 0:cbba28a205fa 697 if (norm == 0.0f) return; // handle NaN
krebyy 0:cbba28a205fa 698 norm = 1.0f/norm;
krebyy 0:cbba28a205fa 699 mx *= norm;
krebyy 0:cbba28a205fa 700 my *= norm;
krebyy 0:cbba28a205fa 701 mz *= norm;
krebyy 0:cbba28a205fa 702
krebyy 0:cbba28a205fa 703 // Reference direction of Earth's magnetic field
krebyy 0:cbba28a205fa 704 _2q1mx = 2.0f * q1 * mx;
krebyy 0:cbba28a205fa 705 _2q1my = 2.0f * q1 * my;
krebyy 0:cbba28a205fa 706 _2q1mz = 2.0f * q1 * mz;
krebyy 0:cbba28a205fa 707 _2q2mx = 2.0f * q2 * mx;
krebyy 0:cbba28a205fa 708 hx = mx * q1q1 - _2q1my * q4 + _2q1mz * q3 + mx * q2q2 + _2q2 * my * q3 + _2q2 * mz * q4 - mx * q3q3 - mx * q4q4;
krebyy 0:cbba28a205fa 709 hy = _2q1mx * q4 + my * q1q1 - _2q1mz * q2 + _2q2mx * q3 - my * q2q2 + my * q3q3 + _2q3 * mz * q4 - my * q4q4;
krebyy 0:cbba28a205fa 710 _2bx = sqrt(hx * hx + hy * hy);
krebyy 0:cbba28a205fa 711 _2bz = -_2q1mx * q3 + _2q1my * q2 + mz * q1q1 + _2q2mx * q4 - mz * q2q2 + _2q3 * my * q4 - mz * q3q3 + mz * q4q4;
krebyy 0:cbba28a205fa 712 _4bx = 2.0f * _2bx;
krebyy 0:cbba28a205fa 713 _4bz = 2.0f * _2bz;
krebyy 0:cbba28a205fa 714
krebyy 0:cbba28a205fa 715 // Gradient decent algorithm corrective step
krebyy 0:cbba28a205fa 716 s1 = -_2q3 * (2.0f * q2q4 - _2q1q3 - ax) + _2q2 * (2.0f * q1q2 + _2q3q4 - ay) - _2bz * q3 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q4 + _2bz * q2) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q3 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
krebyy 0:cbba28a205fa 717 s2 = _2q4 * (2.0f * q2q4 - _2q1q3 - ax) + _2q1 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q2 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + _2bz * q4 * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q3 + _2bz * q1) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q4 - _4bz * q2) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
krebyy 0:cbba28a205fa 718 s3 = -_2q1 * (2.0f * q2q4 - _2q1q3 - ax) + _2q4 * (2.0f * q1q2 + _2q3q4 - ay) - 4.0f * q3 * (1.0f - 2.0f * q2q2 - 2.0f * q3q3 - az) + (-_4bx * q3 - _2bz * q1) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (_2bx * q2 + _2bz * q4) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + (_2bx * q1 - _4bz * q3) * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
krebyy 0:cbba28a205fa 719 s4 = _2q2 * (2.0f * q2q4 - _2q1q3 - ax) + _2q3 * (2.0f * q1q2 + _2q3q4 - ay) + (-_4bx * q4 + _2bz * q2) * (_2bx * (0.5f - q3q3 - q4q4) + _2bz * (q2q4 - q1q3) - mx) + (-_2bx * q1 + _2bz * q3) * (_2bx * (q2q3 - q1q4) + _2bz * (q1q2 + q3q4) - my) + _2bx * q2 * (_2bx * (q1q3 + q2q4) + _2bz * (0.5f - q2q2 - q3q3) - mz);
krebyy 0:cbba28a205fa 720 norm = sqrt(s1 * s1 + s2 * s2 + s3 * s3 + s4 * s4); // normalise step magnitude
krebyy 0:cbba28a205fa 721 norm = 1.0f/norm;
krebyy 0:cbba28a205fa 722 s1 *= norm;
krebyy 0:cbba28a205fa 723 s2 *= norm;
krebyy 0:cbba28a205fa 724 s3 *= norm;
krebyy 0:cbba28a205fa 725 s4 *= norm;
krebyy 0:cbba28a205fa 726
krebyy 0:cbba28a205fa 727 // Compute rate of change of quaternion
krebyy 0:cbba28a205fa 728 qDot1 = 0.5f * (-q2 * gx - q3 * gy - q4 * gz) - beta * s1;
krebyy 0:cbba28a205fa 729 qDot2 = 0.5f * (q1 * gx + q3 * gz - q4 * gy) - beta * s2;
krebyy 0:cbba28a205fa 730 qDot3 = 0.5f * (q1 * gy - q2 * gz + q4 * gx) - beta * s3;
krebyy 0:cbba28a205fa 731 qDot4 = 0.5f * (q1 * gz + q2 * gy - q3 * gx) - beta * s4;
krebyy 0:cbba28a205fa 732
krebyy 0:cbba28a205fa 733 // Integrate to yield quaternion
krebyy 0:cbba28a205fa 734 q1 += qDot1 * deltat;
krebyy 0:cbba28a205fa 735 q2 += qDot2 * deltat;
krebyy 0:cbba28a205fa 736 q3 += qDot3 * deltat;
krebyy 0:cbba28a205fa 737 q4 += qDot4 * deltat;
krebyy 0:cbba28a205fa 738 norm = sqrt(q1 * q1 + q2 * q2 + q3 * q3 + q4 * q4); // normalise quaternion
krebyy 0:cbba28a205fa 739 norm = 1.0f/norm;
krebyy 0:cbba28a205fa 740 q[0] = q1 * norm;
krebyy 0:cbba28a205fa 741 q[1] = q2 * norm;
krebyy 0:cbba28a205fa 742 q[2] = q3 * norm;
krebyy 0:cbba28a205fa 743 q[3] = q4 * norm;
krebyy 0:cbba28a205fa 744
krebyy 0:cbba28a205fa 745 }
krebyy 0:cbba28a205fa 746
krebyy 0:cbba28a205fa 747 /** Get raw 9-axis motion sensor readings (accel/gyro/compass).
krebyy 0:cbba28a205fa 748 * @param ax 12-bit signed integer container for accelerometer X-axis value
krebyy 0:cbba28a205fa 749 * @param ay 12-bit signed integer container for accelerometer Y-axis value
krebyy 0:cbba28a205fa 750 * @param az 12-bit signed integer container for accelerometer Z-axis value
krebyy 0:cbba28a205fa 751 * @param gx 16-bit signed integer container for gyroscope X-axis value
krebyy 0:cbba28a205fa 752 * @param gy 16-bit signed integer container for gyroscope Y-axis value
krebyy 0:cbba28a205fa 753 * @param gz 16-bit signed integer container for gyroscope Z-axis value
krebyy 0:cbba28a205fa 754 * @param mx 13-bit signed integer container for magnetometer X-axis value
krebyy 0:cbba28a205fa 755 * @param my 13-bit signed integer container for magnetometer Y-axis value
krebyy 0:cbba28a205fa 756 * @param mz 15-bit signed integer container for magnetometer Z-axis value
krebyy 0:cbba28a205fa 757 * @see getAcceleration()
krebyy 0:cbba28a205fa 758 * @see getRotation()
krebyy 0:cbba28a205fa 759 * @see getMag()
krebyy 0:cbba28a205fa 760 */
krebyy 0:cbba28a205fa 761 void getRaw9( int16_t* ax, int16_t* ay, int16_t* az,
krebyy 0:cbba28a205fa 762 int16_t* gx, int16_t* gy, int16_t* gz,
krebyy 0:cbba28a205fa 763 int16_t* mx, int16_t* my, int16_t* mz)
krebyy 0:cbba28a205fa 764 {
krebyy 0:cbba28a205fa 765 uint8_t rawData[8]; // x/y/z MSB and LSB registers raw data stored here
krebyy 0:cbba28a205fa 766
krebyy 0:cbba28a205fa 767 // Read the six raw data registers into data array
krebyy 0:cbba28a205fa 768 // Turn the MSB and LSB into a signed 12-bit value
krebyy 0:cbba28a205fa 769 readBytes(BMX055_ACC_ADDRESS, BMX055_ACC_D_X_LSB, 6, rawData);
krebyy 0:cbba28a205fa 770 *ax = (int16_t)(((int16_t)rawData[1] << 8) | rawData[0]) >> 4;
krebyy 0:cbba28a205fa 771 *ay = (int16_t)(((int16_t)rawData[3] << 8) | rawData[2]) >> 4;
krebyy 0:cbba28a205fa 772 *az = (int16_t)(((int16_t)rawData[5] << 8) | rawData[4]) >> 4;
krebyy 0:cbba28a205fa 773
krebyy 0:cbba28a205fa 774 // Read the six raw data registers sequentially into data array
krebyy 0:cbba28a205fa 775 // Turn the MSB and LSB into a signed 16-bit value
krebyy 0:cbba28a205fa 776 readBytes(BMX055_GYRO_ADDRESS, BMX055_GYRO_RATE_X_LSB, 6, rawData);
krebyy 0:cbba28a205fa 777 *gx = (int16_t)(((int16_t)rawData[1] << 8) | rawData[0]);
krebyy 0:cbba28a205fa 778 *gy = (int16_t)(((int16_t)rawData[3] << 8) | rawData[2]);
krebyy 0:cbba28a205fa 779 *gz = (int16_t)(((int16_t)rawData[5] << 8) | rawData[4]);
krebyy 0:cbba28a205fa 780
krebyy 0:cbba28a205fa 781 // Read the six raw data registers into data array
krebyy 0:cbba28a205fa 782 // 13-bit signed integer for x-axis and y-axis field
krebyy 0:cbba28a205fa 783 // 15-bit signed integer for z-axis field
krebyy 0:cbba28a205fa 784 readBytes(BMX055_MAG_ADDRESS, BMX055_MAG_XOUT_LSB, 8, rawData);
krebyy 0:cbba28a205fa 785 if(rawData[6] & 0x01) // Check if data ready status bit is set
krebyy 0:cbba28a205fa 786 {
krebyy 0:cbba28a205fa 787 *mx = (int16_t)(((int16_t)rawData[1] << 8) | rawData[0]) >> 3;
krebyy 0:cbba28a205fa 788 *my = (int16_t)(((int16_t)rawData[3] << 8) | rawData[2]) >> 3;
krebyy 0:cbba28a205fa 789 *mz = (int16_t)(((int16_t)rawData[5] << 8) | rawData[4]) >> 1;
krebyy 0:cbba28a205fa 790 }
krebyy 0:cbba28a205fa 791 }
krebyy 0:cbba28a205fa 792
krebyy 0:cbba28a205fa 793 /** Get raw 9-axis motion sensor readings (accel/gyro/compass).
krebyy 0:cbba28a205fa 794 * @param ax accelerometer X-axis value (g's)
krebyy 0:cbba28a205fa 795 * @param ay accelerometer Y-axis value (g's)
krebyy 0:cbba28a205fa 796 * @param az accelerometer Z-axis value (g's)
krebyy 0:cbba28a205fa 797 * @param gx gyroscope X-axis value (degrees per second)
krebyy 0:cbba28a205fa 798 * @param gy gyroscope Y-axis value (degrees per second)
krebyy 0:cbba28a205fa 799 * @param gz gyroscope Z-axis value (degrees per second)
krebyy 0:cbba28a205fa 800 * @param mx magnetometer X-axis value (milliGauss)
krebyy 0:cbba28a205fa 801 * @param my magnetometer Y-axis value (milliGauss)
krebyy 0:cbba28a205fa 802 * @param mz magnetometer Z-axis value (milliGauss)
krebyy 0:cbba28a205fa 803 * @see getAcceleration()
krebyy 0:cbba28a205fa 804 * @see getRotation()
krebyy 0:cbba28a205fa 805 * @see getMag()
krebyy 0:cbba28a205fa 806 */
krebyy 0:cbba28a205fa 807 void getMotion9( float* ax, float* ay, float* az,
krebyy 0:cbba28a205fa 808 float* gx, float* gy, float* gz,
krebyy 0:cbba28a205fa 809 float* mx, float* my, float* mz)
krebyy 0:cbba28a205fa 810 {
krebyy 0:cbba28a205fa 811 int16_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output
krebyy 0:cbba28a205fa 812 int16_t gyroCount[3]; // Stores the 16-bit signed gyro sensor output
krebyy 0:cbba28a205fa 813 int16_t magCount[3]; // Stores the 13/15-bit signed magnetometer sensor output
krebyy 0:cbba28a205fa 814
krebyy 0:cbba28a205fa 815 // Read the x/y/z raw values
krebyy 0:cbba28a205fa 816 readAccelData(accelCount);
krebyy 0:cbba28a205fa 817
krebyy 0:cbba28a205fa 818 // Calculate the accleration value into actual g's
krebyy 0:cbba28a205fa 819 // get actual g value, this depends on scale being set
krebyy 0:cbba28a205fa 820 *ax = (float)accelCount[0]*aRes; // + accelBias[0];
krebyy 0:cbba28a205fa 821 *ay = (float)accelCount[1]*aRes; // + accelBias[1];
krebyy 0:cbba28a205fa 822 *az = (float)accelCount[2]*aRes; // + accelBias[2];
krebyy 0:cbba28a205fa 823
krebyy 0:cbba28a205fa 824
krebyy 0:cbba28a205fa 825 // Read the x/y/z raw values
krebyy 0:cbba28a205fa 826 readGyroData(gyroCount);
krebyy 0:cbba28a205fa 827
krebyy 0:cbba28a205fa 828 // Calculate the gyro value into actual degrees per second
krebyy 0:cbba28a205fa 829 // get actual gyro value, this depends on scale being set
krebyy 0:cbba28a205fa 830 *gx = (float)gyroCount[0]*gRes;
krebyy 0:cbba28a205fa 831 *gy = (float)gyroCount[1]*gRes;
krebyy 0:cbba28a205fa 832 *gz = (float)gyroCount[2]*gRes;
krebyy 0:cbba28a205fa 833
krebyy 0:cbba28a205fa 834
krebyy 0:cbba28a205fa 835 // Read the x/y/z raw values
krebyy 0:cbba28a205fa 836 readMagData(magCount);
krebyy 0:cbba28a205fa 837
krebyy 0:cbba28a205fa 838 // Calculate the magnetometer values in milliGauss
krebyy 0:cbba28a205fa 839 // Temperature-compensated magnetic field is in 16 LSB/microTesla
krebyy 0:cbba28a205fa 840 // get actual magnetometer value, this depends on scale being set
krebyy 0:cbba28a205fa 841 *mx = (float)magCount[0]*mRes - magBias[0];
krebyy 0:cbba28a205fa 842 *my = (float)magCount[1]*mRes - magBias[1];
krebyy 0:cbba28a205fa 843 *mz = (float)magCount[2]*mRes - magBias[2];
krebyy 0:cbba28a205fa 844 }
krebyy 0:cbba28a205fa 845
krebyy 0:cbba28a205fa 846 void runAHRS(float mdeltat, float local_declination = LOCAL_DECLINATION)
krebyy 0:cbba28a205fa 847 {
krebyy 0:cbba28a205fa 848 float ax, ay, az, gx, gy, gz, mx, my, mz;
krebyy 0:cbba28a205fa 849
krebyy 0:cbba28a205fa 850 getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
krebyy 0:cbba28a205fa 851 deltat = mdeltat;
krebyy 0:cbba28a205fa 852
krebyy 0:cbba28a205fa 853 // Sensors x (y)-axis of the accelerometer is aligned with the -y (x)-axis of the magnetometer;
krebyy 0:cbba28a205fa 854 // the magnetometer z-axis (+ up) is aligned with z-axis (+ up) of accelerometer and gyro!
krebyy 0:cbba28a205fa 855 // We have to make some allowance for this orientation mismatch in feeding the output to the quaternion filter.
krebyy 0:cbba28a205fa 856 // For the BMX-055, we have chosen a magnetic rotation that keeps the sensor forward along the x-axis just like
krebyy 0:cbba28a205fa 857 // in the MPU9250 sensor. This rotation can be modified to allow any convenient orientation convention.
krebyy 0:cbba28a205fa 858 // This is ok by aircraft orientation standards!
krebyy 0:cbba28a205fa 859 // Pass gyro rate as rad/s
krebyy 0:cbba28a205fa 860 //MadgwickQuaternionUpdate(ax, ay, az, gx*M_PI/180.0f, gy*M_PI/180.0f, gz*M_PI/180.0f, -my, mx, mz);
krebyy 0:cbba28a205fa 861 MadgwickQuaternionUpdate(-ay, ax, az, -gy*M_PI/180.0f, gx*M_PI/180.0f, gz*M_PI/180.0f, mx, my, mz);
krebyy 0:cbba28a205fa 862
krebyy 0:cbba28a205fa 863
krebyy 0:cbba28a205fa 864 // Define output variables from updated quaternion---these are Tait-Bryan angles, commonly used in aircraft orientation.
krebyy 0:cbba28a205fa 865 // In this coordinate system, the positive z-axis is down toward Earth.
krebyy 0:cbba28a205fa 866 // Yaw is the angle between Sensor x-axis and Earth magnetic North (or true North if corrected for local declination, looking down on the sensor positive yaw is counterclockwise.
krebyy 0:cbba28a205fa 867 // Pitch is angle between sensor x-axis and Earth ground plane, toward the Earth is positive, up toward the sky is negative.
krebyy 0:cbba28a205fa 868 // Roll is angle between sensor y-axis and Earth ground plane, y-axis up is positive roll.
krebyy 0:cbba28a205fa 869 // These arise from the definition of the homogeneous rotation matrix constructed from quaternions.
krebyy 0:cbba28a205fa 870 // Tait-Bryan angles as well as Euler angles are non-commutative; that is, the get the correct orientation the rotations must be
krebyy 0:cbba28a205fa 871 // applied in the correct order which for this configuration is yaw, pitch, and then roll.
krebyy 0:cbba28a205fa 872 // For more see http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles which has additional links.
krebyy 0:cbba28a205fa 873 yaw = atan2(2.0f * (q[1] * q[2] + q[0] * q[3]), q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3]);
krebyy 0:cbba28a205fa 874 pitch = -asin(2.0f * (q[1] * q[3] - q[0] * q[2]));
krebyy 0:cbba28a205fa 875 roll = atan2(2.0f * (q[0] * q[1] + q[2] * q[3]), q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3]);
krebyy 0:cbba28a205fa 876 pitch *= 180.0f / M_PI;
krebyy 0:cbba28a205fa 877 yaw *= 180.0f / M_PI;
krebyy 0:cbba28a205fa 878 yaw -= local_declination;
krebyy 0:cbba28a205fa 879 roll *= 180.0f / M_PI;
krebyy 0:cbba28a205fa 880 }
krebyy 0:cbba28a205fa 881 };
krebyy 0:cbba28a205fa 882
krebyy 0:cbba28a205fa 883 #endif /* BMX055_H_ */