Contains necessary classes and functions for ELEC351

/media/uploads/Luka_Danilovic/elec_315_prototype_assembly.jpg

Committer:
Luka_Danilovic
Date:
Tue Jan 09 15:47:08 2018 +0000
Revision:
7:92b4783af1d2
Parent:
2:e2b885367ba8
ELEC351 Library; LCD Driver not working due to a bug I could not diagnose. I suspect it is the initialization.

Who changed what in which revision?

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