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.cpp@0:7864abfabe2f, 2016-06-06 (annotated)
- Committer:
- Airium
- Date:
- Mon Jun 06 07:40:45 2016 +0000
- Revision:
- 0:7864abfabe2f
- Child:
- 1:e68ce5025dad
Full Driver for LSM303DLHC (e-compass); Readings for accelerometer, magnetometer and temperature meter; Class method to friendly modify Frequently-used 12 sensor settings; Class method to direct modify registers; Support calibration (offset+scale)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Airium | 0:7864abfabe2f | 1 | #include "mbed.h" |
Airium | 0:7864abfabe2f | 2 | #include "LSM303DLHC.h" |
Airium | 0:7864abfabe2f | 3 | |
Airium | 0:7864abfabe2f | 4 | LSM303DLHC::LSM303DLHC(PinName sda, PinName scl) : i2c(sda, scl){ |
Airium | 0:7864abfabe2f | 5 | i2c.frequency(400000); |
Airium | 0:7864abfabe2f | 6 | |
Airium | 0:7864abfabe2f | 7 | HPF_state = false; // reg default value corresponds to this |
Airium | 0:7864abfabe2f | 8 | |
Airium | 0:7864abfabe2f | 9 | acc_offset[0] = 0; |
Airium | 0:7864abfabe2f | 10 | acc_offset[1] = 0; |
Airium | 0:7864abfabe2f | 11 | acc_offset[2] = 0; |
Airium | 0:7864abfabe2f | 12 | acc_scale[0] = 1; |
Airium | 0:7864abfabe2f | 13 | acc_scale[1] = 1; |
Airium | 0:7864abfabe2f | 14 | acc_scale[2] = 1; |
Airium | 0:7864abfabe2f | 15 | |
Airium | 0:7864abfabe2f | 16 | mag_offset[0] = 0; |
Airium | 0:7864abfabe2f | 17 | mag_offset[1] = 0; |
Airium | 0:7864abfabe2f | 18 | mag_offset[2] = 0; |
Airium | 0:7864abfabe2f | 19 | mag_scale[0] = 1; |
Airium | 0:7864abfabe2f | 20 | mag_scale[1] = 1; |
Airium | 0:7864abfabe2f | 21 | mag_scale[2] = 1; |
Airium | 0:7864abfabe2f | 22 | |
Airium | 0:7864abfabe2f | 23 | temp_offset[0] = 0; |
Airium | 0:7864abfabe2f | 24 | temp_scale[0] = 1; |
Airium | 0:7864abfabe2f | 25 | |
Airium | 0:7864abfabe2f | 26 | // CUSTOM THE INITIAL CTRL FOR YOURSELF |
Airium | 0:7864abfabe2f | 27 | ACtrl(LP_OFF); // ACC Normal Power Mode |
Airium | 0:7864abfabe2f | 28 | ACtrl(ODR3); // ACC ON and Date Rate 25Hz |
Airium | 0:7864abfabe2f | 29 | ACtrl(HPF_ON); // ACC internal HPF In Use |
Airium | 0:7864abfabe2f | 30 | ACtrl(HPF_CF0); // ACC HPF Cutoff Freq = option 0 |
Airium | 0:7864abfabe2f | 31 | ACtrl(HPF_NORM); // ACC HPF Model = Normal |
Airium | 0:7864abfabe2f | 32 | ACtrl(BDU_CONT); // ACC data continuous |
Airium | 0:7864abfabe2f | 33 | ACtrl(G4); // ACC Range +/-4g |
Airium | 0:7864abfabe2f | 34 | ACtrl(HIGH_R); // ACC in High Prec |
Airium | 0:7864abfabe2f | 35 | MCtrl(DR4); // MAG DR 15Hz |
Airium | 0:7864abfabe2f | 36 | MCtrl(GN4); // MAG GN 4.0Gauss |
Airium | 0:7864abfabe2f | 37 | MCtrl(MD_CONT); // MAG ON and MD Continuous |
Airium | 0:7864abfabe2f | 38 | TCtrl(TEMP_ON); // TEMP ON |
Airium | 0:7864abfabe2f | 39 | } |
Airium | 0:7864abfabe2f | 40 | |
Airium | 0:7864abfabe2f | 41 | void LSM303DLHC::GetAcc(float arr[3]){ |
Airium | 0:7864abfabe2f | 42 | data[0] = OUT_X_L_A | (1 << 7); // MSB=1 to read multiple bytes |
Airium | 0:7864abfabe2f | 43 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 44 | i2c.read(ACC_ADDRESS, data, 6); |
Airium | 0:7864abfabe2f | 45 | |
Airium | 0:7864abfabe2f | 46 | // return the raw acceleration |
Airium | 0:7864abfabe2f | 47 | if (HPF_state == HPF_ON){ // HPF has no offset |
Airium | 0:7864abfabe2f | 48 | arr[0] = acc_scale[0]*((short)(data[1]<<8 | data[0])>>4); |
Airium | 0:7864abfabe2f | 49 | arr[1] = acc_scale[1]*((short)(data[3]<<8 | data[2])>>4); |
Airium | 0:7864abfabe2f | 50 | arr[2] = acc_scale[2]*((short)(data[5]<<8 | data[4])>>4); |
Airium | 0:7864abfabe2f | 51 | }else{ |
Airium | 0:7864abfabe2f | 52 | arr[0] = acc_scale[0]*(acc_offset[0]+((short)(data[1]<<8 | data[0])>>4)); |
Airium | 0:7864abfabe2f | 53 | arr[1] = acc_scale[1]*(acc_offset[1]+((short)(data[3]<<8 | data[2])>>4)); |
Airium | 0:7864abfabe2f | 54 | arr[2] = acc_scale[2]*(acc_offset[2]+((short)(data[5]<<8 | data[4])>>4)); |
Airium | 0:7864abfabe2f | 55 | } |
Airium | 0:7864abfabe2f | 56 | } |
Airium | 0:7864abfabe2f | 57 | |
Airium | 0:7864abfabe2f | 58 | void LSM303DLHC::GetMag(float arr[3]){ |
Airium | 0:7864abfabe2f | 59 | data[0] = OUT_X_H_M; |
Airium | 0:7864abfabe2f | 60 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 61 | i2c.read(MAG_ADDRESS, data, 6); |
Airium | 0:7864abfabe2f | 62 | arr[0] = mag_scale[0]*(mag_offset[0]+(short)(data[0]<<8 | data[1])); |
Airium | 0:7864abfabe2f | 63 | arr[1] = mag_scale[1]*(mag_offset[1]+(short)(data[4]<<8 | data[5])); |
Airium | 0:7864abfabe2f | 64 | arr[2] = mag_scale[2]*(mag_offset[2]+(short)(data[2]<<8 | data[3])); |
Airium | 0:7864abfabe2f | 65 | } |
Airium | 0:7864abfabe2f | 66 | |
Airium | 0:7864abfabe2f | 67 | void LSM303DLHC::GetTemp(float arr[1]){ |
Airium | 0:7864abfabe2f | 68 | data[0] = TEMP_OUT_H_M; |
Airium | 0:7864abfabe2f | 69 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 70 | i2c.read(MAG_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 71 | arr[0] = temp_scale[0]*(temp_offset[0]+((short)(data[0]<<8 | data[1])>>4)); |
Airium | 0:7864abfabe2f | 72 | } |
Airium | 0:7864abfabe2f | 73 | |
Airium | 0:7864abfabe2f | 74 | void LSM303DLHC::ACtrl(ACC_ODR cmd){ |
Airium | 0:7864abfabe2f | 75 | data[0] = CTRL_REG1_A; |
Airium | 0:7864abfabe2f | 76 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 77 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 78 | data[1] = data[1] & (0b00001111) | (cmd<<4); |
Airium | 0:7864abfabe2f | 79 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 80 | } |
Airium | 0:7864abfabe2f | 81 | |
Airium | 0:7864abfabe2f | 82 | void LSM303DLHC::ACtrl(ACC_LPen cmd){ |
Airium | 0:7864abfabe2f | 83 | data[0] = CTRL_REG1_A; |
Airium | 0:7864abfabe2f | 84 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 85 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 86 | data[1] = data[1] & (0b11110111) | (cmd<<3); |
Airium | 0:7864abfabe2f | 87 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 88 | } |
Airium | 0:7864abfabe2f | 89 | |
Airium | 0:7864abfabe2f | 90 | void LSM303DLHC::ACtrl(ACC_HPM cmd){ |
Airium | 0:7864abfabe2f | 91 | data[0] = CTRL_REG2_A; |
Airium | 0:7864abfabe2f | 92 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 93 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 94 | data[1] = data[1] & (0b00111111) | (cmd<<6); |
Airium | 0:7864abfabe2f | 95 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 96 | } |
Airium | 0:7864abfabe2f | 97 | |
Airium | 0:7864abfabe2f | 98 | void LSM303DLHC::ACtrl(ACC_HPCF cmd){ |
Airium | 0:7864abfabe2f | 99 | data[0] = CTRL_REG2_A; |
Airium | 0:7864abfabe2f | 100 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 101 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 102 | data[1] = data[1] & (0b11001111) | (cmd<<4); |
Airium | 0:7864abfabe2f | 103 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 104 | } |
Airium | 0:7864abfabe2f | 105 | |
Airium | 0:7864abfabe2f | 106 | void LSM303DLHC::ACtrl(ACC_FDS cmd){ |
Airium | 0:7864abfabe2f | 107 | data[0] = CTRL_REG2_A; |
Airium | 0:7864abfabe2f | 108 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 109 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 110 | data[1] = data[1] & (0b11110111) | (cmd<<3); |
Airium | 0:7864abfabe2f | 111 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 112 | (cmd == HPF_ON)?(HPF_state = true):(HPF_state = false); |
Airium | 0:7864abfabe2f | 113 | } |
Airium | 0:7864abfabe2f | 114 | |
Airium | 0:7864abfabe2f | 115 | void LSM303DLHC::ACtrl(ACC_BDU cmd){ |
Airium | 0:7864abfabe2f | 116 | data[0] = CTRL_REG4_A; |
Airium | 0:7864abfabe2f | 117 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 118 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 119 | data[1] = data[1] & (0b01111111) | (cmd<<7); |
Airium | 0:7864abfabe2f | 120 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 121 | } |
Airium | 0:7864abfabe2f | 122 | |
Airium | 0:7864abfabe2f | 123 | void LSM303DLHC::ACtrl(ACC_FS cmd){ |
Airium | 0:7864abfabe2f | 124 | data[0] = CTRL_REG4_A; |
Airium | 0:7864abfabe2f | 125 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 126 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 127 | data[1] = data[1] & (0b11001111) | (cmd<<4); |
Airium | 0:7864abfabe2f | 128 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 129 | } |
Airium | 0:7864abfabe2f | 130 | |
Airium | 0:7864abfabe2f | 131 | void LSM303DLHC::ACtrl(ACC_HR cmd){ |
Airium | 0:7864abfabe2f | 132 | data[0] = CTRL_REG4_A; |
Airium | 0:7864abfabe2f | 133 | i2c.write(ACC_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 134 | i2c.read(ACC_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 135 | data[1] = data[1] & (0b11110111) | (cmd<<3); |
Airium | 0:7864abfabe2f | 136 | i2c.write(ACC_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 137 | } |
Airium | 0:7864abfabe2f | 138 | |
Airium | 0:7864abfabe2f | 139 | void LSM303DLHC::TCtrl(TEMP_EN cmd){ |
Airium | 0:7864abfabe2f | 140 | data[0] = CRA_REG_M; |
Airium | 0:7864abfabe2f | 141 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 142 | i2c.read(MAG_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 143 | data[1] = data[1] & (0b01111111) | (cmd<<7); |
Airium | 0:7864abfabe2f | 144 | i2c.write(MAG_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 145 | } |
Airium | 0:7864abfabe2f | 146 | |
Airium | 0:7864abfabe2f | 147 | void LSM303DLHC::MCtrl(MAG_DR cmd){ |
Airium | 0:7864abfabe2f | 148 | data[0] = CRA_REG_M; |
Airium | 0:7864abfabe2f | 149 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 150 | i2c.read(MAG_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 151 | data[1] = data[1] & (0b11100011) | (cmd<<2); |
Airium | 0:7864abfabe2f | 152 | i2c.write(MAG_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 153 | } |
Airium | 0:7864abfabe2f | 154 | |
Airium | 0:7864abfabe2f | 155 | void LSM303DLHC::MCtrl(MAG_GN cmd){ |
Airium | 0:7864abfabe2f | 156 | data[0] = CRB_REG_M; |
Airium | 0:7864abfabe2f | 157 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 158 | i2c.read(MAG_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 159 | data[1] = data[1] & (0b00011111) | (cmd<<5); |
Airium | 0:7864abfabe2f | 160 | i2c.write(MAG_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 161 | } |
Airium | 0:7864abfabe2f | 162 | |
Airium | 0:7864abfabe2f | 163 | void LSM303DLHC::MCtrl(MAG_MD cmd){ |
Airium | 0:7864abfabe2f | 164 | data[0] = MR_REG_M; |
Airium | 0:7864abfabe2f | 165 | i2c.write(MAG_ADDRESS, data, 1); |
Airium | 0:7864abfabe2f | 166 | i2c.read(MAG_ADDRESS, &data[1], 1); |
Airium | 0:7864abfabe2f | 167 | data[1] = data[1] & (0b11111100) | (cmd<<0); |
Airium | 0:7864abfabe2f | 168 | i2c.write(MAG_ADDRESS, data, 2); |
Airium | 0:7864abfabe2f | 169 | } |
Airium | 0:7864abfabe2f | 170 | |
Airium | 0:7864abfabe2f | 171 | void LSM303DLHC::WriteReg(int sad, char d[2]){ |
Airium | 0:7864abfabe2f | 172 | i2c.write(sad, d, 2); |
Airium | 0:7864abfabe2f | 173 | } |
Airium | 0:7864abfabe2f | 174 | |
Airium | 0:7864abfabe2f | 175 | void LSM303DLHC::AccCal(float offset[3], float scale[3]){ |
Airium | 0:7864abfabe2f | 176 | acc_offset[0] = offset[0]; |
Airium | 0:7864abfabe2f | 177 | acc_offset[1] = offset[1]; |
Airium | 0:7864abfabe2f | 178 | acc_offset[2] = offset[2]; |
Airium | 0:7864abfabe2f | 179 | acc_scale[0] = scale[0]; |
Airium | 0:7864abfabe2f | 180 | acc_scale[1] = scale[1]; |
Airium | 0:7864abfabe2f | 181 | acc_scale[2] = scale[2]; |
Airium | 0:7864abfabe2f | 182 | } |
Airium | 0:7864abfabe2f | 183 | |
Airium | 0:7864abfabe2f | 184 | void LSM303DLHC::MagCal(float offset[3], float scale[3]){ |
Airium | 0:7864abfabe2f | 185 | mag_offset[0] = offset[0]; |
Airium | 0:7864abfabe2f | 186 | mag_offset[1] = offset[1]; |
Airium | 0:7864abfabe2f | 187 | mag_offset[2] = offset[2]; |
Airium | 0:7864abfabe2f | 188 | mag_scale[0] = scale[0]; |
Airium | 0:7864abfabe2f | 189 | mag_scale[1] = scale[1]; |
Airium | 0:7864abfabe2f | 190 | mag_scale[2] = scale[2]; |
Airium | 0:7864abfabe2f | 191 | } |
Airium | 0:7864abfabe2f | 192 | |
Airium | 0:7864abfabe2f | 193 | void LSM303DLHC::TempCal(float offset[1], float scale[1]){ |
Airium | 0:7864abfabe2f | 194 | temp_offset[0] = offset[0]; |
Airium | 0:7864abfabe2f | 195 | temp_scale[0] = scale[0]; |
Airium | 0:7864abfabe2f | 196 | } |
Airium | 0:7864abfabe2f | 197 | |
Airium | 0:7864abfabe2f | 198 | bool LSM303DLHC::isHPFEn(){ |
Airium | 0:7864abfabe2f | 199 | return HPF_state; |
Airium | 0:7864abfabe2f | 200 | } |