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 06:20:17 2016 +0000
Revision:
1:e68ce5025dad
Parent:
0:7864abfabe2f
Child:
3:522d01930e6a
Add Accelerometer Axis Sel to ACtrl() Method Overloaded

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