Based on https://os.mbed.com/users/Airium/code/module_LSM303DLHC/ Main difference is the usage of the I2C - now it is passed as parameter making cooperative use easier. 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);

Committer:
Pythia
Date:
Mon Feb 03 07:43:48 2020 +0000
Revision:
1:4ee6df2df73a
Parent:
0:a4131de4bddd
Version working. Temperature sensor provide strange results. Is to be extended with orientation measurement.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pythia 0:a4131de4bddd 1 /* COMPACT USER INSTRUCTION OF LSM303DLHC
Pythia 0:a4131de4bddd 2
Pythia 0:a4131de4bddd 3 -- ACCELEROMETER PART
Pythia 0:a4131de4bddd 4 void GetAcc( float arr[3] ) // Get Acceleration Value
Pythia 0:a4131de4bddd 5 arr[3] is the xyz-axis acc data
Pythia 0:a4131de4bddd 6 // default range from -2048 to +2047 with step=1 (12bit high prec) or step=4 (10bit normal prec)
Pythia 0:a4131de4bddd 7 // and roughly 1000/g(+/-2g) 500/g(+/-4g) 200/g(+/-8g) 80/g(+/-16g) depend on your device and ACC_FS
Pythia 0:a4131de4bddd 8 // note your calibration setting will change the range
Pythia 0:a4131de4bddd 9 void ACtrl( enum cmd ) e.g. ACtrl(LSM303DLHC::LP_ON)
Pythia 0:a4131de4bddd 10 enum ACC_LPen {LP_OFF,LP_ON} // to ctrl acc power mode
Pythia 0:a4131de4bddd 11 enum ACC_ODR {PW_D,ADR1,ADR2,ADR3,ADR4,ADR5,ADR6,ADR7,ADR8,ADR9} // to ctrl acc data rate
Pythia 0:a4131de4bddd 12 enum ACC_AXIS {NONE,X,Y,XY,Z,XZ,YZ,XYZ} // to sel the acc data of axis you want
Pythia 0:a4131de4bddd 13 enum ACC_HPM {HPF_NORM_R,HPF_REF,HPF_NORM,HPF_AUTO} // to sel acc internal HPF model
Pythia 0:a4131de4bddd 14 enum ACC_HPCF {HPF_CF0,HPF_CF1,HPF_CF2,HPF_CF3} // to switch acc internal HPF cutoff freq
Pythia 0:a4131de4bddd 15 enum ACC_FDS {HPF_OFF,HPF_ON} // to switch on/off acc internal HPF for output
Pythia 0:a4131de4bddd 16 enum ACC_BDU {BDU_CONT,BDU_HOLD} // to sel acc data update mode
Pythia 0:a4131de4bddd 17 enum ACC_FS {G2,G4,G8,G16} // to sel acc full scale of data
Pythia 0:a4131de4bddd 18 enum ACC_HR {LOW_R,HIGH_R} // to sel acc output data precision
Pythia 0:a4131de4bddd 19 void ACal( float offset[3], float scale[3] ); // Acc Calibration Setting
Pythia 0:a4131de4bddd 20 // affect data of GetAcc() by output = scale * ( offset + original )
Pythia 0:a4131de4bddd 21 // but if internal HPF enable then output = scale * original
Pythia 0:a4131de4bddd 22 // note linear acc has no offset
Pythia 0:a4131de4bddd 23
Pythia 0:a4131de4bddd 24 -- MAGNETOMETER PART
Pythia 0:a4131de4bddd 25 void GetMag( float arr[3] ); // Get magnetic flux density
Pythia 0:a4131de4bddd 26 arr[3] is the xyz-axis mag data
Pythia 0:a4131de4bddd 27 // default range from -2048 to +2047 with step=1
Pythia 0:a4131de4bddd 28 // note your calibration setting will change the range
Pythia 0:a4131de4bddd 29 void MCtrl( enum cmd ) e.g. MCtrl(LSM303DLHC::MDR3);
Pythia 0:a4131de4bddd 30 enum MAG_DR {MDR0,MDR1,MDR2,MDR3,MDR4,MDR5,MDR6,MDR7} // to ctrl mag data rate
Pythia 0:a4131de4bddd 31 enum MAG_GN {GN1,GN2,GN3,GN4,GN5,GN6,GN7) // to ctrl mag full scale of data
Pythia 0:a4131de4bddd 32 enum MAG_MD {MD_CONT,MD_SING,MD_SLP,MD_SLP2};
Pythia 0:a4131de4bddd 33 void MCal(float offset[3], float scale[3]); // Mag Calibration
Pythia 0:a4131de4bddd 34 // affect data of GetMag() by output = scale * ( offset + original )
Pythia 0:a4131de4bddd 35
Pythia 0:a4131de4bddd 36 -- TEMPERATURE METER PART
Pythia 0:a4131de4bddd 37 void GetTemp( float arr[1] ); // Get temperature
Pythia 0:a4131de4bddd 38 arr[1] is the temperture
Pythia 0:a4131de4bddd 39 // default range from -2048 to +2047
Pythia 0:a4131de4bddd 40 void TCal( enum cmd )
Pythia 0:a4131de4bddd 41 enum TEMP_EN{TEMP_OFF,TEMP_ON}; // to switch on/off TEMP
Pythia 0:a4131de4bddd 42 void TempCal(float offset[1], float scale[1]); // Mag Calibration
Pythia 0:a4131de4bddd 43 //affect data of GetMag() by output = scale * ( offset + original )
Pythia 0:a4131de4bddd 44
Pythia 0:a4131de4bddd 45 -- DIRECT WRITE REG
Pythia 0:a4131de4bddd 46 void WriteReg(int sad, char d[2]); // Write value to reg
Pythia 0:a4131de4bddd 47 sad = ACC_ADDRESS or MAG_ADDRESS
Pythia 0:a4131de4bddd 48 d[0] = Register Address
Pythia 0:a4131de4bddd 49 d[1] = Register Value
Pythia 0:a4131de4bddd 50 CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN
Pythia 0:a4131de4bddd 51 CAUTION: WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE
Pythia 0:a4131de4bddd 52 PLEASE FOLLOW DATASHEET RIGIDLY
Pythia 0:a4131de4bddd 53 */
Pythia 0:a4131de4bddd 54
Pythia 0:a4131de4bddd 55
Pythia 0:a4131de4bddd 56 #ifndef LSM303DLHC_H
Pythia 0:a4131de4bddd 57 #define LSM303DLHC_H
Pythia 0:a4131de4bddd 58 #include "mbed.h"
Pythia 0:a4131de4bddd 59 #include "LSM303DLHC_REG.h"
Pythia 0:a4131de4bddd 60
Pythia 0:a4131de4bddd 61 class LSM303DLHC {
Pythia 0:a4131de4bddd 62 public:
Pythia 0:a4131de4bddd 63 //// PORT
Pythia 0:a4131de4bddd 64 LSM303DLHC(I2C &i2c);
Pythia 0:a4131de4bddd 65
Pythia 0:a4131de4bddd 66 //// REG CTRL
Pythia 0:a4131de4bddd 67 // modify the default in LSM303DLHC.cpp
Pythia 0:a4131de4bddd 68
Pythia 0:a4131de4bddd 69 //// CTRL_REG1_A (20h)
Pythia 0:a4131de4bddd 70 // ACC Low Power Mode ON/OFF
Pythia 0:a4131de4bddd 71 enum ACC_LPen { LP_OFF = 0, LP_ON = 1} ;
Pythia 0:a4131de4bddd 72 void ACtrl(ACC_LPen cmd);
Pythia 0:a4131de4bddd 73 // ACC Data Rate NOTE: ACC SWITCH IS HERE
Pythia 0:a4131de4bddd 74 enum ACC_ODR { PW_D = 0, ADR1 = 1, ADR2 = 2, ADR3 = 3, ADR4 = 4, ADR5 = 5, ADR6 = 6, ADR7 = 7, ADR8 = 8, ADR9 = 9};
Pythia 0:a4131de4bddd 75 // PW Down 1Hz 10Hz 25Hz 50Hz 100Hz 200Hz 400Hz 1620Hz@LP 1344Hz@NM/5376HZ@LP
Pythia 0:a4131de4bddd 76 void ACtrl(ACC_ODR cmd);
Pythia 0:a4131de4bddd 77 // ACC AXIS SEL
Pythia 0:a4131de4bddd 78 enum ACC_AXIS { NONE = 0, X = 1, Y = 2, XY = 3, Z = 4, XZ = 5, YZ = 6, XYZ = 7 };
Pythia 0:a4131de4bddd 79 void ACtrl(ACC_AXIS cmd);
Pythia 0:a4131de4bddd 80
Pythia 0:a4131de4bddd 81 //// CTRL_REG2_A (21h)
Pythia 0:a4131de4bddd 82 // ACC HPF Mode
Pythia 0:a4131de4bddd 83 enum ACC_HPM { HPF_NORM_R = 0, HPF_REF = 1, HPF_NORM = 2, HPF_AUTO = 3 };
Pythia 0:a4131de4bddd 84 void ACtrl(ACC_HPM cmd);
Pythia 0:a4131de4bddd 85 // ACC HPF Cutoff Freq
Pythia 0:a4131de4bddd 86 enum ACC_HPCF { HPF_CF0 = 0, HPF_CF1 = 1, HPF_CF2 = 2, HPF_CF3 = 3};
Pythia 0:a4131de4bddd 87 void ACtrl(ACC_HPCF cmd);
Pythia 0:a4131de4bddd 88 // ACC HPF ON/OFF for output
Pythia 0:a4131de4bddd 89 enum ACC_FDS { HPF_OFF = 0, HPF_ON = 1 };
Pythia 0:a4131de4bddd 90 void ACtrl(ACC_FDS cmd);
Pythia 0:a4131de4bddd 91
Pythia 0:a4131de4bddd 92 //// CTRL_REG4_A (23h)
Pythia 0:a4131de4bddd 93 // ACC Block Date Update Mode
Pythia 0:a4131de4bddd 94 enum ACC_BDU { BDU_CONT = 0, BDU_HOLD = 1 };
Pythia 0:a4131de4bddd 95 void ACtrl(ACC_BDU cmd);
Pythia 0:a4131de4bddd 96 // ACC Output Full-Scale SEL
Pythia 0:a4131de4bddd 97 enum ACC_FS {G2 = 0b00, G4 = 0b01, G8 = 0b10, G16= 0b11 };
Pythia 0:a4131de4bddd 98 // +/-2g +/-4g +/-8g +/-16g
Pythia 0:a4131de4bddd 99 void ACtrl(ACC_FS cmd);
Pythia 0:a4131de4bddd 100 // ACC Output in High/Low Resolution (Precision SEL)
Pythia 0:a4131de4bddd 101 enum ACC_HR { LOW_R = 0, HIGH_R = 1 };
Pythia 0:a4131de4bddd 102 // 10bit 12bit
Pythia 0:a4131de4bddd 103 void ACtrl(ACC_HR cmd);
Pythia 0:a4131de4bddd 104
Pythia 0:a4131de4bddd 105 //// CRA_REG_M (00h)
Pythia 0:a4131de4bddd 106 // TEMP Sensor En NOTE: TEMP SWITCH IS HERE
Pythia 0:a4131de4bddd 107 enum TEMP_EN { TEMP_OFF = 0, TEMP_ON = 1};
Pythia 0:a4131de4bddd 108 void TCtrl(TEMP_EN cmd);
Pythia 0:a4131de4bddd 109 // MAG Data Rate (Note: MAG_DR determines DRDY pin)
Pythia 0:a4131de4bddd 110 enum MAG_DR { MDR0 = 0, MDR1 = 1, MDR2 = 2, MDR3 = 3, MDR4 = 4, MDR5 = 5, MDR6 = 6, MDR7 = 7};
Pythia 0:a4131de4bddd 111 // 0.75Hz 1.5Hz 3Hz 7.5Hz 15Hz 30Hz 75Hz 220Hz
Pythia 0:a4131de4bddd 112 void MCtrl(MAG_DR cmd); // MAG Date Rate
Pythia 0:a4131de4bddd 113
Pythia 0:a4131de4bddd 114 //// CRB_REG_M (01h)
Pythia 0:a4131de4bddd 115 // MAG Gain (Range SEL)
Pythia 0:a4131de4bddd 116 enum MAG_GN { GN1 = 1, GN2 = 2, GN3 = 3, GN4 = 4, GN5 = 5, GN6 = 6, GN7 = 7};
Pythia 0:a4131de4bddd 117 // 1.3 1.9 2.5 4.0 4.7 5.6 8.1 (+/- Gauss)
Pythia 0:a4131de4bddd 118 void MCtrl(MAG_GN cmd); // MAG Measure Range
Pythia 0:a4131de4bddd 119
Pythia 0:a4131de4bddd 120 //// MR_REG_M (02h)
Pythia 0:a4131de4bddd 121 // MAG Mode NOTE: MAG SWITCH IS HERE
Pythia 0:a4131de4bddd 122 enum MAG_MD { MD_CONT = 0, MD_SING = 1, MD_SLP = 2, MD_SLP2 = 3};
Pythia 0:a4131de4bddd 123 // Continuous single-conv sleep-mode sleep-mode
Pythia 0:a4131de4bddd 124 void MCtrl(MAG_MD cmd);
Pythia 0:a4131de4bddd 125
Pythia 0:a4131de4bddd 126 //// Change more regs
Pythia 0:a4131de4bddd 127 void WriteReg(int sad, char d[2]); // Write value to reg
Pythia 0:a4131de4bddd 128 // sad = ACC_ADDRESS or MAG_ADDRESS
Pythia 0:a4131de4bddd 129 // d[0] = Register Address and d[1] = Register Value
Pythia 0:a4131de4bddd 130 // CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN AND WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE
Pythia 0:a4131de4bddd 131 // PLEASE FOLLOW DATASHEET RIGIDLY
Pythia 0:a4131de4bddd 132
Pythia 0:a4131de4bddd 133 //// Get Data
Pythia 0:a4131de4bddd 134 // please refer to the top: COMPACT USER INSTRUCTION
Pythia 1:4ee6df2df73a 135 int GetAcc(float arr[3]); // Get acc
Pythia 1:4ee6df2df73a 136 int GetMag(float arr[3]); // Get mag
Pythia 1:4ee6df2df73a 137 int GetTemp(float arr[1]); // Get temp
Pythia 0:a4131de4bddd 138
Pythia 0:a4131de4bddd 139 //// sensor reading calibration
Pythia 0:a4131de4bddd 140 // please refer to the top: COMPACT USER INSTRUCTION
Pythia 0:a4131de4bddd 141 void ACal(float offset[3], float scale[3]); // Acc Calibration
Pythia 0:a4131de4bddd 142 void MCal(float offset[3], float scale[3]); // Mag Calibration
Pythia 0:a4131de4bddd 143 void TCal(float offset[1], float scale[1]); // Mag Calibration
Pythia 0:a4131de4bddd 144
Pythia 0:a4131de4bddd 145
Pythia 0:a4131de4bddd 146 //// Not implemented function
Pythia 0:a4131de4bddd 147 bool isAccRdy(); // Check if acc has new data
Pythia 0:a4131de4bddd 148 // one way is to use high freq ticker to check STATUS_REG_A (27h)
Pythia 0:a4131de4bddd 149 // I2C@400kHz just enough to check Max Normal Mode Data Rate (1344Hz)
Pythia 0:a4131de4bddd 150 // or someone to teach me how to use CTRL_REG6_A THX THX THX (:
Pythia 0:a4131de4bddd 151 bool isMagRdy(); // check if mag has new data
Pythia 0:a4131de4bddd 152 // one way is to use InterruptIn to trigger from DRDY pin
Pythia 0:a4131de4bddd 153 // DRDY pin freq defined by MAG_DR
Pythia 0:a4131de4bddd 154
Pythia 0:a4131de4bddd 155 private:
Pythia 0:a4131de4bddd 156 I2C *_i2c;
Pythia 0:a4131de4bddd 157
Pythia 0:a4131de4bddd 158 char data[6]; // used as main data exchange
Pythia 0:a4131de4bddd 159
Pythia 0:a4131de4bddd 160 // use offset to calibrate zero reading
Pythia 0:a4131de4bddd 161 float acc_offset[3];
Pythia 0:a4131de4bddd 162 float mag_offset[3];
Pythia 0:a4131de4bddd 163 float temp_offset[1];
Pythia 0:a4131de4bddd 164
Pythia 0:a4131de4bddd 165 //use scale to adjust the range to required
Pythia 0:a4131de4bddd 166 float acc_scale[3];
Pythia 0:a4131de4bddd 167 float mag_scale[3];
Pythia 0:a4131de4bddd 168 float temp_scale[1];
Pythia 0:a4131de4bddd 169
Pythia 0:a4131de4bddd 170 // chip count to unit conversion
Pythia 0:a4131de4bddd 171 float acc_scale_multiplier;
Pythia 0:a4131de4bddd 172 float mag_scale_x_multiplier;
Pythia 0:a4131de4bddd 173 float mag_scale_y_multiplier;
Pythia 0:a4131de4bddd 174 float mag_scale_z_multiplier;
Pythia 0:a4131de4bddd 175 };
Pythia 0:a4131de4bddd 176
Pythia 0:a4131de4bddd 177 /*
Pythia 0:a4131de4bddd 178 Original main.c
Pythia 0:a4131de4bddd 179
Pythia 0:a4131de4bddd 180 #include "mbed.h"
Pythia 0:a4131de4bddd 181 #include "LSM303DLHC.h"
Pythia 0:a4131de4bddd 182
Pythia 0:a4131de4bddd 183 // LSM303DLHC sensor(p9,p10);
Pythia 0:a4131de4bddd 184
Pythia 0:a4131de4bddd 185 Serial pc(USBTX,USBRX);
Pythia 0:a4131de4bddd 186 Ticker ticker;
Pythia 0:a4131de4bddd 187
Pythia 0:a4131de4bddd 188 float acc[3] = { 0 };
Pythia 0:a4131de4bddd 189 float mag[3] = { 0 };
Pythia 0:a4131de4bddd 190 float tmp[1] = { 0 };
Pythia 0:a4131de4bddd 191
Pythia 0:a4131de4bddd 192 void CallBack();
Pythia 0:a4131de4bddd 193
Pythia 0:a4131de4bddd 194 int main(){
Pythia 0:a4131de4bddd 195 pc.baud(921600);
Pythia 0:a4131de4bddd 196
Pythia 0:a4131de4bddd 197 // example setup
Pythia 0:a4131de4bddd 198 // refer to LSM303DLHC.h for more overloaded details for ACtrl() MCtrl() TCtrl()
Pythia 0:a4131de4bddd 199 sensor.MCtrl(LSM303DLHC::GN1); // set mag range +/-1.3Gausee
Pythia 0:a4131de4bddd 200 sensor.MCtrl(LSM303DLHC::MDR3); // set mag date rate 7.5Hz
Pythia 0:a4131de4bddd 201 sensor.ACtrl(LSM303DLHC::G8); // set acc range +/-8g
Pythia 0:a4131de4bddd 202 sensor.ACtrl(LSM303DLHC::ADR2); // set acc date rate 10Hz
Pythia 0:a4131de4bddd 203 sensor.ACtrl(LSM303DLHC::HPF_OFF); // disable internal acc HPF
Pythia 0:a4131de4bddd 204
Pythia 0:a4131de4bddd 205 float acc_offset[3] = { 6.5, 5, 12.5 }; // acc offset
Pythia 0:a4131de4bddd 206 float acc_scale[3] = { 3.9, 4, 4 }; // acc scale
Pythia 0:a4131de4bddd 207 sensor.ACal(acc_offset,acc_scale); // set acc calibration
Pythia 0:a4131de4bddd 208
Pythia 0:a4131de4bddd 209 ticker.attach(&CallBack, 0.2); // read and refresh disp with 200ms interval
Pythia 0:a4131de4bddd 210
Pythia 0:a4131de4bddd 211 while (1)
Pythia 0:a4131de4bddd 212 wait_us(1);
Pythia 0:a4131de4bddd 213 }
Pythia 0:a4131de4bddd 214
Pythia 0:a4131de4bddd 215 void CallBack(){
Pythia 0:a4131de4bddd 216 sensor.GetAcc(acc);
Pythia 0:a4131de4bddd 217 sensor.GetMag(mag);
Pythia 0:a4131de4bddd 218 sensor.GetTemp(tmp);
Pythia 0:a4131de4bddd 219
Pythia 0:a4131de4bddd 220 pc.printf("A %5f %5f %5f\n\r", acc[0], acc[1], acc[2]);
Pythia 0:a4131de4bddd 221 pc.printf("M %5f %5f %5f\n\r", mag[0], mag[1], mag[2]);
Pythia 0:a4131de4bddd 222 pc.printf("T %5f\n\r", tmp[0]);
Pythia 0:a4131de4bddd 223 }
Pythia 0:a4131de4bddd 224
Pythia 0:a4131de4bddd 225 */
Pythia 0:a4131de4bddd 226
Pythia 0:a4131de4bddd 227
Pythia 0:a4131de4bddd 228 #endif