Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: LSM303DLHC.h
- Revision:
- 0:a4131de4bddd
- Child:
- 1:4ee6df2df73a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/LSM303DLHC.h Fri Jan 24 16:06:24 2020 +0000
@@ -0,0 +1,228 @@
+/* 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
+
+-- 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"
+#include "LSM303DLHC_REG.h"
+
+class LSM303DLHC {
+ public:
+ //// PORT
+ LSM303DLHC(I2C &i2c);
+
+ //// REG CTRL
+ // modify the default in LSM303DLHC.cpp
+
+ //// CTRL_REG1_A (20h)
+ // ACC Low Power Mode ON/OFF
+ 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, 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 };
+ void ACtrl(ACC_AXIS cmd);
+
+ //// CTRL_REG2_A (21h)
+ // ACC HPF Mode
+ enum ACC_HPM { HPF_NORM_R = 0, HPF_REF = 1, HPF_NORM = 2, HPF_AUTO = 3 };
+ void ACtrl(ACC_HPM cmd);
+ // ACC HPF Cutoff Freq
+ enum ACC_HPCF { HPF_CF0 = 0, HPF_CF1 = 1, HPF_CF2 = 2, HPF_CF3 = 3};
+ void ACtrl(ACC_HPCF cmd);
+ // ACC HPF ON/OFF for output
+ enum ACC_FDS { HPF_OFF = 0, HPF_ON = 1 };
+ void ACtrl(ACC_FDS cmd);
+
+ //// CTRL_REG4_A (23h)
+ // ACC Block Date Update Mode
+ enum ACC_BDU { BDU_CONT = 0, BDU_HOLD = 1 };
+ void ACtrl(ACC_BDU cmd);
+ // ACC Output Full-Scale SEL
+ enum ACC_FS {G2 = 0b00, G4 = 0b01, G8 = 0b10, G16= 0b11 };
+ // +/-2g +/-4g +/-8g +/-16g
+ void ACtrl(ACC_FS cmd);
+ // ACC Output in High/Low Resolution (Precision SEL)
+ enum ACC_HR { LOW_R = 0, HIGH_R = 1 };
+ // 10bit 12bit
+ void ACtrl(ACC_HR cmd);
+
+ //// CRA_REG_M (00h)
+ // TEMP Sensor En NOTE: TEMP SWITCH IS HERE
+ 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 { 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, 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)
+ // MAG Mode NOTE: MAG SWITCH IS HERE
+ enum MAG_MD { MD_CONT = 0, MD_SING = 1, MD_SLP = 2, MD_SLP2 = 3};
+ // Continuous single-conv sleep-mode sleep-mode
+ void MCtrl(MAG_MD cmd);
+
+ //// Change more regs
+ void WriteReg(int sad, char d[2]); // Write value to reg
+ // 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
+
+ //// Get Data
+ // 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
+ // 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
+
+
+ //// Not implemented function
+ 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
+
+ // use offset to calibrate zero reading
+ float acc_offset[3];
+ float mag_offset[3];
+ float temp_offset[1];
+
+ //use scale to adjust the range to required
+ float acc_scale[3];
+ float mag_scale[3];
+ float temp_scale[1];
+
+ // chip count to unit conversion
+ float acc_scale_multiplier;
+ float mag_scale_x_multiplier;
+ float mag_scale_y_multiplier;
+ float mag_scale_z_multiplier;
+};
+
+/*
+Original main.c
+
+#include "mbed.h"
+#include "LSM303DLHC.h"
+
+// LSM303DLHC sensor(p9,p10);
+
+Serial pc(USBTX,USBRX);
+Ticker ticker;
+
+float acc[3] = { 0 };
+float mag[3] = { 0 };
+float tmp[1] = { 0 };
+
+void CallBack();
+
+int main(){
+ pc.baud(921600);
+
+ // example setup
+ // refer to LSM303DLHC.h for more overloaded details for ACtrl() MCtrl() TCtrl()
+ sensor.MCtrl(LSM303DLHC::GN1); // set mag range +/-1.3Gausee
+ sensor.MCtrl(LSM303DLHC::MDR3); // set mag date rate 7.5Hz
+ sensor.ACtrl(LSM303DLHC::G8); // set acc range +/-8g
+ sensor.ACtrl(LSM303DLHC::ADR2); // set acc date rate 10Hz
+ sensor.ACtrl(LSM303DLHC::HPF_OFF); // disable internal acc HPF
+
+ float acc_offset[3] = { 6.5, 5, 12.5 }; // acc offset
+ float acc_scale[3] = { 3.9, 4, 4 }; // acc scale
+ sensor.ACal(acc_offset,acc_scale); // set acc calibration
+
+ ticker.attach(&CallBack, 0.2); // read and refresh disp with 200ms interval
+
+ while (1)
+ wait_us(1);
+}
+
+void CallBack(){
+ sensor.GetAcc(acc);
+ sensor.GetMag(mag);
+ sensor.GetTemp(tmp);
+
+ pc.printf("A %5f %5f %5f\n\r", acc[0], acc[1], acc[2]);
+ pc.printf("M %5f %5f %5f\n\r", mag[0], mag[1], mag[2]);
+ pc.printf("T %5f\n\r", tmp[0]);
+}
+
+*/
+
+
+#endif
\ No newline at end of file