LSM303DLHC Full Driver: Readings For Acc, Mag and Temp; Class Method for frequently-used 13 sensor parameters; Class Method to direct modify registers; Support Calibration (offset+scale);
LSM303DLHC.h@2:192a6c228644, 2016-06-07 (annotated)
- Committer:
- Airium
- Date:
- Tue Jun 07 06:25:44 2016 +0000
- Revision:
- 2:192a6c228644
- Parent:
- 1:e68ce5025dad
- Child:
- 3:522d01930e6a
err.. fix bug
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Airium | 0:7864abfabe2f | 1 | #ifndef LSM303DLHC_H |
Airium | 0:7864abfabe2f | 2 | #define LSM303DLHC_H |
Airium | 0:7864abfabe2f | 3 | #include "mbed.h" |
Airium | 0:7864abfabe2f | 4 | // ACC SAD |
Airium | 0:7864abfabe2f | 5 | #define ACC_ADDRESS 0x32 |
Airium | 0:7864abfabe2f | 6 | // ACC CTRL SUB |
Airium | 0:7864abfabe2f | 7 | #define CTRL_REG1_A 0x20 //RW ODR(4) LPen Zen Yen Xen |
Airium | 0:7864abfabe2f | 8 | #define CTRL_REG2_A 0x21 //RW HPM(2) HPCF(2) FDS HPCLICK HPIS2 HPIS1 |
Airium | 0:7864abfabe2f | 9 | #define CTRL_REG3_A 0x22 //RW I1_CLICK I1_AOI1 I1_AOI2 I1_DRDY1 I1_DRDY2 I1_WTM I1_OVERRUN - |
Airium | 0:7864abfabe2f | 10 | #define CTRL_REG4_A 0x23 //RW BDU BLE FS1 FS0 HR 0(2) SIM |
Airium | 0:7864abfabe2f | 11 | #define CTRL_REG5_A 0x24 //RW BOOT FIFO_EN - - LIR_INT1 D4D_INT1 LIR_INT2 D4D_INT2 |
Airium | 0:7864abfabe2f | 12 | #define CTRL_REG6_A 0x25 //RW I2_CLICKen I2_INT1 I2_INT2 BOOT_I1 P2_ACT - H_LACTIVE - |
Airium | 0:7864abfabe2f | 13 | #define REFERENCE_A 0x26 //RW Ref7 Ref6 Ref5 Ref4 Ref3 Ref2 Ref1 Ref0 |
Airium | 0:7864abfabe2f | 14 | #define STATUS_REG_A 0x27 //R ZYXOR ZOR YOR XOR ZYXDA ZDA YDA XDA |
Airium | 0:7864abfabe2f | 15 | // ACC OUT SUB |
Airium | 0:7864abfabe2f | 16 | #define OUT_X_L_A 0x28 //R MSB(8) |
Airium | 0:7864abfabe2f | 17 | #define OUT_X_H_A 0x29 //R LSB(4) 0(4) |
Airium | 0:7864abfabe2f | 18 | #define OUT_Y_L_A 0x2A //R ditto |
Airium | 0:7864abfabe2f | 19 | #define OUT_Y_H_A 0x2B //R ditto |
Airium | 0:7864abfabe2f | 20 | #define OUT_Z_L_A 0x2C //R ditto |
Airium | 0:7864abfabe2f | 21 | #define OUT_Z_H_A 0x2D //R ditto |
Airium | 0:7864abfabe2f | 22 | // ACC INT SUB |
Airium | 0:7864abfabe2f | 23 | #define INT1_CFG_A 0x30 |
Airium | 0:7864abfabe2f | 24 | #define INT1_SRC_A 0x31 |
Airium | 0:7864abfabe2f | 25 | #define INT1_THS_A 0x32 |
Airium | 0:7864abfabe2f | 26 | #define INT1_DURATION_A 0x33 |
Airium | 0:7864abfabe2f | 27 | #define INT2_CFG_A 0x34 |
Airium | 0:7864abfabe2f | 28 | #define INT2_SRC_A 0x35 |
Airium | 0:7864abfabe2f | 29 | #define INT2_THS_A 0x36 |
Airium | 0:7864abfabe2f | 30 | #define INT2_DURATION_A 0x37 |
Airium | 0:7864abfabe2f | 31 | // ACC CLICK SUB |
Airium | 0:7864abfabe2f | 32 | #define CLICK_CFG_A 0x38 |
Airium | 0:7864abfabe2f | 33 | #define CLICK_SRC_A 0x39 |
Airium | 0:7864abfabe2f | 34 | #define CLICK_THS_A 0x3A |
Airium | 0:7864abfabe2f | 35 | #define TIME_LIMIT_A 0x3B |
Airium | 0:7864abfabe2f | 36 | #define TIME_LATENCY_A 0x3C |
Airium | 0:7864abfabe2f | 37 | #define TIME_WINDOW_A 0x3D |
Airium | 0:7864abfabe2f | 38 | |
Airium | 0:7864abfabe2f | 39 | // MAG SAD |
Airium | 0:7864abfabe2f | 40 | #define MAG_ADDRESS 0x3C |
Airium | 0:7864abfabe2f | 41 | // MAG CTRL SUB |
Airium | 0:7864abfabe2f | 42 | #define CRA_REG_M 0x00 //RW TEMP_EN 0(2) DR(3) 0(2) |
Airium | 0:7864abfabe2f | 43 | #define CRB_REG_M 0x01 //RW GN(3) 0(5) |
Airium | 0:7864abfabe2f | 44 | #define MR_REG_M 0x02 //RW 0(6) MD(2) |
Airium | 0:7864abfabe2f | 45 | // MAG OUT SUB |
Airium | 0:7864abfabe2f | 46 | #define OUT_X_H_M 0x03 //R LSB(8) |
Airium | 0:7864abfabe2f | 47 | #define OUT_X_L_M 0x04 //R 0(4) MSB(4) |
Airium | 0:7864abfabe2f | 48 | #define OUT_Z_H_M 0x05 //R ditto |
Airium | 0:7864abfabe2f | 49 | #define OUT_Z_L_M 0x06 //R ditto |
Airium | 0:7864abfabe2f | 50 | #define OUT_Y_H_M 0x07 //R ditto |
Airium | 0:7864abfabe2f | 51 | #define OUT_Y_L_M 0x08 //R ditto |
Airium | 0:7864abfabe2f | 52 | #define SR_REG_M 0x09 //R -(6) LOCK DRDY |
Airium | 0:7864abfabe2f | 53 | #define IRA_REG_M 0x0A //R |
Airium | 0:7864abfabe2f | 54 | #define IRB_REG_M 0x0B //R |
Airium | 0:7864abfabe2f | 55 | #define IRC_REG_M 0x0C //R |
Airium | 0:7864abfabe2f | 56 | // Temprature OUT SUB |
Airium | 0:7864abfabe2f | 57 | #define TEMP_OUT_H_M 0x31 //R MSB(8) |
Airium | 0:7864abfabe2f | 58 | #define TEMP_OUT_L_M 0x32 //R LSB(4) 0(4) |
Airium | 0:7864abfabe2f | 59 | |
Airium | 0:7864abfabe2f | 60 | class LSM303DLHC { |
Airium | 0:7864abfabe2f | 61 | public: |
Airium | 0:7864abfabe2f | 62 | //// PORT |
Airium | 0:7864abfabe2f | 63 | LSM303DLHC(PinName sda, PinName scl); |
Airium | 0:7864abfabe2f | 64 | |
Airium | 0:7864abfabe2f | 65 | //// REG CTRL |
Airium | 0:7864abfabe2f | 66 | // modify the default in LSM303DLHC.cpp |
Airium | 0:7864abfabe2f | 67 | |
Airium | 0:7864abfabe2f | 68 | //// CTRL_REG1_A (20h) |
Airium | 0:7864abfabe2f | 69 | // ACC Low Power Mode ON/OFF |
Airium | 0:7864abfabe2f | 70 | enum ACC_LPen { LP_OFF = 0, LP_ON = 1} ; |
Airium | 0:7864abfabe2f | 71 | void ACtrl(ACC_LPen cmd); |
Airium | 0:7864abfabe2f | 72 | // ACC Data Rate NOTE: ACC SWITCH IS HERE |
Airium | 0:7864abfabe2f | 73 | enum ACC_ODR { PW_D = 0, ODR1 = 1, ODR2 = 2, ODR3 = 3, ODR4 = 4, |
Airium | 0:7864abfabe2f | 74 | // PW Down 1Hz 10Hz 25Hz 50Hz |
Airium | 0:7864abfabe2f | 75 | ODR5 = 5, ODR6 = 6, ODR7 = 7, ODR8 = 8, ODR9 = 9}; |
Airium | 0:7864abfabe2f | 76 | // 100Hz 200Hz 400Hz 1620Hz@LP 1344Hz@NM/5376HZ@LP |
Airium | 0:7864abfabe2f | 77 | void ACtrl(ACC_ODR cmd); |
Airium | 1:e68ce5025dad | 78 | // ACC AXIS SEL |
Airium | 2:192a6c228644 | 79 | enum ACC_AXIS { NONE = 0, X = 1, Y = 2, XY = 3, Z = 4, XZ = 5, YZ = 6, XYZ = 7 }; |
Airium | 1:e68ce5025dad | 80 | void ACtrl(ACC_AXIS cmd); |
Airium | 0:7864abfabe2f | 81 | |
Airium | 0:7864abfabe2f | 82 | //// CTRL_REG2_A (21h) |
Airium | 0:7864abfabe2f | 83 | // ACC HPF Mode |
Airium | 0:7864abfabe2f | 84 | enum ACC_HPM { HPF_NORM_R = 0, HPF_REF = 1, HPF_NORM = 2, HPF_AUTO = 3 }; |
Airium | 0:7864abfabe2f | 85 | void ACtrl(ACC_HPM cmd); |
Airium | 0:7864abfabe2f | 86 | // ACC HPF Cutoff Freq |
Airium | 0:7864abfabe2f | 87 | enum ACC_HPCF { HPF_CF0 = 0, HPF_CF1 = 1, HPF_CF2 = 2, HPF_CF3 = 3}; |
Airium | 0:7864abfabe2f | 88 | void ACtrl(ACC_HPCF cmd); |
Airium | 0:7864abfabe2f | 89 | // ACC HPF ON/OFF for output |
Airium | 0:7864abfabe2f | 90 | enum ACC_FDS { HPF_OFF = 0, HPF_ON = 1 }; |
Airium | 0:7864abfabe2f | 91 | void ACtrl(ACC_FDS cmd); |
Airium | 0:7864abfabe2f | 92 | |
Airium | 0:7864abfabe2f | 93 | //// CTRL_REG4_A (23h) |
Airium | 0:7864abfabe2f | 94 | // ACC Block Date Update Mode |
Airium | 0:7864abfabe2f | 95 | enum ACC_BDU { BDU_CONT = 0, BDU_HOLD = 1 }; |
Airium | 0:7864abfabe2f | 96 | void ACtrl(ACC_BDU cmd); |
Airium | 0:7864abfabe2f | 97 | // ACC Output Full-Scale SEL |
Airium | 0:7864abfabe2f | 98 | enum ACC_FS {G2 = 0b00, G4 = 0b01, G8 = 0b10, G16= 0b11 }; |
Airium | 0:7864abfabe2f | 99 | // +/-2g +/-4g +/-8g +/-16g |
Airium | 0:7864abfabe2f | 100 | void ACtrl(ACC_FS cmd); |
Airium | 0:7864abfabe2f | 101 | // ACC Output in High/Low Resolution (Precision SEL) |
Airium | 0:7864abfabe2f | 102 | enum ACC_HR { LOW_R = 0, HIGH_R = 1 }; |
Airium | 0:7864abfabe2f | 103 | // 10bit 12bit |
Airium | 0:7864abfabe2f | 104 | void ACtrl(ACC_HR cmd); |
Airium | 0:7864abfabe2f | 105 | |
Airium | 0:7864abfabe2f | 106 | //// CRA_REG_M (00h) |
Airium | 0:7864abfabe2f | 107 | // TEMP Sensor En NOTE: TEMP SWITCH IS HERE |
Airium | 0:7864abfabe2f | 108 | enum TEMP_EN { TEMP_OFF = 0, TEMP_ON = 1}; |
Airium | 0:7864abfabe2f | 109 | void TCtrl(TEMP_EN cmd); |
Airium | 0:7864abfabe2f | 110 | // MAG Data Rate (Note: MAG_DR determines DRDY pin) |
Airium | 0:7864abfabe2f | 111 | enum MAG_DR { DR0 = 0, DR1 = 1, DR2 = 2, DR3 = 3, |
Airium | 0:7864abfabe2f | 112 | // 0.75Hz 1.5Hz 3Hz 7.5Hz |
Airium | 0:7864abfabe2f | 113 | DR4 = 4, DR5 = 5, DR6 = 6, DR7 = 7}; |
Airium | 0:7864abfabe2f | 114 | // 15Hz 30Hz 75Hz 220Hz |
Airium | 0:7864abfabe2f | 115 | void MCtrl(MAG_DR cmd); // MAG Date Rate |
Airium | 0:7864abfabe2f | 116 | |
Airium | 0:7864abfabe2f | 117 | //// CRB_REG_M (01h) |
Airium | 0:7864abfabe2f | 118 | // MAG Gain (Range SEL) |
Airium | 0:7864abfabe2f | 119 | enum MAG_GN { GN1 = 1, GN2 = 2, GN3 = 3, GN4 = 4, |
Airium | 0:7864abfabe2f | 120 | // 1.3 1.9 2.5 4.0 (+/- Gauss) |
Airium | 0:7864abfabe2f | 121 | GN5 = 5, GN6 = 6, GN7 = 7}; |
Airium | 0:7864abfabe2f | 122 | // 4.7 5.6 8.1 (+/- Gauss) |
Airium | 0:7864abfabe2f | 123 | void MCtrl(MAG_GN cmd); // MAG Measure Range |
Airium | 0:7864abfabe2f | 124 | |
Airium | 0:7864abfabe2f | 125 | //// MR_REG_M (02h) |
Airium | 0:7864abfabe2f | 126 | // MAG Mode NOTE: MAG SWITCH IS HERE |
Airium | 0:7864abfabe2f | 127 | enum MAG_MD { MD_CONT = 0, MD_SING = 1, MD_SLP = 2, MD_SLP2 = 3}; |
Airium | 0:7864abfabe2f | 128 | // Continuous single-conv sleep-mode sleep-mode |
Airium | 0:7864abfabe2f | 129 | void MCtrl(MAG_MD cmd); |
Airium | 0:7864abfabe2f | 130 | |
Airium | 0:7864abfabe2f | 131 | //// Change more regs |
Airium | 0:7864abfabe2f | 132 | void WriteReg(int sad, char d[2]); // Write value to reg |
Airium | 0:7864abfabe2f | 133 | // CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN |
Airium | 0:7864abfabe2f | 134 | // CAUTION: WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE |
Airium | 0:7864abfabe2f | 135 | // PLEASE FOLLOW DATASHEET RIGIDLY |
Airium | 0:7864abfabe2f | 136 | // sad = ACC_ADDRESS or MAG_ADDRESS |
Airium | 0:7864abfabe2f | 137 | // d[0] = Register Address |
Airium | 0:7864abfabe2f | 138 | // d[1] = Register Value |
Airium | 0:7864abfabe2f | 139 | |
Airium | 0:7864abfabe2f | 140 | //// Get Data |
Airium | 0:7864abfabe2f | 141 | void GetAcc(float arr[3]); // Get acceleration using current HPF setting |
Airium | 0:7864abfabe2f | 142 | // range -2048 ~ +2047 |
Airium | 0:7864abfabe2f | 143 | void GetMag(float arr[3]); // Get magnetic flux density |
Airium | 0:7864abfabe2f | 144 | // range -2048 to 2047 |
Airium | 0:7864abfabe2f | 145 | void GetTemp(float arr[1]); // Get temperature |
Airium | 0:7864abfabe2f | 146 | // range -2048 to 2047 |
Airium | 0:7864abfabe2f | 147 | |
Airium | 0:7864abfabe2f | 148 | //// sensor reading calibration |
Airium | 0:7864abfabe2f | 149 | void AccCal(float offset[3], float scale[3]); // Acc Calibration |
Airium | 0:7864abfabe2f | 150 | // affect the reading by output = scale * ( offset + original ) |
Airium | 0:7864abfabe2f | 151 | // but if internal HPF enable then output = scale * original |
Airium | 0:7864abfabe2f | 152 | void MagCal(float offset[3], float scale[3]); // Mag Calibration |
Airium | 0:7864abfabe2f | 153 | // affect the reading by output = scale * ( offset + original ) |
Airium | 0:7864abfabe2f | 154 | void TempCal(float offset[1], float scale[1]); // Mag Calibration |
Airium | 0:7864abfabe2f | 155 | // affect the reading by output = scale * ( offset + original ) |
Airium | 0:7864abfabe2f | 156 | |
Airium | 0:7864abfabe2f | 157 | //// Other functions |
Airium | 0:7864abfabe2f | 158 | bool isHPFEn(); // report HPF ON/OFF state for output |
Airium | 0:7864abfabe2f | 159 | // return HPF_state |
Airium | 0:7864abfabe2f | 160 | |
Airium | 0:7864abfabe2f | 161 | //// Not implemented function |
Airium | 0:7864abfabe2f | 162 | bool isAccRdy(); // Check if acc has new data |
Airium | 0:7864abfabe2f | 163 | // one way is to use high freq ticker to check STATUS_REG_A (27h) |
Airium | 0:7864abfabe2f | 164 | // I2C@400kHz just enough to check Max Normal Mode Data Rate (1344Hz) |
Airium | 0:7864abfabe2f | 165 | bool isMagRdy(); // check if mag has new data |
Airium | 0:7864abfabe2f | 166 | // one way is to use InterruptIn to trigger from DRDY pin |
Airium | 0:7864abfabe2f | 167 | // DRDY pin freq defined by MAG_DR |
Airium | 0:7864abfabe2f | 168 | |
Airium | 0:7864abfabe2f | 169 | private: |
Airium | 0:7864abfabe2f | 170 | I2C i2c; |
Airium | 0:7864abfabe2f | 171 | char data[6]; // used as main data exchange |
Airium | 0:7864abfabe2f | 172 | bool HPF_state; // state of internal HPF |
Airium | 0:7864abfabe2f | 173 | |
Airium | 0:7864abfabe2f | 174 | // use offset to calibrate zero reading |
Airium | 0:7864abfabe2f | 175 | float acc_offset[3]; |
Airium | 0:7864abfabe2f | 176 | float mag_offset[3]; |
Airium | 0:7864abfabe2f | 177 | float temp_offset[1]; |
Airium | 0:7864abfabe2f | 178 | |
Airium | 0:7864abfabe2f | 179 | //use scale to adjust the range to required |
Airium | 0:7864abfabe2f | 180 | float acc_scale[3]; |
Airium | 0:7864abfabe2f | 181 | float mag_scale[3]; |
Airium | 0:7864abfabe2f | 182 | float temp_scale[1]; |
Airium | 0:7864abfabe2f | 183 | }; |
Airium | 0:7864abfabe2f | 184 | |
Airium | 0:7864abfabe2f | 185 | #endif |