Code for Technion Formula car sensors reader
Dependencies: mbed Buffer FATFileSystem
Fork of SX1272PingPong by
This is code is part of a Technion course project in advanced IoT, implementing a device to read and transmit sensors data from a Formula racing car built by students at Technion - Israel Institute of Technology.
How to install
- Create an account on Mbed: https://os.mbed.com/account/signup/
- Import project into Compiler
- In the Program Workspace select "Formula_Nucleo_Reader"
- Select a Platform like so:
- Click button at top-left
- Add Board
- Search "NUCLEO F103RB" and then "Add to your Mbed Compiler"
- Finally click "Compile", if the build was successful, the binary would download automatically
- To install it on device simply plug it in to a PC, open device drive and drag then drop binary file in it
Diff: LSM303DLHC/LSM303DLHC.h
- Revision:
- 15:2e0d977dbb31
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LSM303DLHC/LSM303DLHC.h Thu May 17 20:37:41 2018 +0000 @@ -0,0 +1,171 @@ +/* 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(PinName sda, PinName scl); + + //// 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]; +}; + +#endif \ No newline at end of file