ELEC351 SUBMISSION - Same as on the DLE

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

Committer:
Luka_Danilovic
Date:
Wed Jan 10 09:49:43 2018 +0000
Revision:
0:c66224a27cf8
ELEC351 SUBMISSION - SAme as on the DLE

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Luka_Danilovic 0:c66224a27cf8 1 #include "mbed.h"
Luka_Danilovic 0:c66224a27cf8 2 #include "samplingMaster.hpp"
Luka_Danilovic 0:c66224a27cf8 3
Luka_Danilovic 0:c66224a27cf8 4 /* Spec said that we are not allowed to use any third party code unless it is
Luka_Danilovic 0:c66224a27cf8 5 from ARM or STmicroelectronics, so I wrote my own driver for sampling BMP280 &
Luka_Danilovic 0:c66224a27cf8 6 ADC in succesion. Ths code for MPB280 was inspired by the BMP280 Datasheet:
Luka_Danilovic 0:c66224a27cf8 7 [https://cdn-shop.adafruit.com/datasheets/BST-BMP280-DS001-11.pdf]
Luka_Danilovic 0:c66224a27cf8 8 and BMP280 mbed library by "charlie":
Luka_Danilovic 0:c66224a27cf8 9 [https://os.mbed.com/users/CHARLY/code/BMP280/] */
Luka_Danilovic 0:c66224a27cf8 10
Luka_Danilovic 0:c66224a27cf8 11 C_sensorData::C_sensorData()
Luka_Danilovic 0:c66224a27cf8 12 {
Luka_Danilovic 0:c66224a27cf8 13
Luka_Danilovic 0:c66224a27cf8 14 //********************************LDR ADC*********************************//
Luka_Danilovic 0:c66224a27cf8 15 AnalogIn ldrADC(PA_0); // Establish Analog In for ADC
Luka_Danilovic 0:c66224a27cf8 16
Luka_Danilovic 0:c66224a27cf8 17 //******************************BMP280 I2C********************************//
Luka_Danilovic 0:c66224a27cf8 18 I2C sensorLink(D14, D15); // Establish I2C comms
Luka_Danilovic 0:c66224a27cf8 19
Luka_Danilovic 0:c66224a27cf8 20 inst[0] = CONTROL_REGISTER; // Register address
Luka_Danilovic 0:c66224a27cf8 21 inst[1] = 0b01101101; // Temp x4, Pressure x4, Forced mode
Luka_Danilovic 0:c66224a27cf8 22 sensorLink.write(I2C_adr, inst, 2);
Luka_Danilovic 0:c66224a27cf8 23
Luka_Danilovic 0:c66224a27cf8 24 inst[0] = Tsb_IIR_REGISTER; // Register address
Luka_Danilovic 0:c66224a27cf8 25 inst[1] = 0x00; // No standby, No IIR filter
Luka_Danilovic 0:c66224a27cf8 26 sensorLink.write(I2C_adr, inst, 2);
Luka_Danilovic 0:c66224a27cf8 27
Luka_Danilovic 0:c66224a27cf8 28 inst[0] = DIG_Tn_REGISTERS; // Read trimming parameters instruction
Luka_Danilovic 0:c66224a27cf8 29 sensorLink.write(I2C_adr, inst, 1);
Luka_Danilovic 0:c66224a27cf8 30 sensorLink.read(I2C_adr, inst, 6);
Luka_Danilovic 0:c66224a27cf8 31
Luka_Danilovic 0:c66224a27cf8 32 /* For instructions how to decode trimming parameters please refer to the
Luka_Danilovic 0:c66224a27cf8 33 BMP280 datasheet, page 21, chapter 3.11.2, table 17: "Compensation parameter
Luka_Danilovic 0:c66224a27cf8 34 storage, naming and data type" */
Luka_Danilovic 0:c66224a27cf8 35 T1Trim = (inst[1]<<8)|inst[0];
Luka_Danilovic 0:c66224a27cf8 36 T2Trim = (inst[3]<<8)|inst[2];
Luka_Danilovic 0:c66224a27cf8 37 T3Trim = (inst[5]<<8)|inst[4];
Luka_Danilovic 0:c66224a27cf8 38
Luka_Danilovic 0:c66224a27cf8 39 inst[0] = DIG_Pn_REGISTERS; // Read trimming parameters instruction
Luka_Danilovic 0:c66224a27cf8 40 sensorLink.write(I2C_adr, inst, 1);
Luka_Danilovic 0:c66224a27cf8 41 sensorLink.read(I2C_adr, inst, 18);
Luka_Danilovic 0:c66224a27cf8 42
Luka_Danilovic 0:c66224a27cf8 43 /* For instructions how to decode trimming parameters please refer to the
Luka_Danilovic 0:c66224a27cf8 44 BMP280 datasheet, page 21, chapter 3.11.2, table 17: "Compensation parameter
Luka_Danilovic 0:c66224a27cf8 45 storage, naming and data type" */
Luka_Danilovic 0:c66224a27cf8 46 P1Trim = (inst[ 1]<<8)|inst[ 0];
Luka_Danilovic 0:c66224a27cf8 47 P2Trim = (inst[ 3]<<8)|inst[ 2];
Luka_Danilovic 0:c66224a27cf8 48 P3Trim = (inst[ 5]<<8)|inst[ 4];
Luka_Danilovic 0:c66224a27cf8 49 P4Trim = (inst[ 7]<<8)|inst[ 6];
Luka_Danilovic 0:c66224a27cf8 50 P5Trim = (inst[ 9]<<8)|inst[ 8];
Luka_Danilovic 0:c66224a27cf8 51 P6Trim = (inst[11]<<8)|inst[10];
Luka_Danilovic 0:c66224a27cf8 52 P7Trim = (inst[13]<<8)|inst[12];
Luka_Danilovic 0:c66224a27cf8 53 P8Trim = (inst[15]<<8)|inst[14];
Luka_Danilovic 0:c66224a27cf8 54 P9Trim = (inst[17]<<8)|inst[16];
Luka_Danilovic 0:c66224a27cf8 55 }
Luka_Danilovic 0:c66224a27cf8 56
Luka_Danilovic 0:c66224a27cf8 57 TDS_sensorData C_sensorData::read()
Luka_Danilovic 0:c66224a27cf8 58 {
Luka_Danilovic 0:c66224a27cf8 59 //*********************************SETUP**********************************//
Luka_Danilovic 0:c66224a27cf8 60 TDS_sensorData sensorData; // Type def struct to hold the data
Luka_Danilovic 0:c66224a27cf8 61 AnalogIn ldrADC(PA_0); // Establish Analog In for ADC
Luka_Danilovic 0:c66224a27cf8 62 I2C sensorLink(D14, D15); // Establish I2C comms
Luka_Danilovic 0:c66224a27cf8 63
Luka_Danilovic 0:c66224a27cf8 64 /* N.B in forced mode you must write to CONTROL_REGISTER to wake the IMU up.
Luka_Danilovic 0:c66224a27cf8 65 It automaticly sleeps when measurments are aquired but leaves the registers
Luka_Danilovic 0:c66224a27cf8 66 readable for the I2C link */
Luka_Danilovic 0:c66224a27cf8 67 inst[0] = CONTROL_REGISTER; // Register address
Luka_Danilovic 0:c66224a27cf8 68 inst[1] = 0b01101101; // Temp x4, Pressure x4, Forced mode
Luka_Danilovic 0:c66224a27cf8 69 sensorLink.write(I2C_adr, inst, 2);
Luka_Danilovic 0:c66224a27cf8 70
Luka_Danilovic 0:c66224a27cf8 71 //******************************TEMPERATURE*******************************//
Luka_Danilovic 0:c66224a27cf8 72 inst[0] = TEMP_ADDRESS_VAL; // Start of temperature register
Luka_Danilovic 0:c66224a27cf8 73 sensorLink.write(I2C_adr, inst, 1);
Luka_Danilovic 0:c66224a27cf8 74 sensorLink.read(I2C_adr, &inst[1], 3);
Luka_Danilovic 0:c66224a27cf8 75
Luka_Danilovic 0:c66224a27cf8 76 tempT = (inst[1]<<12)|(inst[2]<<4)|(inst[3]>>4);
Luka_Danilovic 0:c66224a27cf8 77 // ^ ^ ^
Luka_Danilovic 0:c66224a27cf8 78 // MSB REGISTER LSB REGISTER X_LSB REGISTER
Luka_Danilovic 0:c66224a27cf8 79
Luka_Danilovic 0:c66224a27cf8 80 /* For instructions how to compensate values please refer to the
Luka_Danilovic 0:c66224a27cf8 81 BMP280 datasheet, page 21 & 22, chapter 3.11.3, pseudo code */
Luka_Danilovic 0:c66224a27cf8 82 tempA = ((((tempT>>3)-(T1Trim<<1)))*T2Trim)>>11;
Luka_Danilovic 0:c66224a27cf8 83 tempB = (((((tempT>>4)-T1Trim)*((tempT>>4)-T1Trim))>>12)*T3Trim)>>14;
Luka_Danilovic 0:c66224a27cf8 84 tempT = tempA+tempB;
Luka_Danilovic 0:c66224a27cf8 85 sensorData.temp = ((float)((tempT * 5 + 128) >> 8))/100;
Luka_Danilovic 0:c66224a27cf8 86
Luka_Danilovic 0:c66224a27cf8 87 //********************************PRESURE********************************//
Luka_Danilovic 0:c66224a27cf8 88 inst[0] = PRES_ADDRESS_VAL; // Start of presure register
Luka_Danilovic 0:c66224a27cf8 89 sensorLink.write(I2C_adr, inst, 1);
Luka_Danilovic 0:c66224a27cf8 90 sensorLink.read(I2C_adr, &inst[1], 3);
Luka_Danilovic 0:c66224a27cf8 91
Luka_Danilovic 0:c66224a27cf8 92 tempP = (inst[1]<<12)|(inst[2]<<4)|(inst[3]>>4);
Luka_Danilovic 0:c66224a27cf8 93 // ^ ^ ^
Luka_Danilovic 0:c66224a27cf8 94 // MSB REGISTER LSB REGISTER X_LSB REGISTER
Luka_Danilovic 0:c66224a27cf8 95
Luka_Danilovic 0:c66224a27cf8 96 /* For instructions how to compensate values please refer to the
Luka_Danilovic 0:c66224a27cf8 97 BMP280 datasheet, page 21 & 22, chapter 3.11.3, pseudo code.
Luka_Danilovic 0:c66224a27cf8 98
Luka_Danilovic 0:c66224a27cf8 99 Please note that the compensation in the datasheet is done with 64 bit
Luka_Danilovic 0:c66224a27cf8 100 signed values. However, "charlie's" BMP280 driver which does the
Luka_Danilovic 0:c66224a27cf8 101 compensation using 32 bit signed values has inspired me to write my
Luka_Danilovic 0:c66224a27cf8 102 compensation algorithm as follows. This makes the algorithm more efficient
Luka_Danilovic 0:c66224a27cf8 103 without sacrifising relevant acuracy
Luka_Danilovic 0:c66224a27cf8 104
Luka_Danilovic 0:c66224a27cf8 105 N.B the pressure calculated by the following algorithm is in hPa which is
Luka_Danilovic 0:c66224a27cf8 106 a newer unit with equivalence of: 1hPA = 1mbar*/
Luka_Danilovic 0:c66224a27cf8 107
Luka_Danilovic 0:c66224a27cf8 108 tempA = (tempT>>1)-64000;
Luka_Danilovic 0:c66224a27cf8 109 tempB = (((tempA>>2)*(tempA>>2))>>11)*P6Trim;
Luka_Danilovic 0:c66224a27cf8 110 tempB = tempB+((tempA*P5Trim)<<1);
Luka_Danilovic 0:c66224a27cf8 111 tempB = (tempB>>2)+(P4Trim<<16);
Luka_Danilovic 0:c66224a27cf8 112 tempA = (((P3Trim*(((tempA>>2)*(tempA>>2))>>13))>>3)+((P2Trim*tempA)>>1))>>18;
Luka_Danilovic 0:c66224a27cf8 113 tempA = ((32768+tempA)*P1Trim)>>15;
Luka_Danilovic 0:c66224a27cf8 114
Luka_Danilovic 0:c66224a27cf8 115 if(tempA == 0) {
Luka_Danilovic 0:c66224a27cf8 116 sensorData.pres = 0;
Luka_Danilovic 0:c66224a27cf8 117 }
Luka_Danilovic 0:c66224a27cf8 118 tempP = (((1048576-tempP)-(tempB>>12)))*3125; // Compensate for 64 bit loss
Luka_Danilovic 0:c66224a27cf8 119 if(tempP < PREAS_UPER_LIMIT) {
Luka_Danilovic 0:c66224a27cf8 120 tempP = (tempP<<1)/tempA;
Luka_Danilovic 0:c66224a27cf8 121 } else {
Luka_Danilovic 0:c66224a27cf8 122 tempP = (tempP/tempA)*2;
Luka_Danilovic 0:c66224a27cf8 123 }
Luka_Danilovic 0:c66224a27cf8 124
Luka_Danilovic 0:c66224a27cf8 125 tempA = ((int32_t)P9Trim*((int32_t)(((tempP>>3)*(tempP>>3))>>13)))>>12;
Luka_Danilovic 0:c66224a27cf8 126 tempB = (((int32_t)(tempP>>2))*(int32_t)P8Trim)>>13;
Luka_Danilovic 0:c66224a27cf8 127 sensorData.pres = ((float)((tempP+((tempA + tempB+P7Trim)>>4))))/100;
Luka_Danilovic 0:c66224a27cf8 128
Luka_Danilovic 0:c66224a27cf8 129
Luka_Danilovic 0:c66224a27cf8 130 //******************************LIGHT LEVEL*******************************//
Luka_Danilovic 0:c66224a27cf8 131 sensorData.ligt = ldrADC.read(); // Read ldr value
Luka_Danilovic 0:c66224a27cf8 132
Luka_Danilovic 0:c66224a27cf8 133 //RETURN SENSOR DATA//
Luka_Danilovic 0:c66224a27cf8 134 return sensorData;
Luka_Danilovic 0:c66224a27cf8 135 }