you can use LPS25HB sensor on mbed.

Dependents:   cansattougoutest mbed_LPS25HB koubousattttttttttttttttttttttdddddyorooooo koubousattttttttttttttttttttttddooaass ... more

Committer:
tajiri1999
Date:
Sat Dec 22 16:44:40 2018 +0000
Revision:
0:4ea758df868a
LPS25HB_i2c for mbed

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 }
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,&reg,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 }