Code for Technion Formula car sensors reader

Dependencies:   mbed Buffer FATFileSystem

Fork of SX1272PingPong by Semtech

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:
  1. Click button at top-left
  2. Add Board
  3. 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
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