Contains necessary classes and functions for ELEC351

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

Revision:
2:e2b885367ba8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samplingMaster/samplingMaster.cpp	Wed Dec 27 15:28:20 2017 +0000
@@ -0,0 +1,135 @@
+#include "mbed.h"
+#include "samplingMaster.hpp"
+
+/* Spec said that we are not allowed to use any third party code unless it is
+from ARM or STmicroelectronics, so I wrote my own driver for sampling BMP280 &
+ADC in succesion. Ths code for MPB280 was inspired by the BMP280 Datasheet:
+[https://cdn-shop.adafruit.com/datasheets/BST-BMP280-DS001-11.pdf]
+and BMP280 mbed library by "charlie":
+[https://os.mbed.com/users/CHARLY/code/BMP280/] */
+
+C_sensorData::C_sensorData()
+{
+
+    //********************************LDR ADC*********************************//
+    AnalogIn ldrADC(PA_0);      // Establish Analog In for ADC
+
+    //******************************BMP280 I2C********************************//
+    I2C sensorLink(D14, D15);   // Establish I2C comms
+
+    inst[0] = CONTROL_REGISTER; // Register address
+    inst[1] = 0b01101101;       // Temp x4, Pressure x4, Forced mode
+    sensorLink.write(I2C_adr, inst, 2);
+
+    inst[0] = Tsb_IIR_REGISTER; // Register address
+    inst[1] = 0x00;             // No standby, No IIR filter
+    sensorLink.write(I2C_adr, inst, 2);
+
+    inst[0] = DIG_Tn_REGISTERS; // Read trimming parameters instruction
+    sensorLink.write(I2C_adr, inst, 1);
+    sensorLink.read(I2C_adr, inst, 6);
+
+    /* For instructions how to decode trimming parameters please refer to the
+    BMP280 datasheet, page 21, chapter 3.11.2, table 17: "Compensation parameter
+    storage, naming and data type" */
+    T1Trim = (inst[1]<<8)|inst[0];
+    T2Trim = (inst[3]<<8)|inst[2];
+    T3Trim = (inst[5]<<8)|inst[4];
+
+    inst[0] = DIG_Pn_REGISTERS; // Read trimming parameters instruction
+    sensorLink.write(I2C_adr, inst, 1);
+    sensorLink.read(I2C_adr, inst, 18);
+
+    /* For instructions how to decode trimming parameters please refer to the
+    BMP280 datasheet, page 21, chapter 3.11.2, table 17: "Compensation parameter
+    storage, naming and data type" */
+    P1Trim = (inst[ 1]<<8)|inst[ 0];
+    P2Trim = (inst[ 3]<<8)|inst[ 2];
+    P3Trim = (inst[ 5]<<8)|inst[ 4];
+    P4Trim = (inst[ 7]<<8)|inst[ 6];
+    P5Trim = (inst[ 9]<<8)|inst[ 8];
+    P6Trim = (inst[11]<<8)|inst[10];
+    P7Trim = (inst[13]<<8)|inst[12];
+    P8Trim = (inst[15]<<8)|inst[14];
+    P9Trim = (inst[17]<<8)|inst[16];
+}
+
+TDS_sensorData C_sensorData::read()
+{
+    //*********************************SETUP**********************************//
+    TDS_sensorData sensorData;  // Type def struct to hold the data
+    AnalogIn ldrADC(PA_0);      // Establish Analog In for ADC
+    I2C sensorLink(D14, D15);   // Establish I2C comms
+
+    /* N.B in forced mode you must write to CONTROL_REGISTER to wake the IMU up.
+    It automaticly sleeps when measurments are aquired but leaves the registers
+    readable for the I2C link                                                 */
+    inst[0] = CONTROL_REGISTER; // Register address
+    inst[1] = 0b01101101;       // Temp x4, Pressure x4, Forced mode
+    sensorLink.write(I2C_adr, inst, 2);
+
+    //******************************TEMPERATURE*******************************//
+    inst[0] = TEMP_ADDRESS_VAL; // Start of temperature register
+    sensorLink.write(I2C_adr, inst, 1);
+    sensorLink.read(I2C_adr, &inst[1], 3);
+
+    tempT = (inst[1]<<12)|(inst[2]<<4)|(inst[3]>>4);
+    //             ^             ^            ^ 
+    //      MSB REGISTER  LSB REGISTER  X_LSB REGISTER
+
+    /* For instructions how to compensate values please refer to the
+    BMP280 datasheet, page 21 & 22, chapter 3.11.3, pseudo code */
+    tempA = ((((tempT>>3)-(T1Trim<<1)))*T2Trim)>>11;
+    tempB = (((((tempT>>4)-T1Trim)*((tempT>>4)-T1Trim))>>12)*T3Trim)>>14;
+    tempT = tempA+tempB;
+    sensorData.temp = ((float)((tempT * 5 + 128) >> 8))/100;
+
+    //********************************PRESURE********************************//
+    inst[0] = PRES_ADDRESS_VAL; // Start of presure register
+    sensorLink.write(I2C_adr, inst, 1);
+    sensorLink.read(I2C_adr, &inst[1], 3);
+
+    tempP = (inst[1]<<12)|(inst[2]<<4)|(inst[3]>>4);
+    //             ^             ^            ^ 
+    //      MSB REGISTER  LSB REGISTER  X_LSB REGISTER
+
+    /* For instructions how to compensate values please refer to the
+    BMP280 datasheet, page 21 & 22, chapter 3.11.3, pseudo code.
+
+    Please note that the compensation in the datasheet is done with 64 bit
+    signed values. However, "charlie's" BMP280 driver which does the
+    compensation using 32 bit signed values has inspired me to write my
+    compensation algorithm as follows. This makes the algorithm more efficient
+    without sacrifising relevant acuracy
+
+    N.B the pressure calculated by the following algorithm is in hPa which is
+    a newer unit with equivalence of: 1hPA = 1mbar*/
+
+    tempA = (tempT>>1)-64000;
+    tempB = (((tempA>>2)*(tempA>>2))>>11)*P6Trim;
+    tempB = tempB+((tempA*P5Trim)<<1);
+    tempB = (tempB>>2)+(P4Trim<<16);
+    tempA = (((P3Trim*(((tempA>>2)*(tempA>>2))>>13))>>3)+((P2Trim*tempA)>>1))>>18;
+    tempA = ((32768+tempA)*P1Trim)>>15;
+
+    if(tempA == 0) {
+        sensorData.pres = 0;
+    }
+    tempP = (((1048576-tempP)-(tempB>>12)))*3125; // Compensate for 64 bit loss
+    if(tempP < PREAS_UPER_LIMIT) {
+        tempP = (tempP<<1)/tempA;
+    } else {
+        tempP = (tempP/tempA)*2;
+    }
+
+    tempA = ((int32_t)P9Trim*((int32_t)(((tempP>>3)*(tempP>>3))>>13)))>>12;
+    tempB = (((int32_t)(tempP>>2))*(int32_t)P8Trim)>>13;
+    sensorData.pres = ((float)((tempP+((tempA + tempB+P7Trim)>>4))))/100;
+
+
+    //******************************LIGHT LEVEL*******************************//
+    sensorData.ligt = ldrADC.read();            // Read ldr value
+
+    //RETURN SENSOR DATA//
+    return sensorData;
+}
\ No newline at end of file