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);

Dependencies:   mbed

Committer:
Airium
Date:
Tue Jun 07 15:18:48 2016 +0000
Revision:
3:522d01930e6a
Parent:
1:e68ce5025dad
Child:
4:8723c07d4c45
Add Compact User Instruction in header; Some names changed for convenience;  Reg addrs defined in a separate header; if no bug this shall be the final version

Who changed what in which revision?

UserRevisionLine numberNew 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 3:522d01930e6a 9 // HERE GIVES DEVICE DEFAULT
Airium 3:522d01930e6a 10 ACtrl(LP_OFF); // ACC Normal Power Mode
Airium 3:522d01930e6a 11 ACtrl(ADR3); // ACC ON and Date Rate 25Hz
Airium 3:522d01930e6a 12 ACtrl(XYZ); // ACC XYZ Axis Enable
Airium 3:522d01930e6a 13 ACtrl(HPF_ON); // ACC internal HPF IN USE
Airium 3:522d01930e6a 14 ACtrl(HPF_CF0); // ACC HPF Cutoff Freq = option 0
Airium 3:522d01930e6a 15 ACtrl(HPF_NORM_R); // ACC HPF Model = Normal
Airium 3:522d01930e6a 16 ACtrl(BDU_CONT); // ACC data continuous
Airium 3:522d01930e6a 17 ACtrl(G4); // ACC Range +/-4g
Airium 3:522d01930e6a 18 ACtrl(HIGH_R); // ACC in High Prec
Airium 3:522d01930e6a 19 MCtrl(MDR4); // MAG DR 15Hz
Airium 3:522d01930e6a 20 MCtrl(GN4); // MAG GN 4.0Gauss
Airium 3:522d01930e6a 21 MCtrl(MD_CONT); // MAG ON and MD Continuous
Airium 3:522d01930e6a 22 TCtrl(TEMP_ON); // TEMP ON
Airium 3:522d01930e6a 23
Airium 3:522d01930e6a 24 // DEFAULT CALIBRATION PARAMETER
Airium 0:7864abfabe2f 25 acc_offset[0] = 0;
Airium 0:7864abfabe2f 26 acc_offset[1] = 0;
Airium 0:7864abfabe2f 27 acc_offset[2] = 0;
Airium 0:7864abfabe2f 28 acc_scale[0] = 1;
Airium 0:7864abfabe2f 29 acc_scale[1] = 1;
Airium 0:7864abfabe2f 30 acc_scale[2] = 1;
Airium 0:7864abfabe2f 31
Airium 0:7864abfabe2f 32 mag_offset[0] = 0;
Airium 0:7864abfabe2f 33 mag_offset[1] = 0;
Airium 0:7864abfabe2f 34 mag_offset[2] = 0;
Airium 0:7864abfabe2f 35 mag_scale[0] = 1;
Airium 0:7864abfabe2f 36 mag_scale[1] = 1;
Airium 0:7864abfabe2f 37 mag_scale[2] = 1;
Airium 0:7864abfabe2f 38
Airium 0:7864abfabe2f 39 temp_offset[0] = 0;
Airium 0:7864abfabe2f 40 temp_scale[0] = 1;
Airium 0:7864abfabe2f 41 }
Airium 0:7864abfabe2f 42
Airium 0:7864abfabe2f 43 void LSM303DLHC::GetAcc(float arr[3]){
Airium 0:7864abfabe2f 44 data[0] = OUT_X_L_A | (1 << 7); // MSB=1 to read multiple bytes
Airium 0:7864abfabe2f 45 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 46 i2c.read(ACC_ADDRESS, data, 6);
Airium 0:7864abfabe2f 47
Airium 0:7864abfabe2f 48 // return the raw acceleration
Airium 0:7864abfabe2f 49 if (HPF_state == HPF_ON){ // HPF has no offset
Airium 0:7864abfabe2f 50 arr[0] = acc_scale[0]*((short)(data[1]<<8 | data[0])>>4);
Airium 0:7864abfabe2f 51 arr[1] = acc_scale[1]*((short)(data[3]<<8 | data[2])>>4);
Airium 0:7864abfabe2f 52 arr[2] = acc_scale[2]*((short)(data[5]<<8 | data[4])>>4);
Airium 0:7864abfabe2f 53 }else{
Airium 0:7864abfabe2f 54 arr[0] = acc_scale[0]*(acc_offset[0]+((short)(data[1]<<8 | data[0])>>4));
Airium 0:7864abfabe2f 55 arr[1] = acc_scale[1]*(acc_offset[1]+((short)(data[3]<<8 | data[2])>>4));
Airium 0:7864abfabe2f 56 arr[2] = acc_scale[2]*(acc_offset[2]+((short)(data[5]<<8 | data[4])>>4));
Airium 0:7864abfabe2f 57 }
Airium 0:7864abfabe2f 58 }
Airium 0:7864abfabe2f 59
Airium 0:7864abfabe2f 60 void LSM303DLHC::GetMag(float arr[3]){
Airium 0:7864abfabe2f 61 data[0] = OUT_X_H_M;
Airium 0:7864abfabe2f 62 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 63 i2c.read(MAG_ADDRESS, data, 6);
Airium 0:7864abfabe2f 64 arr[0] = mag_scale[0]*(mag_offset[0]+(short)(data[0]<<8 | data[1]));
Airium 0:7864abfabe2f 65 arr[1] = mag_scale[1]*(mag_offset[1]+(short)(data[4]<<8 | data[5]));
Airium 0:7864abfabe2f 66 arr[2] = mag_scale[2]*(mag_offset[2]+(short)(data[2]<<8 | data[3]));
Airium 0:7864abfabe2f 67 }
Airium 0:7864abfabe2f 68
Airium 0:7864abfabe2f 69 void LSM303DLHC::GetTemp(float arr[1]){
Airium 0:7864abfabe2f 70 data[0] = TEMP_OUT_H_M;
Airium 0:7864abfabe2f 71 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 72 i2c.read(MAG_ADDRESS, data, 2);
Airium 0:7864abfabe2f 73 arr[0] = temp_scale[0]*(temp_offset[0]+((short)(data[0]<<8 | data[1])>>4));
Airium 0:7864abfabe2f 74 }
Airium 0:7864abfabe2f 75
Airium 0:7864abfabe2f 76 void LSM303DLHC::ACtrl(ACC_ODR cmd){
Airium 0:7864abfabe2f 77 data[0] = CTRL_REG1_A;
Airium 0:7864abfabe2f 78 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 79 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 80 data[1] = data[1] & (0b00001111) | (cmd<<4);
Airium 0:7864abfabe2f 81 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 82 }
Airium 0:7864abfabe2f 83
Airium 0:7864abfabe2f 84 void LSM303DLHC::ACtrl(ACC_LPen cmd){
Airium 0:7864abfabe2f 85 data[0] = CTRL_REG1_A;
Airium 0:7864abfabe2f 86 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 87 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 88 data[1] = data[1] & (0b11110111) | (cmd<<3);
Airium 0:7864abfabe2f 89 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 90 }
Airium 0:7864abfabe2f 91
Airium 1:e68ce5025dad 92 void LSM303DLHC::ACtrl(ACC_AXIS cmd){
Airium 1:e68ce5025dad 93 data[0] = CTRL_REG1_A;
Airium 1:e68ce5025dad 94 i2c.write(ACC_ADDRESS, data, 1);
Airium 1:e68ce5025dad 95 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 1:e68ce5025dad 96 data[1] = data[1] & (0b11111000) | (cmd<<0);
Airium 1:e68ce5025dad 97 i2c.write(ACC_ADDRESS, data, 2);
Airium 1:e68ce5025dad 98 }
Airium 1:e68ce5025dad 99
Airium 0:7864abfabe2f 100 void LSM303DLHC::ACtrl(ACC_HPM cmd){
Airium 0:7864abfabe2f 101 data[0] = CTRL_REG2_A;
Airium 0:7864abfabe2f 102 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 103 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 104 data[1] = data[1] & (0b00111111) | (cmd<<6);
Airium 0:7864abfabe2f 105 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 106 }
Airium 0:7864abfabe2f 107
Airium 0:7864abfabe2f 108 void LSM303DLHC::ACtrl(ACC_HPCF cmd){
Airium 0:7864abfabe2f 109 data[0] = CTRL_REG2_A;
Airium 0:7864abfabe2f 110 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 111 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 112 data[1] = data[1] & (0b11001111) | (cmd<<4);
Airium 0:7864abfabe2f 113 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 114 }
Airium 0:7864abfabe2f 115
Airium 0:7864abfabe2f 116 void LSM303DLHC::ACtrl(ACC_FDS cmd){
Airium 0:7864abfabe2f 117 data[0] = CTRL_REG2_A;
Airium 0:7864abfabe2f 118 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 119 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 120 data[1] = data[1] & (0b11110111) | (cmd<<3);
Airium 0:7864abfabe2f 121 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 122 (cmd == HPF_ON)?(HPF_state = true):(HPF_state = false);
Airium 0:7864abfabe2f 123 }
Airium 0:7864abfabe2f 124
Airium 0:7864abfabe2f 125 void LSM303DLHC::ACtrl(ACC_BDU cmd){
Airium 0:7864abfabe2f 126 data[0] = CTRL_REG4_A;
Airium 0:7864abfabe2f 127 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 128 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 129 data[1] = data[1] & (0b01111111) | (cmd<<7);
Airium 0:7864abfabe2f 130 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 131 }
Airium 0:7864abfabe2f 132
Airium 0:7864abfabe2f 133 void LSM303DLHC::ACtrl(ACC_FS cmd){
Airium 0:7864abfabe2f 134 data[0] = CTRL_REG4_A;
Airium 0:7864abfabe2f 135 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 136 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 137 data[1] = data[1] & (0b11001111) | (cmd<<4);
Airium 0:7864abfabe2f 138 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 139 }
Airium 0:7864abfabe2f 140
Airium 0:7864abfabe2f 141 void LSM303DLHC::ACtrl(ACC_HR cmd){
Airium 0:7864abfabe2f 142 data[0] = CTRL_REG4_A;
Airium 0:7864abfabe2f 143 i2c.write(ACC_ADDRESS, data, 1);
Airium 0:7864abfabe2f 144 i2c.read(ACC_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 145 data[1] = data[1] & (0b11110111) | (cmd<<3);
Airium 0:7864abfabe2f 146 i2c.write(ACC_ADDRESS, data, 2);
Airium 0:7864abfabe2f 147 }
Airium 0:7864abfabe2f 148
Airium 0:7864abfabe2f 149 void LSM303DLHC::TCtrl(TEMP_EN cmd){
Airium 0:7864abfabe2f 150 data[0] = CRA_REG_M;
Airium 0:7864abfabe2f 151 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 152 i2c.read(MAG_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 153 data[1] = data[1] & (0b01111111) | (cmd<<7);
Airium 0:7864abfabe2f 154 i2c.write(MAG_ADDRESS, data, 2);
Airium 0:7864abfabe2f 155 }
Airium 0:7864abfabe2f 156
Airium 0:7864abfabe2f 157 void LSM303DLHC::MCtrl(MAG_DR cmd){
Airium 0:7864abfabe2f 158 data[0] = CRA_REG_M;
Airium 0:7864abfabe2f 159 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 160 i2c.read(MAG_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 161 data[1] = data[1] & (0b11100011) | (cmd<<2);
Airium 0:7864abfabe2f 162 i2c.write(MAG_ADDRESS, data, 2);
Airium 0:7864abfabe2f 163 }
Airium 0:7864abfabe2f 164
Airium 0:7864abfabe2f 165 void LSM303DLHC::MCtrl(MAG_GN cmd){
Airium 0:7864abfabe2f 166 data[0] = CRB_REG_M;
Airium 0:7864abfabe2f 167 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 168 i2c.read(MAG_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 169 data[1] = data[1] & (0b00011111) | (cmd<<5);
Airium 0:7864abfabe2f 170 i2c.write(MAG_ADDRESS, data, 2);
Airium 0:7864abfabe2f 171 }
Airium 0:7864abfabe2f 172
Airium 0:7864abfabe2f 173 void LSM303DLHC::MCtrl(MAG_MD cmd){
Airium 0:7864abfabe2f 174 data[0] = MR_REG_M;
Airium 0:7864abfabe2f 175 i2c.write(MAG_ADDRESS, data, 1);
Airium 0:7864abfabe2f 176 i2c.read(MAG_ADDRESS, &data[1], 1);
Airium 0:7864abfabe2f 177 data[1] = data[1] & (0b11111100) | (cmd<<0);
Airium 0:7864abfabe2f 178 i2c.write(MAG_ADDRESS, data, 2);
Airium 0:7864abfabe2f 179 }
Airium 0:7864abfabe2f 180
Airium 0:7864abfabe2f 181 void LSM303DLHC::WriteReg(int sad, char d[2]){
Airium 0:7864abfabe2f 182 i2c.write(sad, d, 2);
Airium 0:7864abfabe2f 183 }
Airium 0:7864abfabe2f 184
Airium 3:522d01930e6a 185 void LSM303DLHC::ACal(float offset[3], float scale[3]){
Airium 0:7864abfabe2f 186 acc_offset[0] = offset[0];
Airium 0:7864abfabe2f 187 acc_offset[1] = offset[1];
Airium 0:7864abfabe2f 188 acc_offset[2] = offset[2];
Airium 0:7864abfabe2f 189 acc_scale[0] = scale[0];
Airium 0:7864abfabe2f 190 acc_scale[1] = scale[1];
Airium 0:7864abfabe2f 191 acc_scale[2] = scale[2];
Airium 0:7864abfabe2f 192 }
Airium 0:7864abfabe2f 193
Airium 3:522d01930e6a 194 void LSM303DLHC::MCal(float offset[3], float scale[3]){
Airium 0:7864abfabe2f 195 mag_offset[0] = offset[0];
Airium 0:7864abfabe2f 196 mag_offset[1] = offset[1];
Airium 0:7864abfabe2f 197 mag_offset[2] = offset[2];
Airium 0:7864abfabe2f 198 mag_scale[0] = scale[0];
Airium 0:7864abfabe2f 199 mag_scale[1] = scale[1];
Airium 0:7864abfabe2f 200 mag_scale[2] = scale[2];
Airium 0:7864abfabe2f 201 }
Airium 0:7864abfabe2f 202
Airium 3:522d01930e6a 203 void LSM303DLHC::TCal(float offset[1], float scale[1]){
Airium 0:7864abfabe2f 204 temp_offset[0] = offset[0];
Airium 0:7864abfabe2f 205 temp_scale[0] = scale[0];
Airium 0:7864abfabe2f 206 }
Airium 0:7864abfabe2f 207
Airium 0:7864abfabe2f 208 bool LSM303DLHC::isHPFEn(){
Airium 0:7864abfabe2f 209 return HPF_state;
Airium 0:7864abfabe2f 210 }