yes Spada / Mbed OS programme
Committer:
loicguibert
Date:
Tue Mar 05 10:27:40 2019 +0000
Revision:
4:bfe306335065
Mesurements ok, lib ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loicguibert 4:bfe306335065 1 #include "LPS25HBDevice.h"
loicguibert 4:bfe306335065 2
loicguibert 4:bfe306335065 3 #include "mbed_error.h"
loicguibert 4:bfe306335065 4
loicguibert 4:bfe306335065 5 // registers
loicguibert 4:bfe306335065 6 // Who am I register location
loicguibert 4:bfe306335065 7 #define LPS25HB_WHO_AM_I 0x0F
loicguibert 4:bfe306335065 8 // Tells whether the Pressure Data is ready or is being overrun
loicguibert 4:bfe306335065 9 #define LPS25HB_STATUS_REG 0x27
loicguibert 4:bfe306335065 10 // (LSB) Pressure output value
loicguibert 4:bfe306335065 11 #define LPS25HB_PRESS_OUT_XL 0x28
loicguibert 4:bfe306335065 12 // (mid part) Pressure output value
loicguibert 4:bfe306335065 13 #define LPS25HB_PRESS_OUT_L 0x29
loicguibert 4:bfe306335065 14 // (MSB) Pressure output value
loicguibert 4:bfe306335065 15 #define LPS25HB_PRESS_OUT_H 0x2A
loicguibert 4:bfe306335065 16 // (LSB) Pressure output value
loicguibert 4:bfe306335065 17 #define LPS25HB_TEMP_OUT_L 0x2B
loicguibert 4:bfe306335065 18 // (mid part) Pressure output value
loicguibert 4:bfe306335065 19 #define LPS25HB_TEMP_OUT_H 0x2C
loicguibert 4:bfe306335065 20 // Contains PD, BDU and more
loicguibert 4:bfe306335065 21 #define LPS25HB_CTRL_REG1 0x20
loicguibert 4:bfe306335065 22 // Contains one-shot mode and FIFO settings
loicguibert 4:bfe306335065 23 #define LPS25HB_CTRL_REG2 0x21
loicguibert 4:bfe306335065 24 // Pressure and temperature Resolution
loicguibert 4:bfe306335065 25 #define LPS25HB_RES_CONF 0x10
loicguibert 4:bfe306335065 26
loicguibert 4:bfe306335065 27 // Configuration Bits
loicguibert 4:bfe306335065 28 // Power Down when 0, active mode when 1 (Default 0)
loicguibert 4:bfe306335065 29 #define LPS25HB_CTRL_REG1_PD 0x80
loicguibert 4:bfe306335065 30 // Block Data Update: 0 Continuous mode, 1 read LSB,Mid,MSB first
loicguibert 4:bfe306335065 31 #define LPS25HB_CTRL_REG1_BDU 0x4
loicguibert 4:bfe306335065 32 // One shot mode enabled, obtains a new dataset
loicguibert 4:bfe306335065 33 #define LPS25HB_CTRL_REG2_ONE_SHOT 0x1
loicguibert 4:bfe306335065 34 //Pressure data available
loicguibert 4:bfe306335065 35 #define LPS25HB_STATUS_REG_PDA 0x2
loicguibert 4:bfe306335065 36
loicguibert 4:bfe306335065 37 LPS25HBDevice::LPS25HBDevice(PinName sda, PinName scl, Logger& logger)
loicguibert 4:bfe306335065 38 : I2C(sda, scl),
loicguibert 4:bfe306335065 39 m_logger(logger),
loicguibert 4:bfe306335065 40 m_address(0x5D << 1) {
loicguibert 4:bfe306335065 41
loicguibert 4:bfe306335065 42 }
loicguibert 4:bfe306335065 43
loicguibert 4:bfe306335065 44 bool LPS25HBDevice::probe(void) {
loicguibert 4:bfe306335065 45 uint8_t rx_data = 0;
loicguibert 4:bfe306335065 46 int rc = read(m_address | 0x1, (char*) &rx_data, (int) sizeof(rx_data));
loicguibert 4:bfe306335065 47 return (rc == 0);
loicguibert 4:bfe306335065 48 }
loicguibert 4:bfe306335065 49
loicguibert 4:bfe306335065 50 double LPS25HBDevice::getPressure(void) {
loicguibert 4:bfe306335065 51 // One-shot mode measurement sequence
loicguibert 4:bfe306335065 52 // 1. Power down the device (clean start)
loicguibert 4:bfe306335065 53 // WriteByte(LPS25HB_CTRL_REG1 = 0x00); // @0x20=0x00
loicguibert 4:bfe306335065 54 int rc = writeByte(LPS25HB_CTRL_REG1, 0);
loicguibert 4:bfe306335065 55 if (rc != 0) {
loicguibert 4:bfe306335065 56 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 57 return 0.0;
loicguibert 4:bfe306335065 58 }
loicguibert 4:bfe306335065 59
loicguibert 4:bfe306335065 60 // 2. Turn on the pressure sensor analog front end in single shot mode
loicguibert 4:bfe306335065 61 // WriteByte(LPS25HB_CTRL_REG1 = 0x84); // @0x20=0x84
loicguibert 4:bfe306335065 62 rc = writeByte(LPS25HB_CTRL_REG1, LPS25HB_CTRL_REG1_PD | LPS25HB_CTRL_REG1_BDU);
loicguibert 4:bfe306335065 63 if (rc != 0) {
loicguibert 4:bfe306335065 64 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 65 return 0.0;
loicguibert 4:bfe306335065 66 }
loicguibert 4:bfe306335065 67
loicguibert 4:bfe306335065 68 // 3a. Run one-shot measurement (temperature and pressure), the set bit will be reset by the
loicguibert 4:bfe306335065 69 // sensor itself after execution (self-clearing bit)
loicguibert 4:bfe306335065 70 // WriteByte(LPS25HB_CTRL_REG2 = 0x01); // @0x21=0x01
loicguibert 4:bfe306335065 71 rc = writeByte(LPS25HB_CTRL_REG2, LPS25HB_CTRL_REG2_ONE_SHOT);
loicguibert 4:bfe306335065 72 if (rc != 0) {
loicguibert 4:bfe306335065 73 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 74 return 0.0;
loicguibert 4:bfe306335065 75 }
loicguibert 4:bfe306335065 76
loicguibert 4:bfe306335065 77 // 3b. Configure the resolution for pressure for 16 internal averages
loicguibert 4:bfe306335065 78 // WriteByte(LPS25HB_RES_CONF = 0x01); // @0x10=0x01
loicguibert 4:bfe306335065 79 rc = writeByte(LPS25HB_RES_CONF, LPS25HB_CTRL_REG2_ONE_SHOT);
loicguibert 4:bfe306335065 80 if (rc != 0) {
loicguibert 4:bfe306335065 81 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 82 }
loicguibert 4:bfe306335065 83
loicguibert 4:bfe306335065 84 // 4. Wait until the measurement is completed
loicguibert 4:bfe306335065 85 // ReadByte(CTRL_REG2_ADDR = 0x00); // @0x21=0x00
loicguibert 4:bfe306335065 86 uint8_t status = 0;
loicguibert 4:bfe306335065 87 do {
loicguibert 4:bfe306335065 88 rc = readByte(LPS25HB_CTRL_REG2, status);
loicguibert 4:bfe306335065 89 if (rc != 0)
loicguibert 4:bfe306335065 90 {
loicguibert 4:bfe306335065 91 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 92 }
loicguibert 4:bfe306335065 93 } while (status != 0x00);
loicguibert 4:bfe306335065 94
loicguibert 4:bfe306335065 95 // // Wait for Temperature data to be ready
loicguibert 4:bfe306335065 96 // do {
loicguibert 4:bfe306335065 97 // err_code = lps25hb_read_byte(LPS25HB_STATUS_REG, &status);
loicguibert 4:bfe306335065 98 // APP_ERROR_CHECK(err_code);
loicguibert 4:bfe306335065 99 // } while ((status & LPS25HB_STATUS_REG_PDA) == 0);
loicguibert 4:bfe306335065 100
loicguibert 4:bfe306335065 101 // 5. Read the temperature measurement (2 bytes to read)
loicguibert 4:bfe306335065 102 // Read((u8*)pu8, TEMP_OUT_ADDR, 2); // @0x2B(OUT_L)~0x2C(OUT_H)
loicguibert 4:bfe306335065 103 // Temp_Reg_s16 = ((u16) pu8[1]<<8) | pu8[0]; // make a SIGNED 16 bit variable
loicguibert 4:bfe306335065 104 // Temperature_DegC = 42.5 + Temp_Reg_s16 / 480; // offset and scale
loicguibert 4:bfe306335065 105 uint8_t temp_L = 0;
loicguibert 4:bfe306335065 106 rc = readByte(LPS25HB_TEMP_OUT_L, temp_L);
loicguibert 4:bfe306335065 107 if (rc != 0) {
loicguibert 4:bfe306335065 108 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 109 }
loicguibert 4:bfe306335065 110
loicguibert 4:bfe306335065 111 uint8_t temp_H = 0;
loicguibert 4:bfe306335065 112 rc = readByte(LPS25HB_TEMP_OUT_H, temp_H);
loicguibert 4:bfe306335065 113 if (rc != 0) {
loicguibert 4:bfe306335065 114 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 115 }
loicguibert 4:bfe306335065 116
loicguibert 4:bfe306335065 117 // int16_t temp16 = ((uint16_t) temp_H << 8) | temp_L;
loicguibert 4:bfe306335065 118 // double tempC = 42.5 + (((double) temp16) / 480);
loicguibert 4:bfe306335065 119 // int temperature_int = (int) tempC;
loicguibert 4:bfe306335065 120 //int temperature_frac = 0;
loicguibert 4:bfe306335065 121 //if (tempC > 0.0) {
loicguibert 4:bfe306335065 122 // temperature_frac = ((int) ((tempC - temperature_int) * 1000));
loicguibert 4:bfe306335065 123 //}
loicguibert 4:bfe306335065 124 //else {
loicguibert 4:bfe306335065 125 // temperature_frac = ((int) ((-tempC + temperature_int) * 1000));
loicguibert 4:bfe306335065 126 //}
loicguibert 4:bfe306335065 127
loicguibert 4:bfe306335065 128 // 6. Read the pressure measurement
loicguibert 4:bfe306335065 129 // Read((u8*)pu8, PRESS_OUT_ADDR, 3);
loicguibert 4:bfe306335065 130 // @0x28(OUT_XL)~0x29(OUT_L)~0x2A(OUT_H)
loicguibert 4:bfe306335065 131 // Pressure_Reg_s32 = ((u32)pu8[2]<<16)|((u32)pu8[1]<<8)|pu8[0];
loicguibert 4:bfe306335065 132 // make a SIGNED 32 bit Pressure_mb = Pressure_Reg_s32 / 4096; // scale
loicguibert 4:bfe306335065 133 uint8_t pressure_XL = 0;
loicguibert 4:bfe306335065 134 rc = readByte(LPS25HB_PRESS_OUT_XL, pressure_XL);
loicguibert 4:bfe306335065 135 if (rc != 0) {
loicguibert 4:bfe306335065 136 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 137 }
loicguibert 4:bfe306335065 138
loicguibert 4:bfe306335065 139 uint8_t pressure_L = 0;
loicguibert 4:bfe306335065 140 rc = readByte(LPS25HB_PRESS_OUT_L, pressure_L);
loicguibert 4:bfe306335065 141 if (rc != 0) {
loicguibert 4:bfe306335065 142 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 143 }
loicguibert 4:bfe306335065 144
loicguibert 4:bfe306335065 145 uint8_t pressure_H = 0;
loicguibert 4:bfe306335065 146 rc = readByte(LPS25HB_PRESS_OUT_H, pressure_H);
loicguibert 4:bfe306335065 147 if (rc != 0) {
loicguibert 4:bfe306335065 148 m_logger.log("Error\r\n");
loicguibert 4:bfe306335065 149 }
loicguibert 4:bfe306335065 150
loicguibert 4:bfe306335065 151 int32_t pressure32 = ((pressure_H << 16) | (pressure_L << 8) | (pressure_XL));
loicguibert 4:bfe306335065 152
loicguibert 4:bfe306335065 153 // convert the 2's complement 24 bit to 2's complement 32 bit
loicguibert 4:bfe306335065 154 if (pressure32 & 0x00800000) {
loicguibert 4:bfe306335065 155 pressure32 |= 0xFF000000;
loicguibert 4:bfe306335065 156 }
loicguibert 4:bfe306335065 157
loicguibert 4:bfe306335065 158 // Calculate Pressure in mbar or hPa
loicguibert 4:bfe306335065 159 double pressure = ((double) pressure32) / 4096.0f;
loicguibert 4:bfe306335065 160
loicguibert 4:bfe306335065 161 // 7. Check the temperature and pressure values make sense
loicguibert 4:bfe306335065 162 // Reading fixed 760 hPa, means the sensing element is damaged.
loicguibert 4:bfe306335065 163 if (pressure == 760) {
loicguibert 4:bfe306335065 164 return 0.0;
loicguibert 4:bfe306335065 165 }
loicguibert 4:bfe306335065 166
loicguibert 4:bfe306335065 167 return pressure;
loicguibert 4:bfe306335065 168 }
loicguibert 4:bfe306335065 169
loicguibert 4:bfe306335065 170 int LPS25HBDevice::writeByte(uint8_t regAddress, uint8_t value) {
loicguibert 4:bfe306335065 171 uint8_t txData[2] = { regAddress, value };
loicguibert 4:bfe306335065 172
loicguibert 4:bfe306335065 173 int rc = write(m_address, (char*) txData, sizeof(txData));
loicguibert 4:bfe306335065 174 return rc;
loicguibert 4:bfe306335065 175 }
loicguibert 4:bfe306335065 176
loicguibert 4:bfe306335065 177 int LPS25HBDevice::readByte(uint8_t regAddress, uint8_t& value) {
loicguibert 4:bfe306335065 178 // first write register
loicguibert 4:bfe306335065 179 uint8_t txData[1] = { regAddress };
loicguibert 4:bfe306335065 180 int rc = write(m_address, (char*) txData, sizeof(txData), true);
loicguibert 4:bfe306335065 181 if (rc != 0) {
loicguibert 4:bfe306335065 182 m_logger.log("Error in read %d\r\n", rc);
loicguibert 4:bfe306335065 183 return rc;
loicguibert 4:bfe306335065 184 }
loicguibert 4:bfe306335065 185 rc = read(m_address, (char*) &value, sizeof(value));
loicguibert 4:bfe306335065 186
loicguibert 4:bfe306335065 187 return rc;
loicguibert 4:bfe306335065 188 }
loicguibert 4:bfe306335065 189