you can use LPS25HB sensor on mbed. i2c

Dependents:   read_Pmod optWingforHAPS_Eigen hexaTest_Eigen

Committer:
NaotoMorita
Date:
Thu Sep 01 14:04:43 2022 +0000
Revision:
2:c178d72753dc
Parent:
0:4ea758df868a
os 6

Who changed what in which revision?

UserRevisionLine numberNew 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 }
NaotoMorita 2:c178d72753dc 52 return true;
tajiri1999 0:4ea758df868a 53 }
tajiri1999 0:4ea758df868a 54
tajiri1999 0:4ea758df868a 55 // turns on sensor and enables continuous output
tajiri1999 0:4ea758df868a 56 void LPS::enableDefault(void)
tajiri1999 0:4ea758df868a 57 {
tajiri1999 0:4ea758df868a 58 if (_device == device_25H)
tajiri1999 0:4ea758df868a 59 {
tajiri1999 0:4ea758df868a 60 // 0xB0 = 0b10110000
tajiri1999 0:4ea758df868a 61 // PD = 1 (active mode); ODR = 011 (12.5 Hz pressure & temperature output data rate)
tajiri1999 0:4ea758df868a 62 writeReg(CTRL_REG1, 0xB0);
tajiri1999 0:4ea758df868a 63 }
tajiri1999 0:4ea758df868a 64 else if (_device == device_331AP)
tajiri1999 0:4ea758df868a 65 {
tajiri1999 0:4ea758df868a 66 // 0xE0 = 0b11100000
tajiri1999 0:4ea758df868a 67 // PD = 1 (active mode); ODR = 110 (12.5 Hz pressure & temperature output data rate)
tajiri1999 0:4ea758df868a 68 writeReg(CTRL_REG1, 0xE0);
tajiri1999 0:4ea758df868a 69 }
tajiri1999 0:4ea758df868a 70 }
tajiri1999 0:4ea758df868a 71
tajiri1999 0:4ea758df868a 72 // writes register
tajiri1999 0:4ea758df868a 73 void LPS::writeReg(char reg, char value)
tajiri1999 0:4ea758df868a 74 {
tajiri1999 0:4ea758df868a 75 // if dummy register address, look up actual translated address (based on device type)
tajiri1999 0:4ea758df868a 76 if (reg < 0)
tajiri1999 0:4ea758df868a 77 {
tajiri1999 0:4ea758df868a 78 reg = translated_regs[-reg];
tajiri1999 0:4ea758df868a 79 }
tajiri1999 0:4ea758df868a 80 char command[] = {reg,value};
tajiri1999 0:4ea758df868a 81 _i2c.write(address << 1,command,2);
tajiri1999 0:4ea758df868a 82 }
tajiri1999 0:4ea758df868a 83
tajiri1999 0:4ea758df868a 84 // reads register
tajiri1999 0:4ea758df868a 85 int8_t LPS::readReg(char reg)
tajiri1999 0:4ea758df868a 86 {
tajiri1999 0:4ea758df868a 87 char value;
tajiri1999 0:4ea758df868a 88 // if dummy register address, look up actual translated address (based on device type)
tajiri1999 0:4ea758df868a 89 if(reg < 0)
tajiri1999 0:4ea758df868a 90 {
tajiri1999 0:4ea758df868a 91 reg = translated_regs[-reg];
tajiri1999 0:4ea758df868a 92 }
tajiri1999 0:4ea758df868a 93 _i2c.write(address << 1,&reg,1);
tajiri1999 0:4ea758df868a 94 _i2c.read((address << 1)|1,&value,1);
tajiri1999 0:4ea758df868a 95
tajiri1999 0:4ea758df868a 96 return value;
tajiri1999 0:4ea758df868a 97 }
tajiri1999 0:4ea758df868a 98
tajiri1999 0:4ea758df868a 99 // reads pressure in millibars (mbar)/hectopascals (hPa)
tajiri1999 0:4ea758df868a 100 float LPS::readPressureMillibars(void)
tajiri1999 0:4ea758df868a 101 {
tajiri1999 0:4ea758df868a 102 return (float)readPressureRaw() / 4096;
tajiri1999 0:4ea758df868a 103 }
tajiri1999 0:4ea758df868a 104
tajiri1999 0:4ea758df868a 105 // reads pressure in inches of mercury (inHg)
tajiri1999 0:4ea758df868a 106 float LPS::readPressureInchesHg(void)
tajiri1999 0:4ea758df868a 107 {
tajiri1999 0:4ea758df868a 108 return (float)readPressureRaw() / 138706.5;
tajiri1999 0:4ea758df868a 109 }
tajiri1999 0:4ea758df868a 110
tajiri1999 0:4ea758df868a 111 // reads pressure and returns raw 24-bit sensor output
tajiri1999 0:4ea758df868a 112 int32_t LPS::readPressureRaw(void)
tajiri1999 0:4ea758df868a 113 {
tajiri1999 0:4ea758df868a 114 // assert MSB to enable register address auto-increment
tajiri1999 0:4ea758df868a 115
tajiri1999 0:4ea758df868a 116 char command = PRESS_OUT_XL | (1 << 7);
tajiri1999 0:4ea758df868a 117 char p[3];
tajiri1999 0:4ea758df868a 118 _i2c.write(address << 1,&command,1);
tajiri1999 0:4ea758df868a 119 _i2c.read((address << 1)| 1,p,3);
tajiri1999 0:4ea758df868a 120
tajiri1999 0:4ea758df868a 121 // combine int8_ts
tajiri1999 0:4ea758df868a 122 return (int32_t)(int8_t)p[2] << 16 | (uint16_t)p[1] << 8 | p[0];
tajiri1999 0:4ea758df868a 123 }
tajiri1999 0:4ea758df868a 124
tajiri1999 0:4ea758df868a 125 // reads temperature in degrees C
tajiri1999 0:4ea758df868a 126 float LPS::readTemperatureC(void)
tajiri1999 0:4ea758df868a 127 {
tajiri1999 0:4ea758df868a 128 return 42.5 + (float)readTemperatureRaw() / 480;
tajiri1999 0:4ea758df868a 129 }
tajiri1999 0:4ea758df868a 130
tajiri1999 0:4ea758df868a 131 // reads temperature in degrees F
tajiri1999 0:4ea758df868a 132 float LPS::readTemperatureF(void)
tajiri1999 0:4ea758df868a 133 {
tajiri1999 0:4ea758df868a 134 return 108.5 + (float)readTemperatureRaw() / 480 * 1.8;
tajiri1999 0:4ea758df868a 135 }
tajiri1999 0:4ea758df868a 136
tajiri1999 0:4ea758df868a 137 // reads temperature and returns raw 16-bit sensor output
tajiri1999 0:4ea758df868a 138 int16_t LPS::readTemperatureRaw(void)
tajiri1999 0:4ea758df868a 139 {
tajiri1999 0:4ea758df868a 140 char command = TEMP_OUT_L | (1 << 7);
tajiri1999 0:4ea758df868a 141
tajiri1999 0:4ea758df868a 142 // assert MSB to enable register address auto-increment
tajiri1999 0:4ea758df868a 143 char t[2];
tajiri1999 0:4ea758df868a 144 _i2c.write(address << 1,&command,1);
tajiri1999 0:4ea758df868a 145 _i2c.read((address << 1)| 1,t,2);
tajiri1999 0:4ea758df868a 146
tajiri1999 0:4ea758df868a 147 // combine bytes
tajiri1999 0:4ea758df868a 148 return (int16_t)(t[1] << 8 | t[0]);
tajiri1999 0:4ea758df868a 149 }
tajiri1999 0:4ea758df868a 150
tajiri1999 0:4ea758df868a 151 // converts pressure in mbar to altitude in meters, using 1976 US
tajiri1999 0:4ea758df868a 152 // Standard Atmosphere model (note that this formula only applies to a
tajiri1999 0:4ea758df868a 153 // height of 11 km, or about 36000 ft)
tajiri1999 0:4ea758df868a 154 // If altimeter setting (QNH, barometric pressure adjusted to sea
tajiri1999 0:4ea758df868a 155 // level) is given, this function returns an indicated altitude
tajiri1999 0:4ea758df868a 156 // compensated for actual regional pressure; otherwise, it returns
tajiri1999 0:4ea758df868a 157 // the pressure altitude above the standard pressure level of 1013.25
tajiri1999 0:4ea758df868a 158 // mbar or 29.9213 inHg
tajiri1999 0:4ea758df868a 159 float LPS::pressureToAltitudeMeters(double pressure_mbar, double altimeter_setting_mbar)
tajiri1999 0:4ea758df868a 160 {
tajiri1999 0:4ea758df868a 161 return (1 - pow(pressure_mbar / altimeter_setting_mbar, 0.190263)) * 44330.8;//pressure;
tajiri1999 0:4ea758df868a 162 }
tajiri1999 0:4ea758df868a 163
tajiri1999 0:4ea758df868a 164 // converts pressure in inHg to altitude in feet; see notes above
tajiri1999 0:4ea758df868a 165 float LPS::pressureToAltitudeFeet(double pressure_inHg, double altimeter_setting_inHg)
tajiri1999 0:4ea758df868a 166 {
tajiri1999 0:4ea758df868a 167 return (1 - pow(pressure_inHg / altimeter_setting_inHg, 0.190263)) * 145442;//pressure;
tajiri1999 0:4ea758df868a 168 }
tajiri1999 0:4ea758df868a 169
tajiri1999 0:4ea758df868a 170 // Private Methods ///////////////////////////////////////////////////
tajiri1999 0:4ea758df868a 171
tajiri1999 0:4ea758df868a 172 bool LPS::detectDeviceAndAddress(deviceType device, sa0State sa0)
tajiri1999 0:4ea758df868a 173 {
tajiri1999 0:4ea758df868a 174 if (sa0 == sa0_auto || sa0 == sa0_high)
tajiri1999 0:4ea758df868a 175 {
tajiri1999 0:4ea758df868a 176 address = SA0_HIGH_ADDRESS;
tajiri1999 0:4ea758df868a 177 if (detectDevice(device)) return true;
tajiri1999 0:4ea758df868a 178 }
tajiri1999 0:4ea758df868a 179 if (sa0 == sa0_auto || sa0 == sa0_low)
tajiri1999 0:4ea758df868a 180 {
tajiri1999 0:4ea758df868a 181 address = SA0_LOW_ADDRESS;
tajiri1999 0:4ea758df868a 182 if (detectDevice(device)) return true;
tajiri1999 0:4ea758df868a 183 }
tajiri1999 0:4ea758df868a 184
tajiri1999 0:4ea758df868a 185 return false;
tajiri1999 0:4ea758df868a 186 }
tajiri1999 0:4ea758df868a 187
tajiri1999 0:4ea758df868a 188 bool LPS::detectDevice(deviceType device)
tajiri1999 0:4ea758df868a 189 {
tajiri1999 0:4ea758df868a 190 uint8_t id = testWhoAmI(address);
tajiri1999 0:4ea758df868a 191
tajiri1999 0:4ea758df868a 192 if ((device == device_auto || device == device_25H) && id == (uint8_t)LPS25H_WHO_ID)
tajiri1999 0:4ea758df868a 193 {
tajiri1999 0:4ea758df868a 194 _device = device_25H;
tajiri1999 0:4ea758df868a 195 return true;
tajiri1999 0:4ea758df868a 196 }
tajiri1999 0:4ea758df868a 197 if ((device == device_auto || device == device_331AP) && id == (uint8_t)LPS331AP_WHO_ID)
tajiri1999 0:4ea758df868a 198 {
tajiri1999 0:4ea758df868a 199 _device = device_331AP;
tajiri1999 0:4ea758df868a 200 return true;
tajiri1999 0:4ea758df868a 201 }
tajiri1999 0:4ea758df868a 202
tajiri1999 0:4ea758df868a 203 return false;
tajiri1999 0:4ea758df868a 204 }
tajiri1999 0:4ea758df868a 205
tajiri1999 0:4ea758df868a 206 int LPS::testWhoAmI(uint8_t address)
tajiri1999 0:4ea758df868a 207 {
tajiri1999 0:4ea758df868a 208 char command = WHO_AM_I;
tajiri1999 0:4ea758df868a 209 char status = 0;
tajiri1999 0:4ea758df868a 210 _i2c.write(address << 1,&command,1);
tajiri1999 0:4ea758df868a 211 _i2c.read((address << 1)| 1,&status,1);
tajiri1999 0:4ea758df868a 212 return status;
tajiri1999 0:4ea758df868a 213 }