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:
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?

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 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 }