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

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