Components and supplies
USB-6008 National Instruments USB Data Acquisition Card
Pressure Sensor, Differential
Arduino UNO
RTD Sensor, PT100
Inertial Measurement Unit (IMU) (6 deg of freedom)
Project description
Code
Gyro Code
arduino
Code for IMU 6050 gyro sensor.
1 2// MPU-6050 Accelerometer + Gyro + Arduino Uno 3// ----------------------------- 4// 5// 6// June 2012 7// Open Source / Public Domain 8// 9// Using Arduino 1.0.1 10// It will not work with an older version, 11// since Wire.endTransmission() uses a parameter 12// to hold or release the I2C bus. 13// 14// Documentation: 15// - The InvenSense documents: 16// - "MPU-6000 and MPU-6050 Product Specification", 17// PS-MPU-6000A.pdf 18// - "MPU-6000 and MPU-6050 Register Map and Descriptions", 19// RM-MPU-6000A.pdf or RS-MPU-6000A.pdf 20// - "MPU-6000/MPU-6050 9-Axis Evaluation Board User Guide" 21// AN-MPU-6000EVB.pdf 22// 23// The accuracy is 16-bits. 24// 25// Temperature sensor from -40 to +85 degrees Celsius 26// 340 per degrees, -512 at 35 degrees. 27// 28// At power-up, all registers are zero, except these two: 29// Register 0x6B (PWR_MGMT_2) = 0x40 (I read zero). 30// Register 0x75 (WHO_AM_I) = 0x68. 31// 32 33#include <Wire.h> 34 35 36// Register names according to the datasheet. 37// According to the InvenSense document 38// "MPU-6000 and MPU-6050 Register Map 39// and Descriptions Revision 3.2", there are no registers 40// at 0x02 ... 0x18, but according other information 41// the registers in that unknown area are for gain 42// and offsets. 43// 44#define MPU6050_AUX_VDDIO 0x01 // R/W 45#define MPU6050_SMPLRT_DIV 0x19 // R/W 46#define MPU6050_CONFIG 0x1A // R/W 47#define MPU6050_GYRO_CONFIG 0x1B // R/W 48#define MPU6050_ACCEL_CONFIG 0x1C // R/W 49#define MPU6050_FF_THR 0x1D // R/W 50#define MPU6050_FF_DUR 0x1E // R/W 51#define MPU6050_MOT_THR 0x1F // R/W 52#define MPU6050_MOT_DUR 0x20 // R/W 53#define MPU6050_ZRMOT_THR 0x21 // R/W 54#define MPU6050_ZRMOT_DUR 0x22 // R/W 55#define MPU6050_FIFO_EN 0x23 // R/W 56#define MPU6050_I2C_MST_CTRL 0x24 // R/W 57#define MPU6050_I2C_SLV0_ADDR 0x25 // R/W 58#define MPU6050_I2C_SLV0_REG 0x26 // R/W 59#define MPU6050_I2C_SLV0_CTRL 0x27 // R/W 60#define MPU6050_I2C_SLV1_ADDR 0x28 // R/W 61#define MPU6050_I2C_SLV1_REG 0x29 // R/W 62#define MPU6050_I2C_SLV1_CTRL 0x2A // R/W 63#define MPU6050_I2C_SLV2_ADDR 0x2B // R/W 64#define MPU6050_I2C_SLV2_REG 0x2C // R/W 65#define MPU6050_I2C_SLV2_CTRL 0x2D // R/W 66#define MPU6050_I2C_SLV3_ADDR 0x2E // R/W 67#define MPU6050_I2C_SLV3_REG 0x2F // R/W 68#define MPU6050_I2C_SLV3_CTRL 0x30 // R/W 69#define MPU6050_I2C_SLV4_ADDR 0x31 // R/W 70#define MPU6050_I2C_SLV4_REG 0x32 // R/W 71#define MPU6050_I2C_SLV4_DO 0x33 // R/W 72#define MPU6050_I2C_SLV4_CTRL 0x34 // R/W 73#define MPU6050_I2C_SLV4_DI 0x35 // R 74#define MPU6050_I2C_MST_STATUS 0x36 // R 75#define MPU6050_INT_PIN_CFG 0x37 // R/W 76#define MPU6050_INT_ENABLE 0x38 // R/W 77#define MPU6050_INT_STATUS 0x3A // R 78#define MPU6050_ACCEL_XOUT_H 0x3B // R 79#define MPU6050_ACCEL_XOUT_L 0x3C // R 80#define MPU6050_ACCEL_YOUT_H 0x3D // R 81#define MPU6050_ACCEL_YOUT_L 0x3E // R 82#define MPU6050_ACCEL_ZOUT_H 0x3F // R 83#define MPU6050_ACCEL_ZOUT_L 0x40 // R 84#define MPU6050_TEMP_OUT_H 0x41 // R 85#define MPU6050_TEMP_OUT_L 0x42 // R 86#define MPU6050_GYRO_XOUT_H 0x43 // R 87#define MPU6050_GYRO_XOUT_L 0x44 // R 88#define MPU6050_GYRO_YOUT_H 0x45 // R 89#define MPU6050_GYRO_YOUT_L 0x46 // R 90#define MPU6050_GYRO_ZOUT_H 0x47 // R 91#define MPU6050_GYRO_ZOUT_L 0x48 // R 92#define MPU6050_EXT_SENS_DATA_00 0x49 // R 93#define MPU6050_EXT_SENS_DATA_01 0x4A // R 94#define MPU6050_EXT_SENS_DATA_02 0x4B // R 95#define MPU6050_EXT_SENS_DATA_03 0x4C // R 96#define MPU6050_EXT_SENS_DATA_04 0x4D // R 97#define MPU6050_EXT_SENS_DATA_05 0x4E // R 98#define MPU6050_EXT_SENS_DATA_06 0x4F // R 99#define MPU6050_EXT_SENS_DATA_07 0x50 // R 100#define MPU6050_EXT_SENS_DATA_08 0x51 // R 101#define MPU6050_EXT_SENS_DATA_09 0x52 // R 102#define MPU6050_EXT_SENS_DATA_10 0x53 // R 103#define MPU6050_EXT_SENS_DATA_11 0x54 // R 104#define MPU6050_EXT_SENS_DATA_12 0x55 // R 105#define MPU6050_EXT_SENS_DATA_13 0x56 // R 106#define MPU6050_EXT_SENS_DATA_14 0x57 // R 107#define MPU6050_EXT_SENS_DATA_15 0x58 // R 108#define MPU6050_EXT_SENS_DATA_16 0x59 // R 109#define MPU6050_EXT_SENS_DATA_17 0x5A // R 110#define MPU6050_EXT_SENS_DATA_18 0x5B // R 111#define MPU6050_EXT_SENS_DATA_19 0x5C // R 112#define MPU6050_EXT_SENS_DATA_20 0x5D // R 113#define MPU6050_EXT_SENS_DATA_21 0x5E // R 114#define MPU6050_EXT_SENS_DATA_22 0x5F // R 115#define MPU6050_EXT_SENS_DATA_23 0x60 // R 116#define MPU6050_MOT_DETECT_STATUS 0x61 // R 117#define MPU6050_I2C_SLV0_DO 0x63 // R/W 118#define MPU6050_I2C_SLV1_DO 0x64 // R/W 119#define MPU6050_I2C_SLV2_DO 0x65 // R/W 120#define MPU6050_I2C_SLV3_DO 0x66 // R/W 121#define MPU6050_I2C_MST_DELAY_CTRL 0x67 // R/W 122#define MPU6050_SIGNAL_PATH_RESET 0x68 // R/W 123#define MPU6050_MOT_DETECT_CTRL 0x69 // R/W 124#define MPU6050_USER_CTRL 0x6A // R/W 125#define MPU6050_PWR_MGMT_1 0x6B // R/W 126#define MPU6050_PWR_MGMT_2 0x6C // R/W 127#define MPU6050_FIFO_COUNTH 0x72 // R/W 128#define MPU6050_FIFO_COUNTL 0x73 // R/W 129#define MPU6050_FIFO_R_W 0x74 // R/W 130#define MPU6050_WHO_AM_I 0x75 // R 131 132 133// Defines for the bits, to be able to change 134// between bit number and binary definition. 135// By using the bit number, programming the sensor 136// is like programming the AVR microcontroller. 137// But instead of using "(1<<X)", or "_BV(X)", 138// the Arduino "bit(X)" is used. 139#define MPU6050_D0 0 140#define MPU6050_D1 1 141#define MPU6050_D2 2 142#define MPU6050_D3 3 143#define MPU6050_D4 4 144#define MPU6050_D5 5 145#define MPU6050_D6 6 146#define MPU6050_D7 7 147 148// AUX_VDDIO Register 149#define MPU6050_AUX_VDDIO MPU6050_D7 // I2C high: 1=VDD, 0=VLOGIC 150 151// CONFIG Register 152// DLPF is Digital Low Pass Filter for both gyro and accelerometers. 153// These are the names for the bits. 154// Use these only with the bit() macro. 155#define MPU6050_DLPF_CFG0 MPU6050_D0 156#define MPU6050_DLPF_CFG1 MPU6050_D1 157#define MPU6050_DLPF_CFG2 MPU6050_D2 158#define MPU6050_EXT_SYNC_SET0 MPU6050_D3 159#define MPU6050_EXT_SYNC_SET1 MPU6050_D4 160#define MPU6050_EXT_SYNC_SET2 MPU6050_D5 161 162// Combined definitions for the EXT_SYNC_SET values 163#define MPU6050_EXT_SYNC_SET_0 (0) 164#define MPU6050_EXT_SYNC_SET_1 (bit(MPU6050_EXT_SYNC_SET0)) 165#define MPU6050_EXT_SYNC_SET_2 (bit(MPU6050_EXT_SYNC_SET1)) 166#define MPU6050_EXT_SYNC_SET_3 (bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0)) 167#define MPU6050_EXT_SYNC_SET_4 (bit(MPU6050_EXT_SYNC_SET2)) 168#define MPU6050_EXT_SYNC_SET_5 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET0)) 169#define MPU6050_EXT_SYNC_SET_6 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1)) 170#define MPU6050_EXT_SYNC_SET_7 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0)) 171 172// Alternative names for the combined definitions. 173#define MPU6050_EXT_SYNC_DISABLED MPU6050_EXT_SYNC_SET_0 174#define MPU6050_EXT_SYNC_TEMP_OUT_L MPU6050_EXT_SYNC_SET_1 175#define MPU6050_EXT_SYNC_GYRO_XOUT_L MPU6050_EXT_SYNC_SET_2 176#define MPU6050_EXT_SYNC_GYRO_YOUT_L MPU6050_EXT_SYNC_SET_3 177#define MPU6050_EXT_SYNC_GYRO_ZOUT_L MPU6050_EXT_SYNC_SET_4 178#define MPU6050_EXT_SYNC_ACCEL_XOUT_L MPU6050_EXT_SYNC_SET_5 179#define MPU6050_EXT_SYNC_ACCEL_YOUT_L MPU6050_EXT_SYNC_SET_6 180#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L MPU6050_EXT_SYNC_SET_7 181 182// Combined definitions for the DLPF_CFG values 183#define MPU6050_DLPF_CFG_0 (0) 184#define MPU6050_DLPF_CFG_1 (bit(MPU6050_DLPF_CFG0)) 185#define MPU6050_DLPF_CFG_2 (bit(MPU6050_DLPF_CFG1)) 186#define MPU6050_DLPF_CFG_3 (bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0)) 187#define MPU6050_DLPF_CFG_4 (bit(MPU6050_DLPF_CFG2)) 188#define MPU6050_DLPF_CFG_5 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG0)) 189#define MPU6050_DLPF_CFG_6 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1)) 190#define MPU6050_DLPF_CFG_7 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0)) 191 192// Alternative names for the combined definitions 193// This name uses the bandwidth (Hz) for the accelometer, 194// for the gyro the bandwidth is almost the same. 195#define MPU6050_DLPF_260HZ MPU6050_DLPF_CFG_0 196#define MPU6050_DLPF_184HZ MPU6050_DLPF_CFG_1 197#define MPU6050_DLPF_94HZ MPU6050_DLPF_CFG_2 198#define MPU6050_DLPF_44HZ MPU6050_DLPF_CFG_3 199#define MPU6050_DLPF_21HZ MPU6050_DLPF_CFG_4 200#define MPU6050_DLPF_10HZ MPU6050_DLPF_CFG_5 201#define MPU6050_DLPF_5HZ MPU6050_DLPF_CFG_6 202#define MPU6050_DLPF_RESERVED MPU6050_DLPF_CFG_7 203 204// GYRO_CONFIG Register 205// The XG_ST, YG_ST, ZG_ST are bits for selftest. 206// The FS_SEL sets the range for the gyro. 207// These are the names for the bits. 208// Use these only with the bit() macro. 209#define MPU6050_FS_SEL0 MPU6050_D3 210#define MPU6050_FS_SEL1 MPU6050_D4 211#define MPU6050_ZG_ST MPU6050_D5 212#define MPU6050_YG_ST MPU6050_D6 213#define MPU6050_XG_ST MPU6050_D7 214 215// Combined definitions for the FS_SEL values 216#define MPU6050_FS_SEL_0 (0) 217#define MPU6050_FS_SEL_1 (bit(MPU6050_FS_SEL0)) 218#define MPU6050_FS_SEL_2 (bit(MPU6050_FS_SEL1)) 219#define MPU6050_FS_SEL_3 (bit(MPU6050_FS_SEL1)|bit(MPU6050_FS_SEL0)) 220 221// Alternative names for the combined definitions 222// The name uses the range in degrees per second. 223#define MPU6050_FS_SEL_250 MPU6050_FS_SEL_0 224#define MPU6050_FS_SEL_500 MPU6050_FS_SEL_1 225#define MPU6050_FS_SEL_1000 MPU6050_FS_SEL_2 226#define MPU6050_FS_SEL_2000 MPU6050_FS_SEL_3 227 228// ACCEL_CONFIG Register 229// The XA_ST, YA_ST, ZA_ST are bits for selftest. 230// The AFS_SEL sets the range for the accelerometer. 231// These are the names for the bits. 232// Use these only with the bit() macro. 233#define MPU6050_ACCEL_HPF0 MPU6050_D0 234#define MPU6050_ACCEL_HPF1 MPU6050_D1 235#define MPU6050_ACCEL_HPF2 MPU6050_D2 236#define MPU6050_AFS_SEL0 MPU6050_D3 237#define MPU6050_AFS_SEL1 MPU6050_D4 238#define MPU6050_ZA_ST MPU6050_D5 239#define MPU6050_YA_ST MPU6050_D6 240#define MPU6050_XA_ST MPU6050_D7 241 242// Combined definitions for the ACCEL_HPF values 243#define MPU6050_ACCEL_HPF_0 (0) 244#define MPU6050_ACCEL_HPF_1 (bit(MPU6050_ACCEL_HPF0)) 245#define MPU6050_ACCEL_HPF_2 (bit(MPU6050_ACCEL_HPF1)) 246#define MPU6050_ACCEL_HPF_3 (bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0)) 247#define MPU6050_ACCEL_HPF_4 (bit(MPU6050_ACCEL_HPF2)) 248#define MPU6050_ACCEL_HPF_7 (bit(MPU6050_ACCEL_HPF2)|bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0)) 249 250// Alternative names for the combined definitions 251// The name uses the Cut-off frequency. 252#define MPU6050_ACCEL_HPF_RESET MPU6050_ACCEL_HPF_0 253#define MPU6050_ACCEL_HPF_5HZ MPU6050_ACCEL_HPF_1 254#define MPU6050_ACCEL_HPF_2_5HZ MPU6050_ACCEL_HPF_2 255#define MPU6050_ACCEL_HPF_1_25HZ MPU6050_ACCEL_HPF_3 256#define MPU6050_ACCEL_HPF_0_63HZ MPU6050_ACCEL_HPF_4 257#define MPU6050_ACCEL_HPF_HOLD MPU6050_ACCEL_HPF_7 258 259// Combined definitions for the AFS_SEL values 260#define MPU6050_AFS_SEL_0 (0) 261#define MPU6050_AFS_SEL_1 (bit(MPU6050_AFS_SEL0)) 262#define MPU6050_AFS_SEL_2 (bit(MPU6050_AFS_SEL1)) 263#define MPU6050_AFS_SEL_3 (bit(MPU6050_AFS_SEL1)|bit(MPU6050_AFS_SEL0)) 264 265// Alternative names for the combined definitions 266// The name uses the full scale range for the accelerometer. 267#define MPU6050_AFS_SEL_2G MPU6050_AFS_SEL_0 268#define MPU6050_AFS_SEL_4G MPU6050_AFS_SEL_1 269#define MPU6050_AFS_SEL_8G MPU6050_AFS_SEL_2 270#define MPU6050_AFS_SEL_16G MPU6050_AFS_SEL_3 271 272// FIFO_EN Register 273// These are the names for the bits. 274// Use these only with the bit() macro. 275#define MPU6050_SLV0_FIFO_EN MPU6050_D0 276#define MPU6050_SLV1_FIFO_EN MPU6050_D1 277#define MPU6050_SLV2_FIFO_EN MPU6050_D2 278#define MPU6050_ACCEL_FIFO_EN MPU6050_D3 279#define MPU6050_ZG_FIFO_EN MPU6050_D4 280#define MPU6050_YG_FIFO_EN MPU6050_D5 281#define MPU6050_XG_FIFO_EN MPU6050_D6 282#define MPU6050_TEMP_FIFO_EN MPU6050_D7 283 284// I2C_MST_CTRL Register 285// These are the names for the bits. 286// Use these only with the bit() macro. 287#define MPU6050_I2C_MST_CLK0 MPU6050_D0 288#define MPU6050_I2C_MST_CLK1 MPU6050_D1 289#define MPU6050_I2C_MST_CLK2 MPU6050_D2 290#define MPU6050_I2C_MST_CLK3 MPU6050_D3 291#define MPU6050_I2C_MST_P_NSR MPU6050_D4 292#define MPU6050_SLV_3_FIFO_EN MPU6050_D5 293#define MPU6050_WAIT_FOR_ES MPU6050_D6 294#define MPU6050_MULT_MST_EN MPU6050_D7 295 296// Combined definitions for the I2C_MST_CLK 297#define MPU6050_I2C_MST_CLK_0 (0) 298#define MPU6050_I2C_MST_CLK_1 (bit(MPU6050_I2C_MST_CLK0)) 299#define MPU6050_I2C_MST_CLK_2 (bit(MPU6050_I2C_MST_CLK1)) 300#define MPU6050_I2C_MST_CLK_3 (bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 301#define MPU6050_I2C_MST_CLK_4 (bit(MPU6050_I2C_MST_CLK2)) 302#define MPU6050_I2C_MST_CLK_5 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0)) 303#define MPU6050_I2C_MST_CLK_6 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)) 304#define MPU6050_I2C_MST_CLK_7 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 305#define MPU6050_I2C_MST_CLK_8 (bit(MPU6050_I2C_MST_CLK3)) 306#define MPU6050_I2C_MST_CLK_9 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK0)) 307#define MPU6050_I2C_MST_CLK_10 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1)) 308#define MPU6050_I2C_MST_CLK_11 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 309#define MPU6050_I2C_MST_CLK_12 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)) 310#define MPU6050_I2C_MST_CLK_13 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0)) 311#define MPU6050_I2C_MST_CLK_14 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)) 312#define MPU6050_I2C_MST_CLK_15 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 313 314// Alternative names for the combined definitions 315// The names uses I2C Master Clock Speed in kHz. 316#define MPU6050_I2C_MST_CLK_348KHZ MPU6050_I2C_MST_CLK_0 317#define MPU6050_I2C_MST_CLK_333KHZ MPU6050_I2C_MST_CLK_1 318#define MPU6050_I2C_MST_CLK_320KHZ MPU6050_I2C_MST_CLK_2 319#define MPU6050_I2C_MST_CLK_308KHZ MPU6050_I2C_MST_CLK_3 320#define MPU6050_I2C_MST_CLK_296KHZ MPU6050_I2C_MST_CLK_4 321#define MPU6050_I2C_MST_CLK_286KHZ MPU6050_I2C_MST_CLK_5 322#define MPU6050_I2C_MST_CLK_276KHZ MPU6050_I2C_MST_CLK_6 323#define MPU6050_I2C_MST_CLK_267KHZ MPU6050_I2C_MST_CLK_7 324#define MPU6050_I2C_MST_CLK_258KHZ MPU6050_I2C_MST_CLK_8 325#define MPU6050_I2C_MST_CLK_500KHZ MPU6050_I2C_MST_CLK_9 326#define MPU6050_I2C_MST_CLK_471KHZ MPU6050_I2C_MST_CLK_10 327#define MPU6050_I2C_MST_CLK_444KHZ MPU6050_I2C_MST_CLK_11 328#define MPU6050_I2C_MST_CLK_421KHZ MPU6050_I2C_MST_CLK_12 329#define MPU6050_I2C_MST_CLK_400KHZ MPU6050_I2C_MST_CLK_13 330#define MPU6050_I2C_MST_CLK_381KHZ MPU6050_I2C_MST_CLK_14 331#define MPU6050_I2C_MST_CLK_364KHZ MPU6050_I2C_MST_CLK_15 332 333// I2C_SLV0_ADDR Register 334// These are the names for the bits. 335// Use these only with the bit() macro. 336#define MPU6050_I2C_SLV0_RW MPU6050_D7 337 338// I2C_SLV0_CTRL Register 339// These are the names for the bits. 340// Use these only with the bit() macro. 341#define MPU6050_I2C_SLV0_LEN0 MPU6050_D0 342#define MPU6050_I2C_SLV0_LEN1 MPU6050_D1 343#define MPU6050_I2C_SLV0_LEN2 MPU6050_D2 344#define MPU6050_I2C_SLV0_LEN3 MPU6050_D3 345#define MPU6050_I2C_SLV0_GRP MPU6050_D4 346#define MPU6050_I2C_SLV0_REG_DIS MPU6050_D5 347#define MPU6050_I2C_SLV0_BYTE_SW MPU6050_D6 348#define MPU6050_I2C_SLV0_EN MPU6050_D7 349 350// A mask for the length 351#define MPU6050_I2C_SLV0_LEN_MASK 0x0F 352 353// I2C_SLV1_ADDR Register 354// These are the names for the bits. 355// Use these only with the bit() macro. 356#define MPU6050_I2C_SLV1_RW MPU6050_D7 357 358// I2C_SLV1_CTRL Register 359// These are the names for the bits. 360// Use these only with the bit() macro. 361#define MPU6050_I2C_SLV1_LEN0 MPU6050_D0 362#define MPU6050_I2C_SLV1_LEN1 MPU6050_D1 363#define MPU6050_I2C_SLV1_LEN2 MPU6050_D2 364#define MPU6050_I2C_SLV1_LEN3 MPU6050_D3 365#define MPU6050_I2C_SLV1_GRP MPU6050_D4 366#define MPU6050_I2C_SLV1_REG_DIS MPU6050_D5 367#define MPU6050_I2C_SLV1_BYTE_SW MPU6050_D6 368#define MPU6050_I2C_SLV1_EN MPU6050_D7 369 370// A mask for the length 371#define MPU6050_I2C_SLV1_LEN_MASK 0x0F 372 373// I2C_SLV2_ADDR Register 374// These are the names for the bits. 375// Use these only with the bit() macro. 376#define MPU6050_I2C_SLV2_RW MPU6050_D7 377 378// I2C_SLV2_CTRL Register 379// These are the names for the bits. 380// Use these only with the bit() macro. 381#define MPU6050_I2C_SLV2_LEN0 MPU6050_D0 382#define MPU6050_I2C_SLV2_LEN1 MPU6050_D1 383#define MPU6050_I2C_SLV2_LEN2 MPU6050_D2 384#define MPU6050_I2C_SLV2_LEN3 MPU6050_D3 385#define MPU6050_I2C_SLV2_GRP MPU6050_D4 386#define MPU6050_I2C_SLV2_REG_DIS MPU6050_D5 387#define MPU6050_I2C_SLV2_BYTE_SW MPU6050_D6 388#define MPU6050_I2C_SLV2_EN MPU6050_D7 389 390// A mask for the length 391#define MPU6050_I2C_SLV2_LEN_MASK 0x0F 392 393// I2C_SLV3_ADDR Register 394// These are the names for the bits. 395// Use these only with the bit() macro. 396#define MPU6050_I2C_SLV3_RW MPU6050_D7 397 398// I2C_SLV3_CTRL Register 399// These are the names for the bits. 400// Use these only with the bit() macro. 401#define MPU6050_I2C_SLV3_LEN0 MPU6050_D0 402#define MPU6050_I2C_SLV3_LEN1 MPU6050_D1 403#define MPU6050_I2C_SLV3_LEN2 MPU6050_D2 404#define MPU6050_I2C_SLV3_LEN3 MPU6050_D3 405#define MPU6050_I2C_SLV3_GRP MPU6050_D4 406#define MPU6050_I2C_SLV3_REG_DIS MPU6050_D5 407#define MPU6050_I2C_SLV3_BYTE_SW MPU6050_D6 408#define MPU6050_I2C_SLV3_EN MPU6050_D7 409 410// A mask for the length 411#define MPU6050_I2C_SLV3_LEN_MASK 0x0F 412 413// I2C_SLV4_ADDR Register 414// These are the names for the bits. 415// Use these only with the bit() macro. 416#define MPU6050_I2C_SLV4_RW MPU6050_D7 417 418// I2C_SLV4_CTRL Register 419// These are the names for the bits. 420// Use these only with the bit() macro. 421#define MPU6050_I2C_MST_DLY0 MPU6050_D0 422#define MPU6050_I2C_MST_DLY1 MPU6050_D1 423#define MPU6050_I2C_MST_DLY2 MPU6050_D2 424#define MPU6050_I2C_MST_DLY3 MPU6050_D3 425#define MPU6050_I2C_MST_DLY4 MPU6050_D4 426#define MPU6050_I2C_SLV4_REG_DIS MPU6050_D5 427#define MPU6050_I2C_SLV4_INT_EN MPU6050_D6 428#define MPU6050_I2C_SLV4_EN MPU6050_D7 429 430// A mask for the delay 431#define MPU6050_I2C_MST_DLY_MASK 0x1F 432 433// I2C_MST_STATUS Register 434// These are the names for the bits. 435// Use these only with the bit() macro. 436#define MPU6050_I2C_SLV0_NACK MPU6050_D0 437#define MPU6050_I2C_SLV1_NACK MPU6050_D1 438#define MPU6050_I2C_SLV2_NACK MPU6050_D2 439#define MPU6050_I2C_SLV3_NACK MPU6050_D3 440#define MPU6050_I2C_SLV4_NACK MPU6050_D4 441#define MPU6050_I2C_LOST_ARB MPU6050_D5 442#define MPU6050_I2C_SLV4_DONE MPU6050_D6 443#define MPU6050_PASS_THROUGH MPU6050_D7 444 445// I2C_PIN_CFG Register 446// These are the names for the bits. 447// Use these only with the bit() macro. 448#define MPU6050_CLKOUT_EN MPU6050_D0 449#define MPU6050_I2C_BYPASS_EN MPU6050_D1 450#define MPU6050_FSYNC_INT_EN MPU6050_D2 451#define MPU6050_FSYNC_INT_LEVEL MPU6050_D3 452#define MPU6050_INT_RD_CLEAR MPU6050_D4 453#define MPU6050_LATCH_INT_EN MPU6050_D5 454#define MPU6050_INT_OPEN MPU6050_D6 455#define MPU6050_INT_LEVEL MPU6050_D7 456 457// INT_ENABLE Register 458// These are the names for the bits. 459// Use these only with the bit() macro. 460#define MPU6050_DATA_RDY_EN MPU6050_D0 461#define MPU6050_I2C_MST_INT_EN MPU6050_D3 462#define MPU6050_FIFO_OFLOW_EN MPU6050_D4 463#define MPU6050_ZMOT_EN MPU6050_D5 464#define MPU6050_MOT_EN MPU6050_D6 465#define MPU6050_FF_EN MPU6050_D7 466 467// INT_STATUS Register 468// These are the names for the bits. 469// Use these only with the bit() macro. 470#define MPU6050_DATA_RDY_INT MPU6050_D0 471#define MPU6050_I2C_MST_INT MPU6050_D3 472#define MPU6050_FIFO_OFLOW_INT MPU6050_D4 473#define MPU6050_ZMOT_INT MPU6050_D5 474#define MPU6050_MOT_INT MPU6050_D6 475#define MPU6050_FF_INT MPU6050_D7 476 477// MOT_DETECT_STATUS Register 478// These are the names for the bits. 479// Use these only with the bit() macro. 480#define MPU6050_MOT_ZRMOT MPU6050_D0 481#define MPU6050_MOT_ZPOS MPU6050_D2 482#define MPU6050_MOT_ZNEG MPU6050_D3 483#define MPU6050_MOT_YPOS MPU6050_D4 484#define MPU6050_MOT_YNEG MPU6050_D5 485#define MPU6050_MOT_XPOS MPU6050_D6 486#define MPU6050_MOT_XNEG MPU6050_D7 487 488// IC2_MST_DELAY_CTRL Register 489// These are the names for the bits. 490// Use these only with the bit() macro. 491#define MPU6050_I2C_SLV0_DLY_EN MPU6050_D0 492#define MPU6050_I2C_SLV1_DLY_EN MPU6050_D1 493#define MPU6050_I2C_SLV2_DLY_EN MPU6050_D2 494#define MPU6050_I2C_SLV3_DLY_EN MPU6050_D3 495#define MPU6050_I2C_SLV4_DLY_EN MPU6050_D4 496#define MPU6050_DELAY_ES_SHADOW MPU6050_D7 497 498// SIGNAL_PATH_RESET Register 499// These are the names for the bits. 500// Use these only with the bit() macro. 501#define MPU6050_TEMP_RESET MPU6050_D0 502#define MPU6050_ACCEL_RESET MPU6050_D1 503#define MPU6050_GYRO_RESET MPU6050_D2 504 505// MOT_DETECT_CTRL Register 506// These are the names for the bits. 507// Use these only with the bit() macro. 508#define MPU6050_MOT_COUNT0 MPU6050_D0 509#define MPU6050_MOT_COUNT1 MPU6050_D1 510#define MPU6050_FF_COUNT0 MPU6050_D2 511#define MPU6050_FF_COUNT1 MPU6050_D3 512#define MPU6050_ACCEL_ON_DELAY0 MPU6050_D4 513#define MPU6050_ACCEL_ON_DELAY1 MPU6050_D5 514 515// Combined definitions for the MOT_COUNT 516#define MPU6050_MOT_COUNT_0 (0) 517#define MPU6050_MOT_COUNT_1 (bit(MPU6050_MOT_COUNT0)) 518#define MPU6050_MOT_COUNT_2 (bit(MPU6050_MOT_COUNT1)) 519#define MPU6050_MOT_COUNT_3 (bit(MPU6050_MOT_COUNT1)|bit(MPU6050_MOT_COUNT0)) 520 521// Alternative names for the combined definitions 522#define MPU6050_MOT_COUNT_RESET MPU6050_MOT_COUNT_0 523 524// Combined definitions for the FF_COUNT 525#define MPU6050_FF_COUNT_0 (0) 526#define MPU6050_FF_COUNT_1 (bit(MPU6050_FF_COUNT0)) 527#define MPU6050_FF_COUNT_2 (bit(MPU6050_FF_COUNT1)) 528#define MPU6050_FF_COUNT_3 (bit(MPU6050_FF_COUNT1)|bit(MPU6050_FF_COUNT0)) 529 530// Alternative names for the combined definitions 531#define MPU6050_FF_COUNT_RESET MPU6050_FF_COUNT_0 532 533// Combined definitions for the ACCEL_ON_DELAY 534#define MPU6050_ACCEL_ON_DELAY_0 (0) 535#define MPU6050_ACCEL_ON_DELAY_1 (bit(MPU6050_ACCEL_ON_DELAY0)) 536#define MPU6050_ACCEL_ON_DELAY_2 (bit(MPU6050_ACCEL_ON_DELAY1)) 537#define MPU6050_ACCEL_ON_DELAY_3 (bit(MPU6050_ACCEL_ON_DELAY1)|bit(MPU6050_ACCEL_ON_DELAY0)) 538 539// Alternative names for the ACCEL_ON_DELAY 540#define MPU6050_ACCEL_ON_DELAY_0MS MPU6050_ACCEL_ON_DELAY_0 541#define MPU6050_ACCEL_ON_DELAY_1MS MPU6050_ACCEL_ON_DELAY_1 542#define MPU6050_ACCEL_ON_DELAY_2MS MPU6050_ACCEL_ON_DELAY_2 543#define MPU6050_ACCEL_ON_DELAY_3MS MPU6050_ACCEL_ON_DELAY_3 544 545// USER_CTRL Register 546// These are the names for the bits. 547// Use these only with the bit() macro. 548#define MPU6050_SIG_COND_RESET MPU6050_D0 549#define MPU6050_I2C_MST_RESET MPU6050_D1 550#define MPU6050_FIFO_RESET MPU6050_D2 551#define MPU6050_I2C_IF_DIS MPU6050_D4 // must be 0 for MPU-6050 552#define MPU6050_I2C_MST_EN MPU6050_D5 553#define MPU6050_FIFO_EN MPU6050_D6 554 555// PWR_MGMT_1 Register 556// These are the names for the bits. 557// Use these only with the bit() macro. 558#define MPU6050_CLKSEL0 MPU6050_D0 559#define MPU6050_CLKSEL1 MPU6050_D1 560#define MPU6050_CLKSEL2 MPU6050_D2 561#define MPU6050_TEMP_DIS MPU6050_D3 // 1: disable temperature sensor 562#define MPU6050_CYCLE MPU6050_D5 // 1: sample and sleep 563#define MPU6050_SLEEP MPU6050_D6 // 1: sleep mode 564#define MPU6050_DEVICE_RESET MPU6050_D7 // 1: reset to default values 565 566// Combined definitions for the CLKSEL 567#define MPU6050_CLKSEL_0 (0) 568#define MPU6050_CLKSEL_1 (bit(MPU6050_CLKSEL0)) 569#define MPU6050_CLKSEL_2 (bit(MPU6050_CLKSEL1)) 570#define MPU6050_CLKSEL_3 (bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0)) 571#define MPU6050_CLKSEL_4 (bit(MPU6050_CLKSEL2)) 572#define MPU6050_CLKSEL_5 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL0)) 573#define MPU6050_CLKSEL_6 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1)) 574#define MPU6050_CLKSEL_7 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0)) 575 576// Alternative names for the combined definitions 577#define MPU6050_CLKSEL_INTERNAL MPU6050_CLKSEL_0 578#define MPU6050_CLKSEL_X MPU6050_CLKSEL_1 579#define MPU6050_CLKSEL_Y MPU6050_CLKSEL_2 580#define MPU6050_CLKSEL_Z MPU6050_CLKSEL_3 581#define MPU6050_CLKSEL_EXT_32KHZ MPU6050_CLKSEL_4 582#define MPU6050_CLKSEL_EXT_19_2MHZ MPU6050_CLKSEL_5 583#define MPU6050_CLKSEL_RESERVED MPU6050_CLKSEL_6 584#define MPU6050_CLKSEL_STOP MPU6050_CLKSEL_7 585 586// PWR_MGMT_2 Register 587// These are the names for the bits. 588// Use these only with the bit() macro. 589#define MPU6050_STBY_ZG MPU6050_D0 590#define MPU6050_STBY_YG MPU6050_D1 591#define MPU6050_STBY_XG MPU6050_D2 592#define MPU6050_STBY_ZA MPU6050_D3 593#define MPU6050_STBY_YA MPU6050_D4 594#define MPU6050_STBY_XA MPU6050_D5 595#define MPU6050_LP_WAKE_CTRL0 MPU6050_D6 596#define MPU6050_LP_WAKE_CTRL1 MPU6050_D7 597 598// Combined definitions for the LP_WAKE_CTRL 599#define MPU6050_LP_WAKE_CTRL_0 (0) 600#define MPU6050_LP_WAKE_CTRL_1 (bit(MPU6050_LP_WAKE_CTRL0)) 601#define MPU6050_LP_WAKE_CTRL_2 (bit(MPU6050_LP_WAKE_CTRL1)) 602#define MPU6050_LP_WAKE_CTRL_3 (bit(MPU6050_LP_WAKE_CTRL1)|bit(MPU6050_LP_WAKE_CTRL0)) 603 604// Alternative names for the combined definitions 605// The names uses the Wake-up Frequency. 606#define MPU6050_LP_WAKE_1_25HZ MPU6050_LP_WAKE_CTRL_0 607#define MPU6050_LP_WAKE_2_5HZ MPU6050_LP_WAKE_CTRL_1 608#define MPU6050_LP_WAKE_5HZ MPU6050_LP_WAKE_CTRL_2 609#define MPU6050_LP_WAKE_10HZ MPU6050_LP_WAKE_CTRL_3 610 611 612// Default I2C address for the MPU-6050 is 0x68. 613// But only if the AD0 pin is low. 614// Some sensor boards have AD0 high, and the 615// I2C address thus becomes 0x69. 616#define MPU6050_I2C_ADDRESS 0x68 617 618 619// Declaring an union for the registers and the axis values. 620// The byte order does not match the byte order of 621// the compiler and AVR chip. 622// The AVR chip (on the Arduino board) has the Low Byte 623// at the lower address. 624// But the MPU-6050 has a different order: High Byte at 625// lower address, so that has to be corrected. 626// The register part "reg" is only used internally, 627// and are swapped in code. 628typedef union accel_t_gyro_union 629{ 630 struct 631 { 632 uint8_t x_accel_h; 633 uint8_t x_accel_l; 634 uint8_t y_accel_h; 635 uint8_t y_accel_l; 636 uint8_t z_accel_h; 637 uint8_t z_accel_l; 638 uint8_t t_h; 639 uint8_t t_l; 640 uint8_t x_gyro_h; 641 uint8_t x_gyro_l; 642 uint8_t y_gyro_h; 643 uint8_t y_gyro_l; 644 uint8_t z_gyro_h; 645 uint8_t z_gyro_l; 646 } reg; 647 struct 648 { 649 int x_accel; 650 int y_accel; 651 int z_accel; 652 int temperature; 653 int x_gyro; 654 int y_gyro; 655 int z_gyro; 656 } value; 657}; 658 659// Use the following global variables and access functions to help store the overall 660// rotation angle of the sensor 661unsigned long last_read_time; 662float last_x_angle; // These are the filtered angles 663float last_y_angle; 664float last_z_angle; 665float last_gyro_x_angle; // Store the gyro angles to compare drift 666float last_gyro_y_angle; 667float last_gyro_z_angle; 668float last_x_kalangle; //Kalman angle 669float last_y_kalangle; 670float last_z_kalangle; 671 672void set_last_read_angle_data(unsigned long time, float x, float y, float z, float x_gyro, float y_gyro, float z_gyro, float kx, float ky, float kz) { 673 last_read_time = time; 674 last_x_angle = x; 675 last_y_angle = y; 676 last_z_angle = z; 677 last_gyro_x_angle = x_gyro; 678 last_gyro_y_angle = y_gyro; 679 last_gyro_z_angle = z_gyro; 680 last_x_kalangle = kx; 681 last_y_kalangle = ky; 682 last_z_kalangle = kz; 683} 684 685inline unsigned long get_last_time() {return last_read_time;} 686inline float get_last_x_angle() {return last_x_angle;} 687inline float get_last_y_angle() {return last_y_angle;} 688inline float get_last_z_angle() {return last_z_angle;} 689inline float get_last_gyro_x_angle() {return last_gyro_x_angle;} 690inline float get_last_gyro_y_angle() {return last_gyro_y_angle;} 691inline float get_last_gyro_z_angle() {return last_gyro_z_angle;} 692inline float get_last_x_kalangle() {return last_x_kalangle;} 693inline float get_last_y_kalangle() {return last_y_kalangle;} 694inline float get_last_z_kalangle() {return last_z_kalangle;} 695 696// Use the following global variables and access functions 697// to calibrate the acceleration sensor 698float base_x_accel; 699float base_y_accel; 700float base_z_accel; 701 702float base_x_gyro; 703float base_y_gyro; 704float base_z_gyro; 705 706 707int read_gyro_accel_vals(uint8_t* accel_t_gyro_ptr) { 708 // Read the raw values. 709 // Read 14 bytes at once, 710 // containing acceleration, temperature and gyro. 711 // With the default settings of the MPU-6050, 712 // there is no filter enabled, and the values 713 // are not very stable. Returns the error value 714 715 accel_t_gyro_union* accel_t_gyro = (accel_t_gyro_union *) accel_t_gyro_ptr; 716 717 int error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) accel_t_gyro, sizeof(*accel_t_gyro)); 718 719 // Swap all high and low bytes. 720 // After this, the registers values are swapped, 721 // so the structure name like x_accel_l does no 722 // longer contain the lower byte. 723 uint8_t swap; 724 #define SWAP(x,y) swap = x; x = y; y = swap 725 726 SWAP ((*accel_t_gyro).reg.x_accel_h, (*accel_t_gyro).reg.x_accel_l); 727 SWAP ((*accel_t_gyro).reg.y_accel_h, (*accel_t_gyro).reg.y_accel_l); 728 SWAP ((*accel_t_gyro).reg.z_accel_h, (*accel_t_gyro).reg.z_accel_l); 729 SWAP ((*accel_t_gyro).reg.t_h, (*accel_t_gyro).reg.t_l); 730 SWAP ((*accel_t_gyro).reg.x_gyro_h, (*accel_t_gyro).reg.x_gyro_l); 731 SWAP ((*accel_t_gyro).reg.y_gyro_h, (*accel_t_gyro).reg.y_gyro_l); 732 SWAP ((*accel_t_gyro).reg.z_gyro_h, (*accel_t_gyro).reg.z_gyro_l); 733 734 return error; 735} 736 737// The sensor should be motionless on a horizontal surface 738// while calibration is happening 739void calibrate_sensors() { 740 int num_readings = 10; 741 float x_accel = 0; 742 float y_accel = 0; 743 float z_accel = 0; 744 float x_gyro = 0; 745 float y_gyro = 0; 746 float z_gyro = 0; 747 accel_t_gyro_union accel_t_gyro; 748 749 //Serial.println("Starting Calibration"); 750 751 // Discard the first set of values read from the IMU 752 read_gyro_accel_vals((uint8_t *) &accel_t_gyro); 753 754 // Read and average the raw values from the IMU 755 for (int i = 0; i < num_readings; i++) { 756 read_gyro_accel_vals((uint8_t *) &accel_t_gyro); 757 x_accel += accel_t_gyro.value.x_accel; 758 y_accel += accel_t_gyro.value.y_accel; 759 z_accel += accel_t_gyro.value.z_accel; 760 x_gyro += accel_t_gyro.value.x_gyro; 761 y_gyro += accel_t_gyro.value.y_gyro; 762 z_gyro += accel_t_gyro.value.z_gyro; 763 delay(100); 764 } 765 x_accel /= num_readings; 766 y_accel /= num_readings; 767 z_accel /= num_readings; 768 x_gyro /= num_readings; 769 y_gyro /= num_readings; 770 z_gyro /= num_readings; 771 772 // Store the raw calibration values globally 773 base_x_accel = x_accel; 774 base_y_accel = y_accel; 775 base_z_accel = z_accel; 776 base_x_gyro = x_gyro; 777 base_y_gyro = y_gyro; 778 base_z_gyro = z_gyro; 779 780 //Serial.println("Finishing Calibration"); 781} 782 783 784/************************ 785* KALMAN - Filter setup * 786*************************/ 787class Kalman { 788public: 789 Kalman() { 790 /* We will set the varibles like so, these can also be tuned by the user */ 791 Q_angle = 0.001; 792 Q_bias = 0.003; 793 R_measure = 0.03; 794 795 bias = 0; // Reset bias 796 P[0][0] = 0; // Since we assume tha the bias is 0 and we know the starting angle (use setAngle), the error covariance matrix is set like so - see: http://en.wikipedia.org/wiki/Kalman_filter#Example_application.2C_technical 797 P[0][1] = 0; 798 P[1][0] = 0; 799 P[1][1] = 0; 800 }; 801 // The angle should be in degrees and the rate should be in degrees per second and the delta time in seconds 802 float getAngle(float newAngle, float newRate, float dt) { 803 // KasBot V2 - Kalman filter module - http://www.x-firm.com/?page_id=145 804 // Modified by Kristian Lauszus 805 // See my blog post for more information: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it 806 807 // Discrete Kalman filter time update equations - Time Update ("Predict") 808 // Update xhat - Project the state ahead 809 /* Step 1 */ 810 rate = newRate - bias; 811 angle += dt * rate; 812 813 // Update estimation error covariance - Project the error covariance ahead 814 /* Step 2 */ 815 P[0][0] += dt * (dt*P[1][1] - P[0][1] - P[1][0] + Q_angle); 816 P[0][1] -= dt * P[1][1]; 817 P[1][0] -= dt * P[1][1]; 818 P[1][1] += Q_bias * dt; 819 820 // Discrete Kalman filter measurement update equations - Measurement Update ("Correct") 821 // Calculate Kalman gain - Compute the Kalman gain 822 /* Step 4 */ 823 S = P[0][0] + R_measure; 824 /* Step 5 */ 825 K[0] = P[0][0] / S; 826 K[1] = P[1][0] / S; 827 828 // Calculate angle and bias - Update estimate with measurement zk (newAngle) 829 /* Step 3 */ 830 y = newAngle - angle; 831 /* Step 6 */ 832 angle += K[0] * y; 833 bias += K[1] * y; 834 835 // Calculate estimation error covariance - Update the error covariance 836 /* Step 7 */ 837 P[0][0] -= K[0] * P[0][0]; 838 P[0][1] -= K[0] * P[0][1]; 839 P[1][0] -= K[1] * P[0][0]; 840 P[1][1] -= K[1] * P[0][1]; 841 842 return angle; 843 }; 844 void setAngle(double newAngle) { angle = newAngle; }; // Used to set angle, this should be set as the starting angle 845 double getRate() { return rate; }; // Return the unbiased rate 846 847 /* These are used to tune the Kalman filter */ 848 void setQangle(double newQ_angle) { Q_angle = newQ_angle; }; 849 void setQbias(double newQ_bias) { Q_bias = newQ_bias; }; 850 void setRmeasure(double newR_measure) { R_measure = newR_measure; }; 851 852 double getQangle() { return Q_angle; }; 853 double getQbias() { return Q_bias; }; 854 double getRmeasure() { return R_measure; }; 855 856private: 857 /* Kalman filter variables */ 858 double Q_angle; // Process noise variance for the accelerometer 859 double Q_bias; // Process noise variance for the gyro bias 860 double R_measure; // Measurement noise variance - this is actually the variance of the measurement noise 861 862 double angle; // The angle calculated by the Kalman filter - part of the 2x1 state matrix 863 double bias; // The gyro bias calculated by the Kalman filter - part of the 2x1 state matrix 864 double rate; // Unbiased rate calculated from the rate and the calculated bias - you have to call getAngle to update the rate 865 866 double P[2][2]; // Error covariance matrix - This is a 2x2 matrix 867 double K[2]; // Kalman gain - This is a 2x1 matrix 868 double y; // Angle difference - 1x1 matrix 869 double S; // Estimate error - 1x1 matrix 870}; 871Kalman kalmanX; // Create the Kalman instances 872Kalman kalmanY; 873 874 875 876/******** 877* SETUP * 878*********/ 879 880void setup() 881{ 882 int error; 883 uint8_t c; 884 accel_t_gyro_union accel_t_gyro; 885 886 887 Serial.begin(19200); 888 889 // Initialize the 'Wire' class for the I2C-bus. 890 Wire.begin(); 891 892 893 // default at power-up: 894 // Gyro at 250 degrees second 895 // Acceleration at 2g 896 // Clock source at internal 8MHz 897 // The device is in sleep mode. 898 // 899 900 error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1); 901 902 903 // According to the datasheet, the 'sleep' bit 904 // should read a '1'. But I read a '0'. 905 // That bit has to be cleared, since the sensor 906 // is in sleep mode at power-up. Even if the 907 // bit reads '0'. 908 error = MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1); 909 910 // Clear the 'sleep' bit to start the sensor. 911 MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0); 912 913 //Initialize the angles 914 calibrate_sensors(); 915 set_last_read_angle_data(millis(), 0, 0, 0, 0, 0, 0, 0, 0, 0); 916 917 918 // Get raw acceleration values 919 //float G_CONVERT = 16384; 920 float accel_x = accel_t_gyro.value.x_accel; 921 float accel_y = accel_t_gyro.value.y_accel; 922 float accel_z = accel_t_gyro.value.z_accel; 923 924 // Get angle values from accelerometer 925 float RADIANS_TO_DEGREES = 180/3.14159; 926// float accel_vector_length = sqrt(pow(accel_x,2) + pow(accel_y,2) + pow(accel_z,2)); 927 float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 928 float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 929 930 float accel_angle_z = 0; 931 932 kalmanX.setAngle(accel_angle_x); // Set starting angle 933 kalmanY.setAngle(accel_angle_y); 934 935} 936 937 938 939/************ 940* Main loop * 941*************/ 942void loop() 943{ 944 int error; 945 double dT; 946 accel_t_gyro_union accel_t_gyro; 947 948 float kalAngleX, kalAngleY, kalAngleZ; // Calculate the angle using a Kalman filter 949 950 // Read the raw values. 951 error = read_gyro_accel_vals((uint8_t*) &accel_t_gyro); 952 953 // Get the time of reading for rotation computations 954 unsigned long t_now = millis(); 955 956 957 // Convert gyro values to degrees/sec 958 float FS_SEL = 131; 959 960 float gyro_x = (accel_t_gyro.value.x_gyro - base_x_gyro)/FS_SEL; 961 float gyro_y = (accel_t_gyro.value.y_gyro - base_y_gyro)/FS_SEL; 962 float gyro_z = (accel_t_gyro.value.z_gyro - base_z_gyro)/FS_SEL; 963 964 965 // Get raw acceleration values 966 //float G_CONVERT = 16384; 967 float accel_x = accel_t_gyro.value.x_accel; 968 float accel_y = accel_t_gyro.value.y_accel; 969 float accel_z = accel_t_gyro.value.z_accel; 970 971 // Get angle values from accelerometer 972 float RADIANS_TO_DEGREES = 180/3.14159; 973// float accel_vector_length = sqrt(pow(accel_x,2) + pow(accel_y,2) + pow(accel_z,2)); 974 float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 975 float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 976 977 float accel_angle_z = 0; 978 979 // Compute the (filtered) gyro angles 980 float dt =(t_now - get_last_time())/1000.0; 981 float gyro_angle_x = gyro_x*dt + get_last_x_angle(); 982 float gyro_angle_y = gyro_y*dt + get_last_y_angle(); 983 float gyro_angle_z = gyro_z*dt + get_last_z_angle(); 984 985 // Compute the drifting gyro angles 986 float unfiltered_gyro_angle_x = gyro_x*dt + get_last_gyro_x_angle(); 987 float unfiltered_gyro_angle_y = gyro_y*dt + get_last_gyro_y_angle(); 988 float unfiltered_gyro_angle_z = gyro_z*dt + get_last_gyro_z_angle(); 989 990 // Apply the complementary filter to figure out the change in angle - choice of alpha is 991 // estimated now. Alpha depends on the sampling rate... 992 float alpha = 0.96; 993 float angle_x = alpha*gyro_angle_x + (1.0 - alpha)*accel_angle_x; 994 float angle_y = alpha*gyro_angle_y + (1.0 - alpha)*accel_angle_y; 995 float angle_z = gyro_angle_z; //Accelerometer doesn't give z-angle 996 997 998 //KALMAN filter 999 kalAngleX = kalmanX.getAngle(accel_angle_x, gyro_x, dt); 1000 //delay(5); 1001 kalAngleY = kalmanY.getAngle(accel_angle_y, gyro_y, dt); 1002 kalAngleZ = gyro_angle_z; 1003 1004 1005 // Update the saved data with the latest values 1006 set_last_read_angle_data(t_now, angle_x, angle_y, angle_z, unfiltered_gyro_angle_x, unfiltered_gyro_angle_y, unfiltered_gyro_angle_z, kalAngleX, kalAngleY, kalAngleZ); 1007 1008 //Note added: 10/08/13 pad() creates padding that is required to ensure 128Bytes are sent. May not be needed as new version of LV code maybe able to handle 1009 1010 //Serial.print("START"); 1011 // Send the data to the serial port 1012 Serial.print(F("DEL:")); //Delta T 1013 Serial.print(dt, DEC); 1014 1015 Serial.print(F("#ACC:")); //Accelerometer angle 1016 pad(accel_angle_x); 1017 //Serial.print(accel_angle_x, 2); 1018 Serial.print(F(",")); 1019 pad(accel_angle_y); 1020 //Serial.print(accel_angle_y, 2); 1021 Serial.print(F(",")); 1022 pad(accel_angle_z); 1023 //Serial.print(accel_angle_z, 2); 1024 1025 Serial.print(F("#GYR:")); 1026 pad(unfiltered_gyro_angle_x); 1027 //Serial.print(unfiltered_gyro_angle_x, 2); //Gyroscope angle 1028 Serial.print(F(",")); 1029 pad(unfiltered_gyro_angle_y); 1030 //Serial.print(unfiltered_gyro_angle_y, 2); 1031 Serial.print(F(",")); 1032 pad(unfiltered_gyro_angle_z); 1033 //Serial.print(unfiltered_gyro_angle_z, 2); 1034 1035 Serial.print(F("#FIL:")); //Filtered angle 1036 pad(angle_x); 1037 //Serial.print(angle_x, 2); 1038 Serial.print(F(",")); 1039 pad(angle_y); 1040 //Serial.print(angle_y, 2); 1041 Serial.print(F(",")); 1042 pad(angle_z); 1043 //Serial.print(angle_z, 2); 1044 Serial.print(F(",")); 1045 1046 Serial.print(F("#KAL:")); //Kalman Filtered angle 1047 pad(kalAngleX); 1048 //Serial.print(kalAngleX, 2); 1049 Serial.print(F(",")); 1050 pad (kalAngleY); 1051 //Serial.print(kalAngleY, 2); 1052 Serial.print(F(",")); 1053 pad(kalAngleZ); 1054 //Serial.print(kalAngleZ, 2); 1055 //Serial.print("END"); 1056 Serial.print("\ 1057"); 1058 //Serial.println(F("")); 1059 Serial.flush(); 1060 // Delay so we don't swamp the serial port 1061 delay(5); //so not to swamp the serial port 1062} 1063 1064 1065// -------------------------------------------------------- 1066// MPU6050_read 1067// 1068// This is a common function to read multiple bytes 1069// from an I2C device. 1070// 1071// It uses the boolean parameter for Wire.endTransMission() 1072// to be able to hold or release the I2C-bus. 1073// This is implemented in Arduino 1.0.1. 1074// 1075// Only this function is used to read. 1076// There is no function for a single byte. 1077// 1078int MPU6050_read(int start, uint8_t *buffer, int size) 1079{ 1080 int i, n, error; 1081 1082 Wire.beginTransmission(MPU6050_I2C_ADDRESS); 1083 n = Wire.write(start); 1084 if (n != 1) 1085 return (-10); 1086 1087 n = Wire.endTransmission(false); // hold the I2C-bus 1088 if (n != 0) 1089 return (n); 1090 1091 // Third parameter is true: relase I2C-bus after data is read. 1092 Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true); 1093 i = 0; 1094 while(Wire.available() && i<size) 1095 { 1096 buffer[i++]=Wire.read(); 1097 } 1098 if ( i != size) 1099 return (-11); 1100 1101 return (0); // return : no error 1102} 1103 1104 1105// -------------------------------------------------------- 1106// MPU6050_write 1107// 1108// This is a common function to write multiple bytes to an I2C device. 1109// 1110// If only a single register is written, 1111// use the function MPU_6050_write_reg(). 1112// 1113// Parameters: 1114// start : Start address, use a define for the register 1115// pData : A pointer to the data to write. 1116// size : The number of bytes to write. 1117// 1118// If only a single register is written, a pointer 1119// to the data has to be used, and the size is 1120// a single byte: 1121// int data = 0; // the data to write 1122// MPU6050_write (MPU6050_PWR_MGMT_1, &c, 1); 1123// 1124int MPU6050_write(int start, const uint8_t *pData, int size) 1125{ 1126 int n, error; 1127 1128 Wire.beginTransmission(MPU6050_I2C_ADDRESS); 1129 n = Wire.write(start); // write the start address 1130 if (n != 1) 1131 return (-20); 1132 1133 n = Wire.write(pData, size); // write data bytes 1134 if (n != size) 1135 return (-21); 1136 1137 error = Wire.endTransmission(true); // release the I2C-bus 1138 if (error != 0) 1139 return (error); 1140 1141 return (0); // return : no error 1142} 1143 1144// -------------------------------------------------------- 1145// MPU6050_write_reg 1146// 1147// An extra function to write a single register. 1148// It is just a wrapper around the MPU_6050_write() 1149// function, and it is only a convenient function 1150// to make it easier to write a single register. 1151// 1152int MPU6050_write_reg(int reg, uint8_t data) 1153{ 1154 int error; 1155 1156 error = MPU6050_write(reg, &data, 1); 1157 1158 return (error); 1159} 1160 1161//This function pads the printed value to take up 1162//7 characters Example: **20.16 1163void pad(float PadVal){ 1164 1165 //Positve Value 1166 if (PadVal > 0){ //For positive value 1167 if(PadVal < 10){ //For positive value less than 10 1168 Serial.print("***"); //0-9 ***0-9.00 1169 } 1170 else if (PadVal < 100){ //values less than 100 1171 Serial.print("**"); //10-99 **10-99.00 1172 } 1173 1174 } 1175 else if(PadVal < 0){ //for negative values 1176 if(PadVal > -10){ //for negative value greater than -10 1177 Serial.print("**"); //-9 - 0 **-1 - -9.00 1178 } 1179 else if (PadVal > -100){ //for negative values lesss than -99 1180 Serial.print("*"); //*-99.00 1181 } 1182 } 1183 1184 Serial.print(PadVal, 2); //print the padded value 1185}
Gyro Code
arduino
Code for IMU 6050 gyro sensor.
1 2// MPU-6050 Accelerometer + Gyro + Arduino Uno 3// ----------------------------- 4// 5// 6// June 2012 7// Open Source / Public Domain 8// 9// Using Arduino 1.0.1 10// It will not work with an older version, 11// since Wire.endTransmission() uses a parameter 12// to hold or release the I2C bus. 13// 14// Documentation: 15// - The InvenSense documents: 16// - "MPU-6000 and MPU-6050 Product Specification", 17// PS-MPU-6000A.pdf 18// - "MPU-6000 and MPU-6050 Register Map and Descriptions", 19// RM-MPU-6000A.pdf or RS-MPU-6000A.pdf 20// - "MPU-6000/MPU-6050 9-Axis Evaluation Board User Guide" 21// AN-MPU-6000EVB.pdf 22// 23// The accuracy is 16-bits. 24// 25// Temperature sensor from -40 to +85 degrees Celsius 26// 340 per degrees, -512 at 35 degrees. 27// 28// At power-up, all registers are zero, except these two: 29// Register 0x6B (PWR_MGMT_2) = 0x40 (I read zero). 30// Register 0x75 (WHO_AM_I) = 0x68. 31// 32 33#include <Wire.h> 34 35 36// Register names according to the datasheet. 37// According to the InvenSense document 38// "MPU-6000 and MPU-6050 Register Map 39// and Descriptions Revision 3.2", there are no registers 40// at 0x02 ... 0x18, but according other information 41// the registers in that unknown area are for gain 42// and offsets. 43// 44#define MPU6050_AUX_VDDIO 0x01 // R/W 45#define MPU6050_SMPLRT_DIV 0x19 // R/W 46#define MPU6050_CONFIG 0x1A // R/W 47#define MPU6050_GYRO_CONFIG 0x1B // R/W 48#define MPU6050_ACCEL_CONFIG 0x1C // R/W 49#define MPU6050_FF_THR 0x1D // R/W 50#define MPU6050_FF_DUR 0x1E // R/W 51#define MPU6050_MOT_THR 0x1F // R/W 52#define MPU6050_MOT_DUR 0x20 // R/W 53#define MPU6050_ZRMOT_THR 0x21 // R/W 54#define MPU6050_ZRMOT_DUR 0x22 // R/W 55#define MPU6050_FIFO_EN 0x23 // R/W 56#define MPU6050_I2C_MST_CTRL 0x24 // R/W 57#define MPU6050_I2C_SLV0_ADDR 0x25 // R/W 58#define MPU6050_I2C_SLV0_REG 0x26 // R/W 59#define MPU6050_I2C_SLV0_CTRL 0x27 // R/W 60#define MPU6050_I2C_SLV1_ADDR 0x28 // R/W 61#define MPU6050_I2C_SLV1_REG 0x29 // R/W 62#define MPU6050_I2C_SLV1_CTRL 0x2A // R/W 63#define MPU6050_I2C_SLV2_ADDR 0x2B // R/W 64#define MPU6050_I2C_SLV2_REG 0x2C // R/W 65#define MPU6050_I2C_SLV2_CTRL 0x2D // R/W 66#define MPU6050_I2C_SLV3_ADDR 0x2E // R/W 67#define MPU6050_I2C_SLV3_REG 0x2F // R/W 68#define MPU6050_I2C_SLV3_CTRL 0x30 // R/W 69#define MPU6050_I2C_SLV4_ADDR 0x31 // R/W 70#define MPU6050_I2C_SLV4_REG 0x32 // R/W 71#define MPU6050_I2C_SLV4_DO 0x33 // R/W 72#define MPU6050_I2C_SLV4_CTRL 0x34 // R/W 73#define MPU6050_I2C_SLV4_DI 0x35 // R 74#define MPU6050_I2C_MST_STATUS 0x36 // R 75#define MPU6050_INT_PIN_CFG 0x37 // R/W 76#define MPU6050_INT_ENABLE 0x38 // R/W 77#define MPU6050_INT_STATUS 0x3A // R 78#define MPU6050_ACCEL_XOUT_H 0x3B // R 79#define MPU6050_ACCEL_XOUT_L 0x3C // R 80#define MPU6050_ACCEL_YOUT_H 0x3D // R 81#define MPU6050_ACCEL_YOUT_L 0x3E // R 82#define MPU6050_ACCEL_ZOUT_H 0x3F // R 83#define MPU6050_ACCEL_ZOUT_L 0x40 // R 84#define MPU6050_TEMP_OUT_H 0x41 // R 85#define MPU6050_TEMP_OUT_L 0x42 // R 86#define MPU6050_GYRO_XOUT_H 0x43 // R 87#define MPU6050_GYRO_XOUT_L 0x44 // R 88#define MPU6050_GYRO_YOUT_H 0x45 // R 89#define MPU6050_GYRO_YOUT_L 0x46 // R 90#define MPU6050_GYRO_ZOUT_H 0x47 // R 91#define MPU6050_GYRO_ZOUT_L 0x48 // R 92#define MPU6050_EXT_SENS_DATA_00 0x49 // R 93#define MPU6050_EXT_SENS_DATA_01 0x4A // R 94#define MPU6050_EXT_SENS_DATA_02 0x4B // R 95#define MPU6050_EXT_SENS_DATA_03 0x4C // R 96#define MPU6050_EXT_SENS_DATA_04 0x4D // R 97#define MPU6050_EXT_SENS_DATA_05 0x4E // R 98#define MPU6050_EXT_SENS_DATA_06 0x4F // R 99#define MPU6050_EXT_SENS_DATA_07 0x50 // R 100#define MPU6050_EXT_SENS_DATA_08 0x51 // R 101#define MPU6050_EXT_SENS_DATA_09 0x52 // R 102#define MPU6050_EXT_SENS_DATA_10 0x53 // R 103#define MPU6050_EXT_SENS_DATA_11 0x54 // R 104#define MPU6050_EXT_SENS_DATA_12 0x55 // R 105#define MPU6050_EXT_SENS_DATA_13 0x56 // R 106#define MPU6050_EXT_SENS_DATA_14 0x57 // R 107#define MPU6050_EXT_SENS_DATA_15 0x58 // R 108#define MPU6050_EXT_SENS_DATA_16 0x59 // R 109#define MPU6050_EXT_SENS_DATA_17 0x5A // R 110#define MPU6050_EXT_SENS_DATA_18 0x5B // R 111#define MPU6050_EXT_SENS_DATA_19 0x5C // R 112#define MPU6050_EXT_SENS_DATA_20 0x5D // R 113#define MPU6050_EXT_SENS_DATA_21 0x5E // R 114#define MPU6050_EXT_SENS_DATA_22 0x5F // R 115#define MPU6050_EXT_SENS_DATA_23 0x60 // R 116#define MPU6050_MOT_DETECT_STATUS 0x61 // R 117#define MPU6050_I2C_SLV0_DO 0x63 // R/W 118#define MPU6050_I2C_SLV1_DO 0x64 // R/W 119#define MPU6050_I2C_SLV2_DO 0x65 // R/W 120#define MPU6050_I2C_SLV3_DO 0x66 // R/W 121#define MPU6050_I2C_MST_DELAY_CTRL 0x67 // R/W 122#define MPU6050_SIGNAL_PATH_RESET 0x68 // R/W 123#define MPU6050_MOT_DETECT_CTRL 0x69 // R/W 124#define MPU6050_USER_CTRL 0x6A // R/W 125#define MPU6050_PWR_MGMT_1 0x6B // R/W 126#define MPU6050_PWR_MGMT_2 0x6C // R/W 127#define MPU6050_FIFO_COUNTH 0x72 // R/W 128#define MPU6050_FIFO_COUNTL 0x73 // R/W 129#define MPU6050_FIFO_R_W 0x74 // R/W 130#define MPU6050_WHO_AM_I 0x75 // R 131 132 133// Defines for the bits, to be able to change 134// between bit number and binary definition. 135// By using the bit number, programming the sensor 136// is like programming the AVR microcontroller. 137// But instead of using "(1<<X)", or "_BV(X)", 138// the Arduino "bit(X)" is used. 139#define MPU6050_D0 0 140#define MPU6050_D1 1 141#define MPU6050_D2 2 142#define MPU6050_D3 3 143#define MPU6050_D4 4 144#define MPU6050_D5 5 145#define MPU6050_D6 6 146#define MPU6050_D7 7 147 148// AUX_VDDIO Register 149#define MPU6050_AUX_VDDIO MPU6050_D7 // I2C high: 1=VDD, 0=VLOGIC 150 151// CONFIG Register 152// DLPF is Digital Low Pass Filter for both gyro and accelerometers. 153// These are the names for the bits. 154// Use these only with the bit() macro. 155#define MPU6050_DLPF_CFG0 MPU6050_D0 156#define MPU6050_DLPF_CFG1 MPU6050_D1 157#define MPU6050_DLPF_CFG2 MPU6050_D2 158#define MPU6050_EXT_SYNC_SET0 MPU6050_D3 159#define MPU6050_EXT_SYNC_SET1 MPU6050_D4 160#define MPU6050_EXT_SYNC_SET2 MPU6050_D5 161 162// Combined definitions for the EXT_SYNC_SET values 163#define MPU6050_EXT_SYNC_SET_0 (0) 164#define MPU6050_EXT_SYNC_SET_1 (bit(MPU6050_EXT_SYNC_SET0)) 165#define MPU6050_EXT_SYNC_SET_2 (bit(MPU6050_EXT_SYNC_SET1)) 166#define MPU6050_EXT_SYNC_SET_3 (bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0)) 167#define MPU6050_EXT_SYNC_SET_4 (bit(MPU6050_EXT_SYNC_SET2)) 168#define MPU6050_EXT_SYNC_SET_5 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET0)) 169#define MPU6050_EXT_SYNC_SET_6 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1)) 170#define MPU6050_EXT_SYNC_SET_7 (bit(MPU6050_EXT_SYNC_SET2)|bit(MPU6050_EXT_SYNC_SET1)|bit(MPU6050_EXT_SYNC_SET0)) 171 172// Alternative names for the combined definitions. 173#define MPU6050_EXT_SYNC_DISABLED MPU6050_EXT_SYNC_SET_0 174#define MPU6050_EXT_SYNC_TEMP_OUT_L MPU6050_EXT_SYNC_SET_1 175#define MPU6050_EXT_SYNC_GYRO_XOUT_L MPU6050_EXT_SYNC_SET_2 176#define MPU6050_EXT_SYNC_GYRO_YOUT_L MPU6050_EXT_SYNC_SET_3 177#define MPU6050_EXT_SYNC_GYRO_ZOUT_L MPU6050_EXT_SYNC_SET_4 178#define MPU6050_EXT_SYNC_ACCEL_XOUT_L MPU6050_EXT_SYNC_SET_5 179#define MPU6050_EXT_SYNC_ACCEL_YOUT_L MPU6050_EXT_SYNC_SET_6 180#define MPU6050_EXT_SYNC_ACCEL_ZOUT_L MPU6050_EXT_SYNC_SET_7 181 182// Combined definitions for the DLPF_CFG values 183#define MPU6050_DLPF_CFG_0 (0) 184#define MPU6050_DLPF_CFG_1 (bit(MPU6050_DLPF_CFG0)) 185#define MPU6050_DLPF_CFG_2 (bit(MPU6050_DLPF_CFG1)) 186#define MPU6050_DLPF_CFG_3 (bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0)) 187#define MPU6050_DLPF_CFG_4 (bit(MPU6050_DLPF_CFG2)) 188#define MPU6050_DLPF_CFG_5 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG0)) 189#define MPU6050_DLPF_CFG_6 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1)) 190#define MPU6050_DLPF_CFG_7 (bit(MPU6050_DLPF_CFG2)|bit(MPU6050_DLPF_CFG1)|bit(MPU6050_DLPF_CFG0)) 191 192// Alternative names for the combined definitions 193// This name uses the bandwidth (Hz) for the accelometer, 194// for the gyro the bandwidth is almost the same. 195#define MPU6050_DLPF_260HZ MPU6050_DLPF_CFG_0 196#define MPU6050_DLPF_184HZ MPU6050_DLPF_CFG_1 197#define MPU6050_DLPF_94HZ MPU6050_DLPF_CFG_2 198#define MPU6050_DLPF_44HZ MPU6050_DLPF_CFG_3 199#define MPU6050_DLPF_21HZ MPU6050_DLPF_CFG_4 200#define MPU6050_DLPF_10HZ MPU6050_DLPF_CFG_5 201#define MPU6050_DLPF_5HZ MPU6050_DLPF_CFG_6 202#define MPU6050_DLPF_RESERVED MPU6050_DLPF_CFG_7 203 204// GYRO_CONFIG Register 205// The XG_ST, YG_ST, ZG_ST are bits for selftest. 206// The FS_SEL sets the range for the gyro. 207// These are the names for the bits. 208// Use these only with the bit() macro. 209#define MPU6050_FS_SEL0 MPU6050_D3 210#define MPU6050_FS_SEL1 MPU6050_D4 211#define MPU6050_ZG_ST MPU6050_D5 212#define MPU6050_YG_ST MPU6050_D6 213#define MPU6050_XG_ST MPU6050_D7 214 215// Combined definitions for the FS_SEL values 216#define MPU6050_FS_SEL_0 (0) 217#define MPU6050_FS_SEL_1 (bit(MPU6050_FS_SEL0)) 218#define MPU6050_FS_SEL_2 (bit(MPU6050_FS_SEL1)) 219#define MPU6050_FS_SEL_3 (bit(MPU6050_FS_SEL1)|bit(MPU6050_FS_SEL0)) 220 221// Alternative names for the combined definitions 222// The name uses the range in degrees per second. 223#define MPU6050_FS_SEL_250 MPU6050_FS_SEL_0 224#define MPU6050_FS_SEL_500 MPU6050_FS_SEL_1 225#define MPU6050_FS_SEL_1000 MPU6050_FS_SEL_2 226#define MPU6050_FS_SEL_2000 MPU6050_FS_SEL_3 227 228// ACCEL_CONFIG Register 229// The XA_ST, YA_ST, ZA_ST are bits for selftest. 230// The AFS_SEL sets the range for the accelerometer. 231// These are the names for the bits. 232// Use these only with the bit() macro. 233#define MPU6050_ACCEL_HPF0 MPU6050_D0 234#define MPU6050_ACCEL_HPF1 MPU6050_D1 235#define MPU6050_ACCEL_HPF2 MPU6050_D2 236#define MPU6050_AFS_SEL0 MPU6050_D3 237#define MPU6050_AFS_SEL1 MPU6050_D4 238#define MPU6050_ZA_ST MPU6050_D5 239#define MPU6050_YA_ST MPU6050_D6 240#define MPU6050_XA_ST MPU6050_D7 241 242// Combined definitions for the ACCEL_HPF values 243#define MPU6050_ACCEL_HPF_0 (0) 244#define MPU6050_ACCEL_HPF_1 (bit(MPU6050_ACCEL_HPF0)) 245#define MPU6050_ACCEL_HPF_2 (bit(MPU6050_ACCEL_HPF1)) 246#define MPU6050_ACCEL_HPF_3 (bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0)) 247#define MPU6050_ACCEL_HPF_4 (bit(MPU6050_ACCEL_HPF2)) 248#define MPU6050_ACCEL_HPF_7 (bit(MPU6050_ACCEL_HPF2)|bit(MPU6050_ACCEL_HPF1)|bit(MPU6050_ACCEL_HPF0)) 249 250// Alternative names for the combined definitions 251// The name uses the Cut-off frequency. 252#define MPU6050_ACCEL_HPF_RESET MPU6050_ACCEL_HPF_0 253#define MPU6050_ACCEL_HPF_5HZ MPU6050_ACCEL_HPF_1 254#define MPU6050_ACCEL_HPF_2_5HZ MPU6050_ACCEL_HPF_2 255#define MPU6050_ACCEL_HPF_1_25HZ MPU6050_ACCEL_HPF_3 256#define MPU6050_ACCEL_HPF_0_63HZ MPU6050_ACCEL_HPF_4 257#define MPU6050_ACCEL_HPF_HOLD MPU6050_ACCEL_HPF_7 258 259// Combined definitions for the AFS_SEL values 260#define MPU6050_AFS_SEL_0 (0) 261#define MPU6050_AFS_SEL_1 (bit(MPU6050_AFS_SEL0)) 262#define MPU6050_AFS_SEL_2 (bit(MPU6050_AFS_SEL1)) 263#define MPU6050_AFS_SEL_3 (bit(MPU6050_AFS_SEL1)|bit(MPU6050_AFS_SEL0)) 264 265// Alternative names for the combined definitions 266// The name uses the full scale range for the accelerometer. 267#define MPU6050_AFS_SEL_2G MPU6050_AFS_SEL_0 268#define MPU6050_AFS_SEL_4G MPU6050_AFS_SEL_1 269#define MPU6050_AFS_SEL_8G MPU6050_AFS_SEL_2 270#define MPU6050_AFS_SEL_16G MPU6050_AFS_SEL_3 271 272// FIFO_EN Register 273// These are the names for the bits. 274// Use these only with the bit() macro. 275#define MPU6050_SLV0_FIFO_EN MPU6050_D0 276#define MPU6050_SLV1_FIFO_EN MPU6050_D1 277#define MPU6050_SLV2_FIFO_EN MPU6050_D2 278#define MPU6050_ACCEL_FIFO_EN MPU6050_D3 279#define MPU6050_ZG_FIFO_EN MPU6050_D4 280#define MPU6050_YG_FIFO_EN MPU6050_D5 281#define MPU6050_XG_FIFO_EN MPU6050_D6 282#define MPU6050_TEMP_FIFO_EN MPU6050_D7 283 284// I2C_MST_CTRL Register 285// These are the names for the bits. 286// Use these only with the bit() macro. 287#define MPU6050_I2C_MST_CLK0 MPU6050_D0 288#define MPU6050_I2C_MST_CLK1 MPU6050_D1 289#define MPU6050_I2C_MST_CLK2 MPU6050_D2 290#define MPU6050_I2C_MST_CLK3 MPU6050_D3 291#define MPU6050_I2C_MST_P_NSR MPU6050_D4 292#define MPU6050_SLV_3_FIFO_EN MPU6050_D5 293#define MPU6050_WAIT_FOR_ES MPU6050_D6 294#define MPU6050_MULT_MST_EN MPU6050_D7 295 296// Combined definitions for the I2C_MST_CLK 297#define MPU6050_I2C_MST_CLK_0 (0) 298#define MPU6050_I2C_MST_CLK_1 (bit(MPU6050_I2C_MST_CLK0)) 299#define MPU6050_I2C_MST_CLK_2 (bit(MPU6050_I2C_MST_CLK1)) 300#define MPU6050_I2C_MST_CLK_3 (bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 301#define MPU6050_I2C_MST_CLK_4 (bit(MPU6050_I2C_MST_CLK2)) 302#define MPU6050_I2C_MST_CLK_5 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0)) 303#define MPU6050_I2C_MST_CLK_6 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)) 304#define MPU6050_I2C_MST_CLK_7 (bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 305#define MPU6050_I2C_MST_CLK_8 (bit(MPU6050_I2C_MST_CLK3)) 306#define MPU6050_I2C_MST_CLK_9 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK0)) 307#define MPU6050_I2C_MST_CLK_10 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1)) 308#define MPU6050_I2C_MST_CLK_11 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 309#define MPU6050_I2C_MST_CLK_12 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)) 310#define MPU6050_I2C_MST_CLK_13 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK0)) 311#define MPU6050_I2C_MST_CLK_14 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)) 312#define MPU6050_I2C_MST_CLK_15 (bit(MPU6050_I2C_MST_CLK3)|bit(MPU6050_I2C_MST_CLK2)|bit(MPU6050_I2C_MST_CLK1)|bit(MPU6050_I2C_MST_CLK0)) 313 314// Alternative names for the combined definitions 315// The names uses I2C Master Clock Speed in kHz. 316#define MPU6050_I2C_MST_CLK_348KHZ MPU6050_I2C_MST_CLK_0 317#define MPU6050_I2C_MST_CLK_333KHZ MPU6050_I2C_MST_CLK_1 318#define MPU6050_I2C_MST_CLK_320KHZ MPU6050_I2C_MST_CLK_2 319#define MPU6050_I2C_MST_CLK_308KHZ MPU6050_I2C_MST_CLK_3 320#define MPU6050_I2C_MST_CLK_296KHZ MPU6050_I2C_MST_CLK_4 321#define MPU6050_I2C_MST_CLK_286KHZ MPU6050_I2C_MST_CLK_5 322#define MPU6050_I2C_MST_CLK_276KHZ MPU6050_I2C_MST_CLK_6 323#define MPU6050_I2C_MST_CLK_267KHZ MPU6050_I2C_MST_CLK_7 324#define MPU6050_I2C_MST_CLK_258KHZ MPU6050_I2C_MST_CLK_8 325#define MPU6050_I2C_MST_CLK_500KHZ MPU6050_I2C_MST_CLK_9 326#define MPU6050_I2C_MST_CLK_471KHZ MPU6050_I2C_MST_CLK_10 327#define MPU6050_I2C_MST_CLK_444KHZ MPU6050_I2C_MST_CLK_11 328#define MPU6050_I2C_MST_CLK_421KHZ MPU6050_I2C_MST_CLK_12 329#define MPU6050_I2C_MST_CLK_400KHZ MPU6050_I2C_MST_CLK_13 330#define MPU6050_I2C_MST_CLK_381KHZ MPU6050_I2C_MST_CLK_14 331#define MPU6050_I2C_MST_CLK_364KHZ MPU6050_I2C_MST_CLK_15 332 333// I2C_SLV0_ADDR Register 334// These are the names for the bits. 335// Use these only with the bit() macro. 336#define MPU6050_I2C_SLV0_RW MPU6050_D7 337 338// I2C_SLV0_CTRL Register 339// These are the names for the bits. 340// Use these only with the bit() macro. 341#define MPU6050_I2C_SLV0_LEN0 MPU6050_D0 342#define MPU6050_I2C_SLV0_LEN1 MPU6050_D1 343#define MPU6050_I2C_SLV0_LEN2 MPU6050_D2 344#define MPU6050_I2C_SLV0_LEN3 MPU6050_D3 345#define MPU6050_I2C_SLV0_GRP MPU6050_D4 346#define MPU6050_I2C_SLV0_REG_DIS MPU6050_D5 347#define MPU6050_I2C_SLV0_BYTE_SW MPU6050_D6 348#define MPU6050_I2C_SLV0_EN MPU6050_D7 349 350// A mask for the length 351#define MPU6050_I2C_SLV0_LEN_MASK 0x0F 352 353// I2C_SLV1_ADDR Register 354// These are the names for the bits. 355// Use these only with the bit() macro. 356#define MPU6050_I2C_SLV1_RW MPU6050_D7 357 358// I2C_SLV1_CTRL Register 359// These are the names for the bits. 360// Use these only with the bit() macro. 361#define MPU6050_I2C_SLV1_LEN0 MPU6050_D0 362#define MPU6050_I2C_SLV1_LEN1 MPU6050_D1 363#define MPU6050_I2C_SLV1_LEN2 MPU6050_D2 364#define MPU6050_I2C_SLV1_LEN3 MPU6050_D3 365#define MPU6050_I2C_SLV1_GRP MPU6050_D4 366#define MPU6050_I2C_SLV1_REG_DIS MPU6050_D5 367#define MPU6050_I2C_SLV1_BYTE_SW MPU6050_D6 368#define MPU6050_I2C_SLV1_EN MPU6050_D7 369 370// A mask for the length 371#define MPU6050_I2C_SLV1_LEN_MASK 0x0F 372 373// I2C_SLV2_ADDR Register 374// These are the names for the bits. 375// Use these only with the bit() macro. 376#define MPU6050_I2C_SLV2_RW MPU6050_D7 377 378// I2C_SLV2_CTRL Register 379// These are the names for the bits. 380// Use these only with the bit() macro. 381#define MPU6050_I2C_SLV2_LEN0 MPU6050_D0 382#define MPU6050_I2C_SLV2_LEN1 MPU6050_D1 383#define MPU6050_I2C_SLV2_LEN2 MPU6050_D2 384#define MPU6050_I2C_SLV2_LEN3 MPU6050_D3 385#define MPU6050_I2C_SLV2_GRP MPU6050_D4 386#define MPU6050_I2C_SLV2_REG_DIS MPU6050_D5 387#define MPU6050_I2C_SLV2_BYTE_SW MPU6050_D6 388#define MPU6050_I2C_SLV2_EN MPU6050_D7 389 390// A mask for the length 391#define MPU6050_I2C_SLV2_LEN_MASK 0x0F 392 393// I2C_SLV3_ADDR Register 394// These are the names for the bits. 395// Use these only with the bit() macro. 396#define MPU6050_I2C_SLV3_RW MPU6050_D7 397 398// I2C_SLV3_CTRL Register 399// These are the names for the bits. 400// Use these only with the bit() macro. 401#define MPU6050_I2C_SLV3_LEN0 MPU6050_D0 402#define MPU6050_I2C_SLV3_LEN1 MPU6050_D1 403#define MPU6050_I2C_SLV3_LEN2 MPU6050_D2 404#define MPU6050_I2C_SLV3_LEN3 MPU6050_D3 405#define MPU6050_I2C_SLV3_GRP MPU6050_D4 406#define MPU6050_I2C_SLV3_REG_DIS MPU6050_D5 407#define MPU6050_I2C_SLV3_BYTE_SW MPU6050_D6 408#define MPU6050_I2C_SLV3_EN MPU6050_D7 409 410// A mask for the length 411#define MPU6050_I2C_SLV3_LEN_MASK 0x0F 412 413// I2C_SLV4_ADDR Register 414// These are the names for the bits. 415// Use these only with the bit() macro. 416#define MPU6050_I2C_SLV4_RW MPU6050_D7 417 418// I2C_SLV4_CTRL Register 419// These are the names for the bits. 420// Use these only with the bit() macro. 421#define MPU6050_I2C_MST_DLY0 MPU6050_D0 422#define MPU6050_I2C_MST_DLY1 MPU6050_D1 423#define MPU6050_I2C_MST_DLY2 MPU6050_D2 424#define MPU6050_I2C_MST_DLY3 MPU6050_D3 425#define MPU6050_I2C_MST_DLY4 MPU6050_D4 426#define MPU6050_I2C_SLV4_REG_DIS MPU6050_D5 427#define MPU6050_I2C_SLV4_INT_EN MPU6050_D6 428#define MPU6050_I2C_SLV4_EN MPU6050_D7 429 430// A mask for the delay 431#define MPU6050_I2C_MST_DLY_MASK 0x1F 432 433// I2C_MST_STATUS Register 434// These are the names for the bits. 435// Use these only with the bit() macro. 436#define MPU6050_I2C_SLV0_NACK MPU6050_D0 437#define MPU6050_I2C_SLV1_NACK MPU6050_D1 438#define MPU6050_I2C_SLV2_NACK MPU6050_D2 439#define MPU6050_I2C_SLV3_NACK MPU6050_D3 440#define MPU6050_I2C_SLV4_NACK MPU6050_D4 441#define MPU6050_I2C_LOST_ARB MPU6050_D5 442#define MPU6050_I2C_SLV4_DONE MPU6050_D6 443#define MPU6050_PASS_THROUGH MPU6050_D7 444 445// I2C_PIN_CFG Register 446// These are the names for the bits. 447// Use these only with the bit() macro. 448#define MPU6050_CLKOUT_EN MPU6050_D0 449#define MPU6050_I2C_BYPASS_EN MPU6050_D1 450#define MPU6050_FSYNC_INT_EN MPU6050_D2 451#define MPU6050_FSYNC_INT_LEVEL MPU6050_D3 452#define MPU6050_INT_RD_CLEAR MPU6050_D4 453#define MPU6050_LATCH_INT_EN MPU6050_D5 454#define MPU6050_INT_OPEN MPU6050_D6 455#define MPU6050_INT_LEVEL MPU6050_D7 456 457// INT_ENABLE Register 458// These are the names for the bits. 459// Use these only with the bit() macro. 460#define MPU6050_DATA_RDY_EN MPU6050_D0 461#define MPU6050_I2C_MST_INT_EN MPU6050_D3 462#define MPU6050_FIFO_OFLOW_EN MPU6050_D4 463#define MPU6050_ZMOT_EN MPU6050_D5 464#define MPU6050_MOT_EN MPU6050_D6 465#define MPU6050_FF_EN MPU6050_D7 466 467// INT_STATUS Register 468// These are the names for the bits. 469// Use these only with the bit() macro. 470#define MPU6050_DATA_RDY_INT MPU6050_D0 471#define MPU6050_I2C_MST_INT MPU6050_D3 472#define MPU6050_FIFO_OFLOW_INT MPU6050_D4 473#define MPU6050_ZMOT_INT MPU6050_D5 474#define MPU6050_MOT_INT MPU6050_D6 475#define MPU6050_FF_INT MPU6050_D7 476 477// MOT_DETECT_STATUS Register 478// These are the names for the bits. 479// Use these only with the bit() macro. 480#define MPU6050_MOT_ZRMOT MPU6050_D0 481#define MPU6050_MOT_ZPOS MPU6050_D2 482#define MPU6050_MOT_ZNEG MPU6050_D3 483#define MPU6050_MOT_YPOS MPU6050_D4 484#define MPU6050_MOT_YNEG MPU6050_D5 485#define MPU6050_MOT_XPOS MPU6050_D6 486#define MPU6050_MOT_XNEG MPU6050_D7 487 488// IC2_MST_DELAY_CTRL Register 489// These are the names for the bits. 490// Use these only with the bit() macro. 491#define MPU6050_I2C_SLV0_DLY_EN MPU6050_D0 492#define MPU6050_I2C_SLV1_DLY_EN MPU6050_D1 493#define MPU6050_I2C_SLV2_DLY_EN MPU6050_D2 494#define MPU6050_I2C_SLV3_DLY_EN MPU6050_D3 495#define MPU6050_I2C_SLV4_DLY_EN MPU6050_D4 496#define MPU6050_DELAY_ES_SHADOW MPU6050_D7 497 498// SIGNAL_PATH_RESET Register 499// These are the names for the bits. 500// Use these only with the bit() macro. 501#define MPU6050_TEMP_RESET MPU6050_D0 502#define MPU6050_ACCEL_RESET MPU6050_D1 503#define MPU6050_GYRO_RESET MPU6050_D2 504 505// MOT_DETECT_CTRL Register 506// These are the names for the bits. 507// Use these only with the bit() macro. 508#define MPU6050_MOT_COUNT0 MPU6050_D0 509#define MPU6050_MOT_COUNT1 MPU6050_D1 510#define MPU6050_FF_COUNT0 MPU6050_D2 511#define MPU6050_FF_COUNT1 MPU6050_D3 512#define MPU6050_ACCEL_ON_DELAY0 MPU6050_D4 513#define MPU6050_ACCEL_ON_DELAY1 MPU6050_D5 514 515// Combined definitions for the MOT_COUNT 516#define MPU6050_MOT_COUNT_0 (0) 517#define MPU6050_MOT_COUNT_1 (bit(MPU6050_MOT_COUNT0)) 518#define MPU6050_MOT_COUNT_2 (bit(MPU6050_MOT_COUNT1)) 519#define MPU6050_MOT_COUNT_3 (bit(MPU6050_MOT_COUNT1)|bit(MPU6050_MOT_COUNT0)) 520 521// Alternative names for the combined definitions 522#define MPU6050_MOT_COUNT_RESET MPU6050_MOT_COUNT_0 523 524// Combined definitions for the FF_COUNT 525#define MPU6050_FF_COUNT_0 (0) 526#define MPU6050_FF_COUNT_1 (bit(MPU6050_FF_COUNT0)) 527#define MPU6050_FF_COUNT_2 (bit(MPU6050_FF_COUNT1)) 528#define MPU6050_FF_COUNT_3 (bit(MPU6050_FF_COUNT1)|bit(MPU6050_FF_COUNT0)) 529 530// Alternative names for the combined definitions 531#define MPU6050_FF_COUNT_RESET MPU6050_FF_COUNT_0 532 533// Combined definitions for the ACCEL_ON_DELAY 534#define MPU6050_ACCEL_ON_DELAY_0 (0) 535#define MPU6050_ACCEL_ON_DELAY_1 (bit(MPU6050_ACCEL_ON_DELAY0)) 536#define MPU6050_ACCEL_ON_DELAY_2 (bit(MPU6050_ACCEL_ON_DELAY1)) 537#define MPU6050_ACCEL_ON_DELAY_3 (bit(MPU6050_ACCEL_ON_DELAY1)|bit(MPU6050_ACCEL_ON_DELAY0)) 538 539// Alternative names for the ACCEL_ON_DELAY 540#define MPU6050_ACCEL_ON_DELAY_0MS MPU6050_ACCEL_ON_DELAY_0 541#define MPU6050_ACCEL_ON_DELAY_1MS MPU6050_ACCEL_ON_DELAY_1 542#define MPU6050_ACCEL_ON_DELAY_2MS MPU6050_ACCEL_ON_DELAY_2 543#define MPU6050_ACCEL_ON_DELAY_3MS MPU6050_ACCEL_ON_DELAY_3 544 545// USER_CTRL Register 546// These are the names for the bits. 547// Use these only with the bit() macro. 548#define MPU6050_SIG_COND_RESET MPU6050_D0 549#define MPU6050_I2C_MST_RESET MPU6050_D1 550#define MPU6050_FIFO_RESET MPU6050_D2 551#define MPU6050_I2C_IF_DIS MPU6050_D4 // must be 0 for MPU-6050 552#define MPU6050_I2C_MST_EN MPU6050_D5 553#define MPU6050_FIFO_EN MPU6050_D6 554 555// PWR_MGMT_1 Register 556// These are the names for the bits. 557// Use these only with the bit() macro. 558#define MPU6050_CLKSEL0 MPU6050_D0 559#define MPU6050_CLKSEL1 MPU6050_D1 560#define MPU6050_CLKSEL2 MPU6050_D2 561#define MPU6050_TEMP_DIS MPU6050_D3 // 1: disable temperature sensor 562#define MPU6050_CYCLE MPU6050_D5 // 1: sample and sleep 563#define MPU6050_SLEEP MPU6050_D6 // 1: sleep mode 564#define MPU6050_DEVICE_RESET MPU6050_D7 // 1: reset to default values 565 566// Combined definitions for the CLKSEL 567#define MPU6050_CLKSEL_0 (0) 568#define MPU6050_CLKSEL_1 (bit(MPU6050_CLKSEL0)) 569#define MPU6050_CLKSEL_2 (bit(MPU6050_CLKSEL1)) 570#define MPU6050_CLKSEL_3 (bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0)) 571#define MPU6050_CLKSEL_4 (bit(MPU6050_CLKSEL2)) 572#define MPU6050_CLKSEL_5 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL0)) 573#define MPU6050_CLKSEL_6 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1)) 574#define MPU6050_CLKSEL_7 (bit(MPU6050_CLKSEL2)|bit(MPU6050_CLKSEL1)|bit(MPU6050_CLKSEL0)) 575 576// Alternative names for the combined definitions 577#define MPU6050_CLKSEL_INTERNAL MPU6050_CLKSEL_0 578#define MPU6050_CLKSEL_X MPU6050_CLKSEL_1 579#define MPU6050_CLKSEL_Y MPU6050_CLKSEL_2 580#define MPU6050_CLKSEL_Z MPU6050_CLKSEL_3 581#define MPU6050_CLKSEL_EXT_32KHZ MPU6050_CLKSEL_4 582#define MPU6050_CLKSEL_EXT_19_2MHZ MPU6050_CLKSEL_5 583#define MPU6050_CLKSEL_RESERVED MPU6050_CLKSEL_6 584#define MPU6050_CLKSEL_STOP MPU6050_CLKSEL_7 585 586// PWR_MGMT_2 Register 587// These are the names for the bits. 588// Use these only with the bit() macro. 589#define MPU6050_STBY_ZG MPU6050_D0 590#define MPU6050_STBY_YG MPU6050_D1 591#define MPU6050_STBY_XG MPU6050_D2 592#define MPU6050_STBY_ZA MPU6050_D3 593#define MPU6050_STBY_YA MPU6050_D4 594#define MPU6050_STBY_XA MPU6050_D5 595#define MPU6050_LP_WAKE_CTRL0 MPU6050_D6 596#define MPU6050_LP_WAKE_CTRL1 MPU6050_D7 597 598// Combined definitions for the LP_WAKE_CTRL 599#define MPU6050_LP_WAKE_CTRL_0 (0) 600#define MPU6050_LP_WAKE_CTRL_1 (bit(MPU6050_LP_WAKE_CTRL0)) 601#define MPU6050_LP_WAKE_CTRL_2 (bit(MPU6050_LP_WAKE_CTRL1)) 602#define MPU6050_LP_WAKE_CTRL_3 (bit(MPU6050_LP_WAKE_CTRL1)|bit(MPU6050_LP_WAKE_CTRL0)) 603 604// Alternative names for the combined definitions 605// The names uses the Wake-up Frequency. 606#define MPU6050_LP_WAKE_1_25HZ MPU6050_LP_WAKE_CTRL_0 607#define MPU6050_LP_WAKE_2_5HZ MPU6050_LP_WAKE_CTRL_1 608#define MPU6050_LP_WAKE_5HZ MPU6050_LP_WAKE_CTRL_2 609#define MPU6050_LP_WAKE_10HZ MPU6050_LP_WAKE_CTRL_3 610 611 612// Default I2C address for the MPU-6050 is 0x68. 613// But only if the AD0 pin is low. 614// Some sensor boards have AD0 high, and the 615// I2C address thus becomes 0x69. 616#define MPU6050_I2C_ADDRESS 0x68 617 618 619// Declaring an union for the registers and the axis values. 620// The byte order does not match the byte order of 621// the compiler and AVR chip. 622// The AVR chip (on the Arduino board) has the Low Byte 623// at the lower address. 624// But the MPU-6050 has a different order: High Byte at 625// lower address, so that has to be corrected. 626// The register part "reg" is only used internally, 627// and are swapped in code. 628typedef union accel_t_gyro_union 629{ 630 struct 631 { 632 uint8_t x_accel_h; 633 uint8_t x_accel_l; 634 uint8_t y_accel_h; 635 uint8_t y_accel_l; 636 uint8_t z_accel_h; 637 uint8_t z_accel_l; 638 uint8_t t_h; 639 uint8_t t_l; 640 uint8_t x_gyro_h; 641 uint8_t x_gyro_l; 642 uint8_t y_gyro_h; 643 uint8_t y_gyro_l; 644 uint8_t z_gyro_h; 645 uint8_t z_gyro_l; 646 } reg; 647 struct 648 { 649 int x_accel; 650 int y_accel; 651 int z_accel; 652 int temperature; 653 int x_gyro; 654 int y_gyro; 655 int z_gyro; 656 } value; 657}; 658 659// Use the following global variables and access functions to help store the overall 660// rotation angle of the sensor 661unsigned long last_read_time; 662float last_x_angle; // These are the filtered angles 663float last_y_angle; 664float last_z_angle; 665float last_gyro_x_angle; // Store the gyro angles to compare drift 666float last_gyro_y_angle; 667float last_gyro_z_angle; 668float last_x_kalangle; //Kalman angle 669float last_y_kalangle; 670float last_z_kalangle; 671 672void set_last_read_angle_data(unsigned long time, float x, float y, float z, float x_gyro, float y_gyro, float z_gyro, float kx, float ky, float kz) { 673 last_read_time = time; 674 last_x_angle = x; 675 last_y_angle = y; 676 last_z_angle = z; 677 last_gyro_x_angle = x_gyro; 678 last_gyro_y_angle = y_gyro; 679 last_gyro_z_angle = z_gyro; 680 last_x_kalangle = kx; 681 last_y_kalangle = ky; 682 last_z_kalangle = kz; 683} 684 685inline unsigned long get_last_time() {return last_read_time;} 686inline float get_last_x_angle() {return last_x_angle;} 687inline float get_last_y_angle() {return last_y_angle;} 688inline float get_last_z_angle() {return last_z_angle;} 689inline float get_last_gyro_x_angle() {return last_gyro_x_angle;} 690inline float get_last_gyro_y_angle() {return last_gyro_y_angle;} 691inline float get_last_gyro_z_angle() {return last_gyro_z_angle;} 692inline float get_last_x_kalangle() {return last_x_kalangle;} 693inline float get_last_y_kalangle() {return last_y_kalangle;} 694inline float get_last_z_kalangle() {return last_z_kalangle;} 695 696// Use the following global variables and access functions 697// to calibrate the acceleration sensor 698float base_x_accel; 699float base_y_accel; 700float base_z_accel; 701 702float base_x_gyro; 703float base_y_gyro; 704float base_z_gyro; 705 706 707int read_gyro_accel_vals(uint8_t* accel_t_gyro_ptr) { 708 // Read the raw values. 709 // Read 14 bytes at once, 710 // containing acceleration, temperature and gyro. 711 // With the default settings of the MPU-6050, 712 // there is no filter enabled, and the values 713 // are not very stable. Returns the error value 714 715 accel_t_gyro_union* accel_t_gyro = (accel_t_gyro_union *) accel_t_gyro_ptr; 716 717 int error = MPU6050_read (MPU6050_ACCEL_XOUT_H, (uint8_t *) accel_t_gyro, sizeof(*accel_t_gyro)); 718 719 // Swap all high and low bytes. 720 // After this, the registers values are swapped, 721 // so the structure name like x_accel_l does no 722 // longer contain the lower byte. 723 uint8_t swap; 724 #define SWAP(x,y) swap = x; x = y; y = swap 725 726 SWAP ((*accel_t_gyro).reg.x_accel_h, (*accel_t_gyro).reg.x_accel_l); 727 SWAP ((*accel_t_gyro).reg.y_accel_h, (*accel_t_gyro).reg.y_accel_l); 728 SWAP ((*accel_t_gyro).reg.z_accel_h, (*accel_t_gyro).reg.z_accel_l); 729 SWAP ((*accel_t_gyro).reg.t_h, (*accel_t_gyro).reg.t_l); 730 SWAP ((*accel_t_gyro).reg.x_gyro_h, (*accel_t_gyro).reg.x_gyro_l); 731 SWAP ((*accel_t_gyro).reg.y_gyro_h, (*accel_t_gyro).reg.y_gyro_l); 732 SWAP ((*accel_t_gyro).reg.z_gyro_h, (*accel_t_gyro).reg.z_gyro_l); 733 734 return error; 735} 736 737// The sensor should be motionless on a horizontal surface 738// while calibration is happening 739void calibrate_sensors() { 740 int num_readings = 10; 741 float x_accel = 0; 742 float y_accel = 0; 743 float z_accel = 0; 744 float x_gyro = 0; 745 float y_gyro = 0; 746 float z_gyro = 0; 747 accel_t_gyro_union accel_t_gyro; 748 749 //Serial.println("Starting Calibration"); 750 751 // Discard the first set of values read from the IMU 752 read_gyro_accel_vals((uint8_t *) &accel_t_gyro); 753 754 // Read and average the raw values from the IMU 755 for (int i = 0; i < num_readings; i++) { 756 read_gyro_accel_vals((uint8_t *) &accel_t_gyro); 757 x_accel += accel_t_gyro.value.x_accel; 758 y_accel += accel_t_gyro.value.y_accel; 759 z_accel += accel_t_gyro.value.z_accel; 760 x_gyro += accel_t_gyro.value.x_gyro; 761 y_gyro += accel_t_gyro.value.y_gyro; 762 z_gyro += accel_t_gyro.value.z_gyro; 763 delay(100); 764 } 765 x_accel /= num_readings; 766 y_accel /= num_readings; 767 z_accel /= num_readings; 768 x_gyro /= num_readings; 769 y_gyro /= num_readings; 770 z_gyro /= num_readings; 771 772 // Store the raw calibration values globally 773 base_x_accel = x_accel; 774 base_y_accel = y_accel; 775 base_z_accel = z_accel; 776 base_x_gyro = x_gyro; 777 base_y_gyro = y_gyro; 778 base_z_gyro = z_gyro; 779 780 //Serial.println("Finishing Calibration"); 781} 782 783 784/************************ 785* KALMAN - Filter setup * 786*************************/ 787class Kalman { 788public: 789 Kalman() { 790 /* We will set the varibles like so, these can also be tuned by the user */ 791 Q_angle = 0.001; 792 Q_bias = 0.003; 793 R_measure = 0.03; 794 795 bias = 0; // Reset bias 796 P[0][0] = 0; // Since we assume tha the bias is 0 and we know the starting angle (use setAngle), the error covariance matrix is set like so - see: http://en.wikipedia.org/wiki/Kalman_filter#Example_application.2C_technical 797 P[0][1] = 0; 798 P[1][0] = 0; 799 P[1][1] = 0; 800 }; 801 // The angle should be in degrees and the rate should be in degrees per second and the delta time in seconds 802 float getAngle(float newAngle, float newRate, float dt) { 803 // KasBot V2 - Kalman filter module - http://www.x-firm.com/?page_id=145 804 // Modified by Kristian Lauszus 805 // See my blog post for more information: http://blog.tkjelectronics.dk/2012/09/a-practical-approach-to-kalman-filter-and-how-to-implement-it 806 807 // Discrete Kalman filter time update equations - Time Update ("Predict") 808 // Update xhat - Project the state ahead 809 /* Step 1 */ 810 rate = newRate - bias; 811 angle += dt * rate; 812 813 // Update estimation error covariance - Project the error covariance ahead 814 /* Step 2 */ 815 P[0][0] += dt * (dt*P[1][1] - P[0][1] - P[1][0] + Q_angle); 816 P[0][1] -= dt * P[1][1]; 817 P[1][0] -= dt * P[1][1]; 818 P[1][1] += Q_bias * dt; 819 820 // Discrete Kalman filter measurement update equations - Measurement Update ("Correct") 821 // Calculate Kalman gain - Compute the Kalman gain 822 /* Step 4 */ 823 S = P[0][0] + R_measure; 824 /* Step 5 */ 825 K[0] = P[0][0] / S; 826 K[1] = P[1][0] / S; 827 828 // Calculate angle and bias - Update estimate with measurement zk (newAngle) 829 /* Step 3 */ 830 y = newAngle - angle; 831 /* Step 6 */ 832 angle += K[0] * y; 833 bias += K[1] * y; 834 835 // Calculate estimation error covariance - Update the error covariance 836 /* Step 7 */ 837 P[0][0] -= K[0] * P[0][0]; 838 P[0][1] -= K[0] * P[0][1]; 839 P[1][0] -= K[1] * P[0][0]; 840 P[1][1] -= K[1] * P[0][1]; 841 842 return angle; 843 }; 844 void setAngle(double newAngle) { angle = newAngle; }; // Used to set angle, this should be set as the starting angle 845 double getRate() { return rate; }; // Return the unbiased rate 846 847 /* These are used to tune the Kalman filter */ 848 void setQangle(double newQ_angle) { Q_angle = newQ_angle; }; 849 void setQbias(double newQ_bias) { Q_bias = newQ_bias; }; 850 void setRmeasure(double newR_measure) { R_measure = newR_measure; }; 851 852 double getQangle() { return Q_angle; }; 853 double getQbias() { return Q_bias; }; 854 double getRmeasure() { return R_measure; }; 855 856private: 857 /* Kalman filter variables */ 858 double Q_angle; // Process noise variance for the accelerometer 859 double Q_bias; // Process noise variance for the gyro bias 860 double R_measure; // Measurement noise variance - this is actually the variance of the measurement noise 861 862 double angle; // The angle calculated by the Kalman filter - part of the 2x1 state matrix 863 double bias; // The gyro bias calculated by the Kalman filter - part of the 2x1 state matrix 864 double rate; // Unbiased rate calculated from the rate and the calculated bias - you have to call getAngle to update the rate 865 866 double P[2][2]; // Error covariance matrix - This is a 2x2 matrix 867 double K[2]; // Kalman gain - This is a 2x1 matrix 868 double y; // Angle difference - 1x1 matrix 869 double S; // Estimate error - 1x1 matrix 870}; 871Kalman kalmanX; // Create the Kalman instances 872Kalman kalmanY; 873 874 875 876/******** 877* SETUP * 878*********/ 879 880void setup() 881{ 882 int error; 883 uint8_t c; 884 accel_t_gyro_union accel_t_gyro; 885 886 887 Serial.begin(19200); 888 889 // Initialize the 'Wire' class for the I2C-bus. 890 Wire.begin(); 891 892 893 // default at power-up: 894 // Gyro at 250 degrees second 895 // Acceleration at 2g 896 // Clock source at internal 8MHz 897 // The device is in sleep mode. 898 // 899 900 error = MPU6050_read (MPU6050_WHO_AM_I, &c, 1); 901 902 903 // According to the datasheet, the 'sleep' bit 904 // should read a '1'. But I read a '0'. 905 // That bit has to be cleared, since the sensor 906 // is in sleep mode at power-up. Even if the 907 // bit reads '0'. 908 error = MPU6050_read (MPU6050_PWR_MGMT_2, &c, 1); 909 910 // Clear the 'sleep' bit to start the sensor. 911 MPU6050_write_reg (MPU6050_PWR_MGMT_1, 0); 912 913 //Initialize the angles 914 calibrate_sensors(); 915 set_last_read_angle_data(millis(), 0, 0, 0, 0, 0, 0, 0, 0, 0); 916 917 918 // Get raw acceleration values 919 //float G_CONVERT = 16384; 920 float accel_x = accel_t_gyro.value.x_accel; 921 float accel_y = accel_t_gyro.value.y_accel; 922 float accel_z = accel_t_gyro.value.z_accel; 923 924 // Get angle values from accelerometer 925 float RADIANS_TO_DEGREES = 180/3.14159; 926// float accel_vector_length = sqrt(pow(accel_x,2) + pow(accel_y,2) + pow(accel_z,2)); 927 float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 928 float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 929 930 float accel_angle_z = 0; 931 932 kalmanX.setAngle(accel_angle_x); // Set starting angle 933 kalmanY.setAngle(accel_angle_y); 934 935} 936 937 938 939/************ 940* Main loop * 941*************/ 942void loop() 943{ 944 int error; 945 double dT; 946 accel_t_gyro_union accel_t_gyro; 947 948 float kalAngleX, kalAngleY, kalAngleZ; // Calculate the angle using a Kalman filter 949 950 // Read the raw values. 951 error = read_gyro_accel_vals((uint8_t*) &accel_t_gyro); 952 953 // Get the time of reading for rotation computations 954 unsigned long t_now = millis(); 955 956 957 // Convert gyro values to degrees/sec 958 float FS_SEL = 131; 959 960 float gyro_x = (accel_t_gyro.value.x_gyro - base_x_gyro)/FS_SEL; 961 float gyro_y = (accel_t_gyro.value.y_gyro - base_y_gyro)/FS_SEL; 962 float gyro_z = (accel_t_gyro.value.z_gyro - base_z_gyro)/FS_SEL; 963 964 965 // Get raw acceleration values 966 //float G_CONVERT = 16384; 967 float accel_x = accel_t_gyro.value.x_accel; 968 float accel_y = accel_t_gyro.value.y_accel; 969 float accel_z = accel_t_gyro.value.z_accel; 970 971 // Get angle values from accelerometer 972 float RADIANS_TO_DEGREES = 180/3.14159; 973// float accel_vector_length = sqrt(pow(accel_x,2) + pow(accel_y,2) + pow(accel_z,2)); 974 float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 975 float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES; 976 977 float accel_angle_z = 0; 978 979 // Compute the (filtered) gyro angles 980 float dt =(t_now - get_last_time())/1000.0; 981 float gyro_angle_x = gyro_x*dt + get_last_x_angle(); 982 float gyro_angle_y = gyro_y*dt + get_last_y_angle(); 983 float gyro_angle_z = gyro_z*dt + get_last_z_angle(); 984 985 // Compute the drifting gyro angles 986 float unfiltered_gyro_angle_x = gyro_x*dt + get_last_gyro_x_angle(); 987 float unfiltered_gyro_angle_y = gyro_y*dt + get_last_gyro_y_angle(); 988 float unfiltered_gyro_angle_z = gyro_z*dt + get_last_gyro_z_angle(); 989 990 // Apply the complementary filter to figure out the change in angle - choice of alpha is 991 // estimated now. Alpha depends on the sampling rate... 992 float alpha = 0.96; 993 float angle_x = alpha*gyro_angle_x + (1.0 - alpha)*accel_angle_x; 994 float angle_y = alpha*gyro_angle_y + (1.0 - alpha)*accel_angle_y; 995 float angle_z = gyro_angle_z; //Accelerometer doesn't give z-angle 996 997 998 //KALMAN filter 999 kalAngleX = kalmanX.getAngle(accel_angle_x, gyro_x, dt); 1000 //delay(5); 1001 kalAngleY = kalmanY.getAngle(accel_angle_y, gyro_y, dt); 1002 kalAngleZ = gyro_angle_z; 1003 1004 1005 // Update the saved data with the latest values 1006 set_last_read_angle_data(t_now, angle_x, angle_y, angle_z, unfiltered_gyro_angle_x, unfiltered_gyro_angle_y, unfiltered_gyro_angle_z, kalAngleX, kalAngleY, kalAngleZ); 1007 1008 //Note added: 10/08/13 pad() creates padding that is required to ensure 128Bytes are sent. May not be needed as new version of LV code maybe able to handle 1009 1010 //Serial.print("START"); 1011 // Send the data to the serial port 1012 Serial.print(F("DEL:")); //Delta T 1013 Serial.print(dt, DEC); 1014 1015 Serial.print(F("#ACC:")); //Accelerometer angle 1016 pad(accel_angle_x); 1017 //Serial.print(accel_angle_x, 2); 1018 Serial.print(F(",")); 1019 pad(accel_angle_y); 1020 //Serial.print(accel_angle_y, 2); 1021 Serial.print(F(",")); 1022 pad(accel_angle_z); 1023 //Serial.print(accel_angle_z, 2); 1024 1025 Serial.print(F("#GYR:")); 1026 pad(unfiltered_gyro_angle_x); 1027 //Serial.print(unfiltered_gyro_angle_x, 2); //Gyroscope angle 1028 Serial.print(F(",")); 1029 pad(unfiltered_gyro_angle_y); 1030 //Serial.print(unfiltered_gyro_angle_y, 2); 1031 Serial.print(F(",")); 1032 pad(unfiltered_gyro_angle_z); 1033 //Serial.print(unfiltered_gyro_angle_z, 2); 1034 1035 Serial.print(F("#FIL:")); //Filtered angle 1036 pad(angle_x); 1037 //Serial.print(angle_x, 2); 1038 Serial.print(F(",")); 1039 pad(angle_y); 1040 //Serial.print(angle_y, 2); 1041 Serial.print(F(",")); 1042 pad(angle_z); 1043 //Serial.print(angle_z, 2); 1044 Serial.print(F(",")); 1045 1046 Serial.print(F("#KAL:")); //Kalman Filtered angle 1047 pad(kalAngleX); 1048 //Serial.print(kalAngleX, 2); 1049 Serial.print(F(",")); 1050 pad (kalAngleY); 1051 //Serial.print(kalAngleY, 2); 1052 Serial.print(F(",")); 1053 pad(kalAngleZ); 1054 //Serial.print(kalAngleZ, 2); 1055 //Serial.print("END"); 1056 Serial.print("\ 1057"); 1058 //Serial.println(F("")); 1059 Serial.flush(); 1060 // Delay so we don't swamp the serial port 1061 delay(5); //so not to swamp the serial port 1062} 1063 1064 1065// -------------------------------------------------------- 1066// MPU6050_read 1067// 1068// This is a common function to read multiple bytes 1069// from an I2C device. 1070// 1071// It uses the boolean parameter for Wire.endTransMission() 1072// to be able to hold or release the I2C-bus. 1073// This is implemented in Arduino 1.0.1. 1074// 1075// Only this function is used to read. 1076// There is no function for a single byte. 1077// 1078int MPU6050_read(int start, uint8_t *buffer, int size) 1079{ 1080 int i, n, error; 1081 1082 Wire.beginTransmission(MPU6050_I2C_ADDRESS); 1083 n = Wire.write(start); 1084 if (n != 1) 1085 return (-10); 1086 1087 n = Wire.endTransmission(false); // hold the I2C-bus 1088 if (n != 0) 1089 return (n); 1090 1091 // Third parameter is true: relase I2C-bus after data is read. 1092 Wire.requestFrom(MPU6050_I2C_ADDRESS, size, true); 1093 i = 0; 1094 while(Wire.available() && i<size) 1095 { 1096 buffer[i++]=Wire.read(); 1097 } 1098 if ( i != size) 1099 return (-11); 1100 1101 return (0); // return : no error 1102} 1103 1104 1105// -------------------------------------------------------- 1106// MPU6050_write 1107// 1108// This is a common function to write multiple bytes to an I2C device. 1109// 1110// If only a single register is written, 1111// use the function MPU_6050_write_reg(). 1112// 1113// Parameters: 1114// start : Start address, use a define for the register 1115// pData : A pointer to the data to write. 1116// size : The number of bytes to write. 1117// 1118// If only a single register is written, a pointer 1119// to the data has to be used, and the size is 1120// a single byte: 1121// int data = 0; // the data to write 1122// MPU6050_write (MPU6050_PWR_MGMT_1, &c, 1); 1123// 1124int MPU6050_write(int start, const uint8_t *pData, int size) 1125{ 1126 int n, error; 1127 1128 Wire.beginTransmission(MPU6050_I2C_ADDRESS); 1129 n = Wire.write(start); // write the start address 1130 if (n != 1) 1131 return (-20); 1132 1133 n = Wire.write(pData, size); // write data bytes 1134 if (n != size) 1135 return (-21); 1136 1137 error = Wire.endTransmission(true); // release the I2C-bus 1138 if (error != 0) 1139 return (error); 1140 1141 return (0); // return : no error 1142} 1143 1144// -------------------------------------------------------- 1145// MPU6050_write_reg 1146// 1147// An extra function to write a single register. 1148// It is just a wrapper around the MPU_6050_write() 1149// function, and it is only a convenient function 1150// to make it easier to write a single register. 1151// 1152int MPU6050_write_reg(int reg, uint8_t data) 1153{ 1154 int error; 1155 1156 error = MPU6050_write(reg, &data, 1); 1157 1158 return (error); 1159} 1160 1161//This function pads the printed value to take up 1162//7 characters Example: **20.16 1163void pad(float PadVal){ 1164 1165 //Positve Value 1166 if (PadVal > 0){ //For positive value 1167 if(PadVal < 10){ //For positive value less than 10 1168 Serial.print("***"); //0-9 ***0-9.00 1169 } 1170 else if (PadVal < 100){ //values less than 100 1171 Serial.print("**"); //10-99 **10-99.00 1172 } 1173 1174 } 1175 else if(PadVal < 0){ //for negative values 1176 if(PadVal > -10){ //for negative value greater than -10 1177 Serial.print("**"); //-9 - 0 **-1 - -9.00 1178 } 1179 else if (PadVal > -100){ //for negative values lesss than -99 1180 Serial.print("*"); //*-99.00 1181 } 1182 } 1183 1184 Serial.print(PadVal, 2); //print the padded value 1185}
Downloadable files
Project Schematic Diagram
Project Schematic Diagram
Comments
Only logged in users can leave comments
tahiryasin5
0 Followers
•0 Projects
Table of contents
Intro
2
0