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);
Diff: LSM303DLHC.h
- Revision:
- 3:522d01930e6a
- Parent:
- 2:192a6c228644
- Child:
- 4:8723c07d4c45
--- a/LSM303DLHC.h Tue Jun 07 06:25:44 2016 +0000 +++ b/LSM303DLHC.h Tue Jun 07 15:18:48 2016 +0000 @@ -1,61 +1,64 @@ +/* COMPACT USER INSTRUCTION OF LSM303DLHC + +-- ACCELEROMETER PART +void GetAcc( float arr[3] ) // Get Acceleration Value + arr[3] is the xyz-axis acc data + // default range from -2048 to +2047 with step=1 (12bit high prec) or step=4 (10bit normal prec) + // and roughly 1000/g(+/-2g) 500/g(+/-4g) 200/g(+/-8g) 80/g(+/-16g) depend on your device and ACC_FS + // note your calibration setting will change the range +void ACtrl( enum cmd ) e.g. ACtrl(LSM303DLHC::LP_ON) + enum ACC_LPen {LP_OFF,LP_ON} // to ctrl acc power mode + enum ACC_ODR {PW_D,ADR1,ADR2,ADR3,ADR4,ADR5,ADR6,ADR7,ADR8,ADR9} // to ctrl acc data rate + enum ACC_AXIS {NONE,X,Y,XY,Z,XZ,YZ,XYZ} // to sel the acc data of axis you want + enum ACC_HPM {HPF_NORM_R,HPF_REF,HPF_NORM,HPF_AUTO} // to sel acc internal HPF model + enum ACC_HPCF {HPF_CF0,HPF_CF1,HPF_CF2,HPF_CF3} // to switch acc internal HPF cutoff freq + enum ACC_FDS {HPF_OFF,HPF_ON} // to switch on/off acc internal HPF for output + enum ACC_BDU {BDU_CONT,BDU_HOLD} // to sel acc data update mode + enum ACC_FS {G2,G4,G8,G16} // to sel acc full scale of data + enum ACC_HR {LOW_R,HIGH_R} // to sel acc output data precision +void ACal( float offset[3], float scale[3] ); // Acc Calibration Setting + // affect data of GetAcc() by output = scale * ( offset + original ) + // but if internal HPF enable then output = scale * original + // note linear acc has no offset +bool isHPFEn(); // report HPF ON/OFF state for output + return bool = true if ACC_FDS = HPF_ON and vice versa + +-- MAGNETOMETER PART +void GetMag( float arr[3] ); // Get magnetic flux density + arr[3] is the xyz-axis mag data + // default range from -2048 to +2047 with step=1 + // note your calibration setting will change the range +void MCtrl( enum cmd ) e.g. MCtrl(LSM303DLHC::MDR3); + enum MAG_DR {MDR0,MDR1,MDR2,MDR3,MDR4,MDR5,MDR6,MDR7} // to ctrl mag data rate + enum MAG_GN {GN1,GN2,GN3,GN4,GN5,GN6,GN7) // to ctrl mag full scale of data + enum MAG_MD {MD_CONT,MD_SING,MD_SLP,MD_SLP2}; +void MCal(float offset[3], float scale[3]); // Mag Calibration + // affect data of GetMag() by output = scale * ( offset + original ) + +-- TEMPERATURE METER PART +void GetTemp( float arr[1] ); // Get temperature + arr[1] is the temperture + // default range from -2048 to +2047 +void TCal( enum cmd ) + enum TEMP_EN{TEMP_OFF,TEMP_ON}; // to switch on/off TEMP +void TempCal(float offset[1], float scale[1]); // Mag Calibration + //affect data of GetMag() by output = scale * ( offset + original ) + +-- DIRECT WRITE REG +void WriteReg(int sad, char d[2]); // Write value to reg + sad = ACC_ADDRESS or MAG_ADDRESS + d[0] = Register Address + d[1] = Register Value + CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN + CAUTION: WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE + PLEASE FOLLOW DATASHEET RIGIDLY +*/ + + #ifndef LSM303DLHC_H #define LSM303DLHC_H #include "mbed.h" -// ACC SAD -#define ACC_ADDRESS 0x32 -// ACC CTRL SUB -#define CTRL_REG1_A 0x20 //RW ODR(4) LPen Zen Yen Xen -#define CTRL_REG2_A 0x21 //RW HPM(2) HPCF(2) FDS HPCLICK HPIS2 HPIS1 -#define CTRL_REG3_A 0x22 //RW I1_CLICK I1_AOI1 I1_AOI2 I1_DRDY1 I1_DRDY2 I1_WTM I1_OVERRUN - -#define CTRL_REG4_A 0x23 //RW BDU BLE FS1 FS0 HR 0(2) SIM -#define CTRL_REG5_A 0x24 //RW BOOT FIFO_EN - - LIR_INT1 D4D_INT1 LIR_INT2 D4D_INT2 -#define CTRL_REG6_A 0x25 //RW I2_CLICKen I2_INT1 I2_INT2 BOOT_I1 P2_ACT - H_LACTIVE - -#define REFERENCE_A 0x26 //RW Ref7 Ref6 Ref5 Ref4 Ref3 Ref2 Ref1 Ref0 -#define STATUS_REG_A 0x27 //R ZYXOR ZOR YOR XOR ZYXDA ZDA YDA XDA -// ACC OUT SUB -#define OUT_X_L_A 0x28 //R MSB(8) -#define OUT_X_H_A 0x29 //R LSB(4) 0(4) -#define OUT_Y_L_A 0x2A //R ditto -#define OUT_Y_H_A 0x2B //R ditto -#define OUT_Z_L_A 0x2C //R ditto -#define OUT_Z_H_A 0x2D //R ditto -// ACC INT SUB -#define INT1_CFG_A 0x30 -#define INT1_SRC_A 0x31 -#define INT1_THS_A 0x32 -#define INT1_DURATION_A 0x33 -#define INT2_CFG_A 0x34 -#define INT2_SRC_A 0x35 -#define INT2_THS_A 0x36 -#define INT2_DURATION_A 0x37 -// ACC CLICK SUB -#define CLICK_CFG_A 0x38 -#define CLICK_SRC_A 0x39 -#define CLICK_THS_A 0x3A -#define TIME_LIMIT_A 0x3B -#define TIME_LATENCY_A 0x3C -#define TIME_WINDOW_A 0x3D - -// MAG SAD -#define MAG_ADDRESS 0x3C -// MAG CTRL SUB -#define CRA_REG_M 0x00 //RW TEMP_EN 0(2) DR(3) 0(2) -#define CRB_REG_M 0x01 //RW GN(3) 0(5) -#define MR_REG_M 0x02 //RW 0(6) MD(2) -// MAG OUT SUB -#define OUT_X_H_M 0x03 //R LSB(8) -#define OUT_X_L_M 0x04 //R 0(4) MSB(4) -#define OUT_Z_H_M 0x05 //R ditto -#define OUT_Z_L_M 0x06 //R ditto -#define OUT_Y_H_M 0x07 //R ditto -#define OUT_Y_L_M 0x08 //R ditto -#define SR_REG_M 0x09 //R -(6) LOCK DRDY -#define IRA_REG_M 0x0A //R -#define IRB_REG_M 0x0B //R -#define IRC_REG_M 0x0C //R -// Temprature OUT SUB -#define TEMP_OUT_H_M 0x31 //R MSB(8) -#define TEMP_OUT_L_M 0x32 //R LSB(4) 0(4) +#include "LSM303DLHC_REG.h" class LSM303DLHC { public: @@ -70,10 +73,8 @@ enum ACC_LPen { LP_OFF = 0, LP_ON = 1} ; void ACtrl(ACC_LPen cmd); // ACC Data Rate NOTE: ACC SWITCH IS HERE - enum ACC_ODR { PW_D = 0, ODR1 = 1, ODR2 = 2, ODR3 = 3, ODR4 = 4, - // PW Down 1Hz 10Hz 25Hz 50Hz - ODR5 = 5, ODR6 = 6, ODR7 = 7, ODR8 = 8, ODR9 = 9}; - // 100Hz 200Hz 400Hz 1620Hz@LP 1344Hz@NM/5376HZ@LP + enum ACC_ODR { PW_D = 0, ADR1 = 1, ADR2 = 2, ADR3 = 3, ADR4 = 4, ADR5 = 5, ADR6 = 6, ADR7 = 7, ADR8 = 8, ADR9 = 9}; + // PW Down 1Hz 10Hz 25Hz 50Hz 100Hz 200Hz 400Hz 1620Hz@LP 1344Hz@NM/5376HZ@LP void ACtrl(ACC_ODR cmd); // ACC AXIS SEL enum ACC_AXIS { NONE = 0, X = 1, Y = 2, XY = 3, Z = 4, XZ = 5, YZ = 6, XYZ = 7 }; @@ -108,18 +109,14 @@ enum TEMP_EN { TEMP_OFF = 0, TEMP_ON = 1}; void TCtrl(TEMP_EN cmd); // MAG Data Rate (Note: MAG_DR determines DRDY pin) - enum MAG_DR { DR0 = 0, DR1 = 1, DR2 = 2, DR3 = 3, - // 0.75Hz 1.5Hz 3Hz 7.5Hz - DR4 = 4, DR5 = 5, DR6 = 6, DR7 = 7}; - // 15Hz 30Hz 75Hz 220Hz + enum MAG_DR { MDR0 = 0, MDR1 = 1, MDR2 = 2, MDR3 = 3, MDR4 = 4, MDR5 = 5, MDR6 = 6, MDR7 = 7}; + // 0.75Hz 1.5Hz 3Hz 7.5Hz 15Hz 30Hz 75Hz 220Hz void MCtrl(MAG_DR cmd); // MAG Date Rate //// CRB_REG_M (01h) // MAG Gain (Range SEL) - enum MAG_GN { GN1 = 1, GN2 = 2, GN3 = 3, GN4 = 4, - // 1.3 1.9 2.5 4.0 (+/- Gauss) - GN5 = 5, GN6 = 6, GN7 = 7}; - // 4.7 5.6 8.1 (+/- Gauss) + enum MAG_GN { GN1 = 1, GN2 = 2, GN3 = 3, GN4 = 4, GN5 = 5, GN6 = 6, GN7 = 7}; + // 1.3 1.9 2.5 4.0 4.7 5.6 8.1 (+/- Gauss) void MCtrl(MAG_GN cmd); // MAG Measure Range //// MR_REG_M (02h) @@ -130,29 +127,22 @@ //// Change more regs void WriteReg(int sad, char d[2]); // Write value to reg - // CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN - // CAUTION: WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE + // sad = ACC_ADDRESS or MAG_ADDRESS + // d[0] = Register Address and d[1] = Register Value + // CAUTION: THE FUNTION USES UNFRIENDLY ASSIGN AND WRITING TO RESERVED REG MAY CAUSE PERMANENT DAMAGE // PLEASE FOLLOW DATASHEET RIGIDLY - // sad = ACC_ADDRESS or MAG_ADDRESS - // d[0] = Register Address - // d[1] = Register Value //// Get Data - void GetAcc(float arr[3]); // Get acceleration using current HPF setting - // range -2048 ~ +2047 - void GetMag(float arr[3]); // Get magnetic flux density - // range -2048 to 2047 - void GetTemp(float arr[1]); // Get temperature - // range -2048 to 2047 + // please refer to the top: COMPACT USER INSTRUCTION + void GetAcc(float arr[3]); // Get acc + void GetMag(float arr[3]); // Get mag + void GetTemp(float arr[1]); // Get temp - //// sensor reading calibration - void AccCal(float offset[3], float scale[3]); // Acc Calibration - // affect the reading by output = scale * ( offset + original ) - // but if internal HPF enable then output = scale * original - void MagCal(float offset[3], float scale[3]); // Mag Calibration - // affect the reading by output = scale * ( offset + original ) - void TempCal(float offset[1], float scale[1]); // Mag Calibration - // affect the reading by output = scale * ( offset + original ) + //// sensor reading calibration + // please refer to the top: COMPACT USER INSTRUCTION + void ACal(float offset[3], float scale[3]); // Acc Calibration + void MCal(float offset[3], float scale[3]); // Mag Calibration + void TCal(float offset[1], float scale[1]); // Mag Calibration //// Other functions bool isHPFEn(); // report HPF ON/OFF state for output @@ -162,12 +152,14 @@ bool isAccRdy(); // Check if acc has new data // one way is to use high freq ticker to check STATUS_REG_A (27h) // I2C@400kHz just enough to check Max Normal Mode Data Rate (1344Hz) + // or someone to teach me how to use CTRL_REG6_A THX THX THX (: bool isMagRdy(); // check if mag has new data // one way is to use InterruptIn to trigger from DRDY pin // DRDY pin freq defined by MAG_DR private: I2C i2c; + char data[6]; // used as main data exchange bool HPF_state; // state of internal HPF