you can use LPS25HB sensor on mbed. i2c
Dependents: read_Pmod optWingforHAPS_Eigen hexaTest_Eigen
LPS.cpp@0:4ea758df868a, 2018-12-22 (annotated)
- Committer:
- tajiri1999
- Date:
- Sat Dec 22 16:44:40 2018 +0000
- Revision:
- 0:4ea758df868a
- Child:
- 2:c178d72753dc
LPS25HB_i2c for mbed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tajiri1999 | 0:4ea758df868a | 1 | #include "LPS.h" |
tajiri1999 | 0:4ea758df868a | 2 | #include "mbed.h" |
tajiri1999 | 0:4ea758df868a | 3 | |
tajiri1999 | 0:4ea758df868a | 4 | // Defines /////////////////////////////////////////////////////////// |
tajiri1999 | 0:4ea758df868a | 5 | |
tajiri1999 | 0:4ea758df868a | 6 | // The Arduino two-wire interface uses a 7-bit number for the address, |
tajiri1999 | 0:4ea758df868a | 7 | #define SA0_LOW_ADDRESS 0b1011100 |
tajiri1999 | 0:4ea758df868a | 8 | #define SA0_HIGH_ADDRESS 0b1011101 |
tajiri1999 | 0:4ea758df868a | 9 | |
tajiri1999 | 0:4ea758df868a | 10 | #define TEST_REG_NACK -1 |
tajiri1999 | 0:4ea758df868a | 11 | |
tajiri1999 | 0:4ea758df868a | 12 | #define LPS331AP_WHO_ID 0xBB |
tajiri1999 | 0:4ea758df868a | 13 | #define LPS25H_WHO_ID 0xBD |
tajiri1999 | 0:4ea758df868a | 14 | |
tajiri1999 | 0:4ea758df868a | 15 | // Constructors ////////////////////////////////////////////////////// |
tajiri1999 | 0:4ea758df868a | 16 | |
tajiri1999 | 0:4ea758df868a | 17 | LPS::LPS(I2C& p_i2c):_i2c(p_i2c) |
tajiri1999 | 0:4ea758df868a | 18 | { |
tajiri1999 | 0:4ea758df868a | 19 | _device = device_auto; |
tajiri1999 | 0:4ea758df868a | 20 | |
tajiri1999 | 0:4ea758df868a | 21 | // Pololu board pulls SA0 high, so default assumption is that it is |
tajiri1999 | 0:4ea758df868a | 22 | // high |
tajiri1999 | 0:4ea758df868a | 23 | address = SA0_HIGH_ADDRESS; |
tajiri1999 | 0:4ea758df868a | 24 | } |
tajiri1999 | 0:4ea758df868a | 25 | |
tajiri1999 | 0:4ea758df868a | 26 | // Public Methods //////////////////////////////////////////////////// |
tajiri1999 | 0:4ea758df868a | 27 | |
tajiri1999 | 0:4ea758df868a | 28 | // sets or detects device type and slave address; returns bool indicating success |
tajiri1999 | 0:4ea758df868a | 29 | bool LPS::init(deviceType device, uint8_t sa0) |
tajiri1999 | 0:4ea758df868a | 30 | { |
tajiri1999 | 0:4ea758df868a | 31 | if (!detectDeviceAndAddress(device, (sa0State)sa0)) |
tajiri1999 | 0:4ea758df868a | 32 | return false; |
tajiri1999 | 0:4ea758df868a | 33 | |
tajiri1999 | 0:4ea758df868a | 34 | switch (_device) |
tajiri1999 | 0:4ea758df868a | 35 | { |
tajiri1999 | 0:4ea758df868a | 36 | case device_25H: |
tajiri1999 | 0:4ea758df868a | 37 | translated_regs[-INTERRUPT_CFG] = LPS25H_INTERRUPT_CFG; |
tajiri1999 | 0:4ea758df868a | 38 | translated_regs[-INT_SOURCE] = LPS25H_INT_SOURCE; |
tajiri1999 | 0:4ea758df868a | 39 | translated_regs[-THS_P_L] = LPS25H_THS_P_L; |
tajiri1999 | 0:4ea758df868a | 40 | translated_regs[-THS_P_H] = LPS25H_THS_P_H; |
tajiri1999 | 0:4ea758df868a | 41 | return true; |
tajiri1999 | 0:4ea758df868a | 42 | break; |
tajiri1999 | 0:4ea758df868a | 43 | |
tajiri1999 | 0:4ea758df868a | 44 | case device_331AP: |
tajiri1999 | 0:4ea758df868a | 45 | translated_regs[-INTERRUPT_CFG] = LPS331AP_INTERRUPT_CFG; |
tajiri1999 | 0:4ea758df868a | 46 | translated_regs[-INT_SOURCE] = LPS331AP_INT_SOURCE; |
tajiri1999 | 0:4ea758df868a | 47 | translated_regs[-THS_P_L] = LPS331AP_THS_P_L; |
tajiri1999 | 0:4ea758df868a | 48 | translated_regs[-THS_P_H] = LPS331AP_THS_P_H; |
tajiri1999 | 0:4ea758df868a | 49 | return true; |
tajiri1999 | 0:4ea758df868a | 50 | break; |
tajiri1999 | 0:4ea758df868a | 51 | } |
tajiri1999 | 0:4ea758df868a | 52 | } |
tajiri1999 | 0:4ea758df868a | 53 | |
tajiri1999 | 0:4ea758df868a | 54 | // turns on sensor and enables continuous output |
tajiri1999 | 0:4ea758df868a | 55 | void LPS::enableDefault(void) |
tajiri1999 | 0:4ea758df868a | 56 | { |
tajiri1999 | 0:4ea758df868a | 57 | if (_device == device_25H) |
tajiri1999 | 0:4ea758df868a | 58 | { |
tajiri1999 | 0:4ea758df868a | 59 | // 0xB0 = 0b10110000 |
tajiri1999 | 0:4ea758df868a | 60 | // PD = 1 (active mode); ODR = 011 (12.5 Hz pressure & temperature output data rate) |
tajiri1999 | 0:4ea758df868a | 61 | writeReg(CTRL_REG1, 0xB0); |
tajiri1999 | 0:4ea758df868a | 62 | } |
tajiri1999 | 0:4ea758df868a | 63 | else if (_device == device_331AP) |
tajiri1999 | 0:4ea758df868a | 64 | { |
tajiri1999 | 0:4ea758df868a | 65 | // 0xE0 = 0b11100000 |
tajiri1999 | 0:4ea758df868a | 66 | // PD = 1 (active mode); ODR = 110 (12.5 Hz pressure & temperature output data rate) |
tajiri1999 | 0:4ea758df868a | 67 | writeReg(CTRL_REG1, 0xE0); |
tajiri1999 | 0:4ea758df868a | 68 | } |
tajiri1999 | 0:4ea758df868a | 69 | } |
tajiri1999 | 0:4ea758df868a | 70 | |
tajiri1999 | 0:4ea758df868a | 71 | // writes register |
tajiri1999 | 0:4ea758df868a | 72 | void LPS::writeReg(char reg, char value) |
tajiri1999 | 0:4ea758df868a | 73 | { |
tajiri1999 | 0:4ea758df868a | 74 | // if dummy register address, look up actual translated address (based on device type) |
tajiri1999 | 0:4ea758df868a | 75 | if (reg < 0) |
tajiri1999 | 0:4ea758df868a | 76 | { |
tajiri1999 | 0:4ea758df868a | 77 | reg = translated_regs[-reg]; |
tajiri1999 | 0:4ea758df868a | 78 | } |
tajiri1999 | 0:4ea758df868a | 79 | char command[] = {reg,value}; |
tajiri1999 | 0:4ea758df868a | 80 | _i2c.write(address << 1,command,2); |
tajiri1999 | 0:4ea758df868a | 81 | } |
tajiri1999 | 0:4ea758df868a | 82 | |
tajiri1999 | 0:4ea758df868a | 83 | // reads register |
tajiri1999 | 0:4ea758df868a | 84 | int8_t LPS::readReg(char reg) |
tajiri1999 | 0:4ea758df868a | 85 | { |
tajiri1999 | 0:4ea758df868a | 86 | char value; |
tajiri1999 | 0:4ea758df868a | 87 | // if dummy register address, look up actual translated address (based on device type) |
tajiri1999 | 0:4ea758df868a | 88 | if(reg < 0) |
tajiri1999 | 0:4ea758df868a | 89 | { |
tajiri1999 | 0:4ea758df868a | 90 | reg = translated_regs[-reg]; |
tajiri1999 | 0:4ea758df868a | 91 | } |
tajiri1999 | 0:4ea758df868a | 92 | _i2c.write(address << 1,®,1); |
tajiri1999 | 0:4ea758df868a | 93 | _i2c.read((address << 1)|1,&value,1); |
tajiri1999 | 0:4ea758df868a | 94 | |
tajiri1999 | 0:4ea758df868a | 95 | return value; |
tajiri1999 | 0:4ea758df868a | 96 | } |
tajiri1999 | 0:4ea758df868a | 97 | |
tajiri1999 | 0:4ea758df868a | 98 | // reads pressure in millibars (mbar)/hectopascals (hPa) |
tajiri1999 | 0:4ea758df868a | 99 | float LPS::readPressureMillibars(void) |
tajiri1999 | 0:4ea758df868a | 100 | { |
tajiri1999 | 0:4ea758df868a | 101 | return (float)readPressureRaw() / 4096; |
tajiri1999 | 0:4ea758df868a | 102 | } |
tajiri1999 | 0:4ea758df868a | 103 | |
tajiri1999 | 0:4ea758df868a | 104 | // reads pressure in inches of mercury (inHg) |
tajiri1999 | 0:4ea758df868a | 105 | float LPS::readPressureInchesHg(void) |
tajiri1999 | 0:4ea758df868a | 106 | { |
tajiri1999 | 0:4ea758df868a | 107 | return (float)readPressureRaw() / 138706.5; |
tajiri1999 | 0:4ea758df868a | 108 | } |
tajiri1999 | 0:4ea758df868a | 109 | |
tajiri1999 | 0:4ea758df868a | 110 | // reads pressure and returns raw 24-bit sensor output |
tajiri1999 | 0:4ea758df868a | 111 | int32_t LPS::readPressureRaw(void) |
tajiri1999 | 0:4ea758df868a | 112 | { |
tajiri1999 | 0:4ea758df868a | 113 | // assert MSB to enable register address auto-increment |
tajiri1999 | 0:4ea758df868a | 114 | |
tajiri1999 | 0:4ea758df868a | 115 | char command = PRESS_OUT_XL | (1 << 7); |
tajiri1999 | 0:4ea758df868a | 116 | char p[3]; |
tajiri1999 | 0:4ea758df868a | 117 | _i2c.write(address << 1,&command,1); |
tajiri1999 | 0:4ea758df868a | 118 | _i2c.read((address << 1)| 1,p,3); |
tajiri1999 | 0:4ea758df868a | 119 | |
tajiri1999 | 0:4ea758df868a | 120 | // combine int8_ts |
tajiri1999 | 0:4ea758df868a | 121 | return (int32_t)(int8_t)p[2] << 16 | (uint16_t)p[1] << 8 | p[0]; |
tajiri1999 | 0:4ea758df868a | 122 | } |
tajiri1999 | 0:4ea758df868a | 123 | |
tajiri1999 | 0:4ea758df868a | 124 | // reads temperature in degrees C |
tajiri1999 | 0:4ea758df868a | 125 | float LPS::readTemperatureC(void) |
tajiri1999 | 0:4ea758df868a | 126 | { |
tajiri1999 | 0:4ea758df868a | 127 | return 42.5 + (float)readTemperatureRaw() / 480; |
tajiri1999 | 0:4ea758df868a | 128 | } |
tajiri1999 | 0:4ea758df868a | 129 | |
tajiri1999 | 0:4ea758df868a | 130 | // reads temperature in degrees F |
tajiri1999 | 0:4ea758df868a | 131 | float LPS::readTemperatureF(void) |
tajiri1999 | 0:4ea758df868a | 132 | { |
tajiri1999 | 0:4ea758df868a | 133 | return 108.5 + (float)readTemperatureRaw() / 480 * 1.8; |
tajiri1999 | 0:4ea758df868a | 134 | } |
tajiri1999 | 0:4ea758df868a | 135 | |
tajiri1999 | 0:4ea758df868a | 136 | // reads temperature and returns raw 16-bit sensor output |
tajiri1999 | 0:4ea758df868a | 137 | int16_t LPS::readTemperatureRaw(void) |
tajiri1999 | 0:4ea758df868a | 138 | { |
tajiri1999 | 0:4ea758df868a | 139 | char command = TEMP_OUT_L | (1 << 7); |
tajiri1999 | 0:4ea758df868a | 140 | |
tajiri1999 | 0:4ea758df868a | 141 | // assert MSB to enable register address auto-increment |
tajiri1999 | 0:4ea758df868a | 142 | char t[2]; |
tajiri1999 | 0:4ea758df868a | 143 | _i2c.write(address << 1,&command,1); |
tajiri1999 | 0:4ea758df868a | 144 | _i2c.read((address << 1)| 1,t,2); |
tajiri1999 | 0:4ea758df868a | 145 | |
tajiri1999 | 0:4ea758df868a | 146 | // combine bytes |
tajiri1999 | 0:4ea758df868a | 147 | return (int16_t)(t[1] << 8 | t[0]); |
tajiri1999 | 0:4ea758df868a | 148 | } |
tajiri1999 | 0:4ea758df868a | 149 | |
tajiri1999 | 0:4ea758df868a | 150 | // converts pressure in mbar to altitude in meters, using 1976 US |
tajiri1999 | 0:4ea758df868a | 151 | // Standard Atmosphere model (note that this formula only applies to a |
tajiri1999 | 0:4ea758df868a | 152 | // height of 11 km, or about 36000 ft) |
tajiri1999 | 0:4ea758df868a | 153 | // If altimeter setting (QNH, barometric pressure adjusted to sea |
tajiri1999 | 0:4ea758df868a | 154 | // level) is given, this function returns an indicated altitude |
tajiri1999 | 0:4ea758df868a | 155 | // compensated for actual regional pressure; otherwise, it returns |
tajiri1999 | 0:4ea758df868a | 156 | // the pressure altitude above the standard pressure level of 1013.25 |
tajiri1999 | 0:4ea758df868a | 157 | // mbar or 29.9213 inHg |
tajiri1999 | 0:4ea758df868a | 158 | float LPS::pressureToAltitudeMeters(double pressure_mbar, double altimeter_setting_mbar) |
tajiri1999 | 0:4ea758df868a | 159 | { |
tajiri1999 | 0:4ea758df868a | 160 | return (1 - pow(pressure_mbar / altimeter_setting_mbar, 0.190263)) * 44330.8;//pressure; |
tajiri1999 | 0:4ea758df868a | 161 | } |
tajiri1999 | 0:4ea758df868a | 162 | |
tajiri1999 | 0:4ea758df868a | 163 | // converts pressure in inHg to altitude in feet; see notes above |
tajiri1999 | 0:4ea758df868a | 164 | float LPS::pressureToAltitudeFeet(double pressure_inHg, double altimeter_setting_inHg) |
tajiri1999 | 0:4ea758df868a | 165 | { |
tajiri1999 | 0:4ea758df868a | 166 | return (1 - pow(pressure_inHg / altimeter_setting_inHg, 0.190263)) * 145442;//pressure; |
tajiri1999 | 0:4ea758df868a | 167 | } |
tajiri1999 | 0:4ea758df868a | 168 | |
tajiri1999 | 0:4ea758df868a | 169 | // Private Methods /////////////////////////////////////////////////// |
tajiri1999 | 0:4ea758df868a | 170 | |
tajiri1999 | 0:4ea758df868a | 171 | bool LPS::detectDeviceAndAddress(deviceType device, sa0State sa0) |
tajiri1999 | 0:4ea758df868a | 172 | { |
tajiri1999 | 0:4ea758df868a | 173 | if (sa0 == sa0_auto || sa0 == sa0_high) |
tajiri1999 | 0:4ea758df868a | 174 | { |
tajiri1999 | 0:4ea758df868a | 175 | address = SA0_HIGH_ADDRESS; |
tajiri1999 | 0:4ea758df868a | 176 | if (detectDevice(device)) return true; |
tajiri1999 | 0:4ea758df868a | 177 | } |
tajiri1999 | 0:4ea758df868a | 178 | if (sa0 == sa0_auto || sa0 == sa0_low) |
tajiri1999 | 0:4ea758df868a | 179 | { |
tajiri1999 | 0:4ea758df868a | 180 | address = SA0_LOW_ADDRESS; |
tajiri1999 | 0:4ea758df868a | 181 | if (detectDevice(device)) return true; |
tajiri1999 | 0:4ea758df868a | 182 | } |
tajiri1999 | 0:4ea758df868a | 183 | |
tajiri1999 | 0:4ea758df868a | 184 | return false; |
tajiri1999 | 0:4ea758df868a | 185 | } |
tajiri1999 | 0:4ea758df868a | 186 | |
tajiri1999 | 0:4ea758df868a | 187 | bool LPS::detectDevice(deviceType device) |
tajiri1999 | 0:4ea758df868a | 188 | { |
tajiri1999 | 0:4ea758df868a | 189 | uint8_t id = testWhoAmI(address); |
tajiri1999 | 0:4ea758df868a | 190 | |
tajiri1999 | 0:4ea758df868a | 191 | if ((device == device_auto || device == device_25H) && id == (uint8_t)LPS25H_WHO_ID) |
tajiri1999 | 0:4ea758df868a | 192 | { |
tajiri1999 | 0:4ea758df868a | 193 | _device = device_25H; |
tajiri1999 | 0:4ea758df868a | 194 | return true; |
tajiri1999 | 0:4ea758df868a | 195 | } |
tajiri1999 | 0:4ea758df868a | 196 | if ((device == device_auto || device == device_331AP) && id == (uint8_t)LPS331AP_WHO_ID) |
tajiri1999 | 0:4ea758df868a | 197 | { |
tajiri1999 | 0:4ea758df868a | 198 | _device = device_331AP; |
tajiri1999 | 0:4ea758df868a | 199 | return true; |
tajiri1999 | 0:4ea758df868a | 200 | } |
tajiri1999 | 0:4ea758df868a | 201 | |
tajiri1999 | 0:4ea758df868a | 202 | return false; |
tajiri1999 | 0:4ea758df868a | 203 | } |
tajiri1999 | 0:4ea758df868a | 204 | |
tajiri1999 | 0:4ea758df868a | 205 | int LPS::testWhoAmI(uint8_t address) |
tajiri1999 | 0:4ea758df868a | 206 | { |
tajiri1999 | 0:4ea758df868a | 207 | char command = WHO_AM_I; |
tajiri1999 | 0:4ea758df868a | 208 | char status = 0; |
tajiri1999 | 0:4ea758df868a | 209 | _i2c.write(address << 1,&command,1); |
tajiri1999 | 0:4ea758df868a | 210 | _i2c.read((address << 1)| 1,&status,1); |
tajiri1999 | 0:4ea758df868a | 211 | return status; |
tajiri1999 | 0:4ea758df868a | 212 | } |