Library to read from Keller Druck I2C Pressure sensors. Inputs are I2C object and address.
Dependents: TestBenchSerenity-proto_F429ZI TestBenchFlow HSPFLOW1 TestBenchFlow1 ... more
keller_pressure.cpp@9:8df18eb9c0af, 2019-05-06 (annotated)
- Committer:
- dmwahl
- Date:
- Mon May 06 21:19:33 2019 +0000
- Revision:
- 9:8df18eb9c0af
- Parent:
- 8:0d45e94faf0f
6-MAY-2019 Added check on startup to detect whether or not a sensor is plugged in (initFailed bool)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dmwahl | 6:deb4008b136e | 1 | ///----------------------------------------------------------------- |
dmwahl | 6:deb4008b136e | 2 | /// Description: Read from Keller-Druck I2C pressure sensor |
dmwahl | 6:deb4008b136e | 3 | /// Author: David Wahl |
dmwahl | 8:0d45e94faf0f | 4 | /// Date: 5-APR-2018 |
dmwahl | 8:0d45e94faf0f | 5 | /// Notes: Added readP function |
dmwahl | 6:deb4008b136e | 6 | /// |
dmwahl | 6:deb4008b136e | 7 | /// Revision History: |
dmwahl | 9:8df18eb9c0af | 8 | /// Name: Date: Description: |
dmwahl | 9:8df18eb9c0af | 9 | /// 6-MAY-2019 Added check on startup to detect whether or not a sensor is plugged in (initFailed bool) |
dmwahl | 6:deb4008b136e | 10 | ///----------------------------------------------------------------- |
dmwahl | 6:deb4008b136e | 11 | |
dmwahl | 6:deb4008b136e | 12 | |
dmwahl | 3:1a0add40e308 | 13 | // Sample code |
dmwahl | 5:3ac90d95062a | 14 | /* |
dmwahl | 5:3ac90d95062a | 15 | #include <mbed.h> |
dmwahl | 5:3ac90d95062a | 16 | #include "keller_pressure.h" |
dmwahl | 5:3ac90d95062a | 17 | |
dmwahl | 5:3ac90d95062a | 18 | DigitalOut myled(LED1); |
dmwahl | 5:3ac90d95062a | 19 | Serial pc(SERIAL_TX, SERIAL_RX); |
dmwahl | 5:3ac90d95062a | 20 | |
dmwahl | 5:3ac90d95062a | 21 | // an I2C sub-class that provides a constructed default |
dmwahl | 5:3ac90d95062a | 22 | class I2CPreInit : public I2C |
dmwahl | 5:3ac90d95062a | 23 | { |
dmwahl | 5:3ac90d95062a | 24 | public: |
dmwahl | 5:3ac90d95062a | 25 | I2CPreInit(PinName sda, PinName scl, int freq) : I2C(sda, scl) { |
dmwahl | 5:3ac90d95062a | 26 | frequency(freq); |
dmwahl | 5:3ac90d95062a | 27 | }; |
dmwahl | 5:3ac90d95062a | 28 | }; |
dmwahl | 5:3ac90d95062a | 29 | //I2CPreInit gI2C1(I2C_SDA, I2C_SCL, I2C frequency); |
dmwahl | 6:deb4008b136e | 30 | I2CPreInit i2c(PB_9, PB_8, 100000); |
dmwahl | 5:3ac90d95062a | 31 | KELLER_PRESSURE pumpP(i2c, 0x40); |
dmwahl | 5:3ac90d95062a | 32 | |
dmwahl | 5:3ac90d95062a | 33 | int main() |
dmwahl | 5:3ac90d95062a | 34 | { |
dmwahl | 6:deb4008b136e | 35 | pc.baud(115200); |
dmwahl | 5:3ac90d95062a | 36 | pc.printf("Starting up...\n\r"); |
dmwahl | 5:3ac90d95062a | 37 | if (pumpP.isAvailable()) { |
dmwahl | 5:3ac90d95062a | 38 | pc.printf("ACK\r\n"); |
dmwahl | 5:3ac90d95062a | 39 | pumpP.readPT(); |
dmwahl | 5:3ac90d95062a | 40 | pc.printf("Pmin: %.03f Pmax: %.03f\r\n", pumpP.pmin, pumpP.pmax); |
dmwahl | 5:3ac90d95062a | 41 | pc.printf("Year: %d Month: %d Day: %d Mode: %d\r\n", pumpP.year, pumpP.month, pumpP.day, pumpP.mode); |
dmwahl | 5:3ac90d95062a | 42 | pc.printf("Status: 0x%x\r\n", pumpP.getStatus()); |
dmwahl | 5:3ac90d95062a | 43 | pc.printf("%.02fkPa %.02fpsi %.02fC\r\n", pumpP.pressureKPA, pumpP.pressurePSI, pumpP.temperatureC); |
dmwahl | 5:3ac90d95062a | 44 | } |
dmwahl | 5:3ac90d95062a | 45 | while (1) { |
dmwahl | 5:3ac90d95062a | 46 | // Main loop |
dmwahl | 5:3ac90d95062a | 47 | if (pumpP.isAvailable()) { |
dmwahl | 5:3ac90d95062a | 48 | pumpP.readPT(); |
dmwahl | 5:3ac90d95062a | 49 | pc.printf("%.02fkPa %.02fpsi %.02fC\r\n", pumpP.pressureKPA, pumpP.pressurePSI, pumpP.temperatureC); |
dmwahl | 5:3ac90d95062a | 50 | } |
dmwahl | 5:3ac90d95062a | 51 | wait(1); |
dmwahl | 5:3ac90d95062a | 52 | } |
dmwahl | 5:3ac90d95062a | 53 | } |
dmwahl | 5:3ac90d95062a | 54 | */ |
dmwahl | 3:1a0add40e308 | 55 | // End sample code |
dmwahl | 3:1a0add40e308 | 56 | |
dmwahl | 0:fc5c10fc5a05 | 57 | #include "keller_pressure.h" |
dmwahl | 3:1a0add40e308 | 58 | union { |
dmwahl | 3:1a0add40e308 | 59 | char c[4]; |
dmwahl | 3:1a0add40e308 | 60 | float f; |
dmwahl | 3:1a0add40e308 | 61 | } u; |
dmwahl | 0:fc5c10fc5a05 | 62 | |
dmwahl | 3:1a0add40e308 | 63 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 64 | // Default constructor, input is the I2C address followed by min/max pressures (psi) |
dmwahl | 0:fc5c10fc5a05 | 65 | KELLER_PRESSURE::KELLER_PRESSURE(I2C &i2c, int i2cAddress) : i2c(i2c), mi2cAddress(i2cAddress << 1) |
dmwahl | 3:1a0add40e308 | 66 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 67 | { |
dmwahl | 9:8df18eb9c0af | 68 | // Read scaling factors from sensor. If the sensor doesn't respond, set all outputs to unobtanium values |
dmwahl | 9:8df18eb9c0af | 69 | if (readUserInfo() != 0) { |
dmwahl | 9:8df18eb9c0af | 70 | initFailed = true; |
dmwahl | 9:8df18eb9c0af | 71 | pressureBAR = -1; |
dmwahl | 9:8df18eb9c0af | 72 | pressurePSI = -1; |
dmwahl | 9:8df18eb9c0af | 73 | pressureKPA = -1; |
dmwahl | 9:8df18eb9c0af | 74 | temperatureC = -273.15; |
dmwahl | 9:8df18eb9c0af | 75 | temperatureF = -459.67; |
dmwahl | 9:8df18eb9c0af | 76 | } else { |
dmwahl | 9:8df18eb9c0af | 77 | initFailed = false; |
dmwahl | 9:8df18eb9c0af | 78 | } |
dmwahl | 0:fc5c10fc5a05 | 79 | }; |
dmwahl | 0:fc5c10fc5a05 | 80 | |
dmwahl | 3:1a0add40e308 | 81 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 82 | KELLER_PRESSURE::~KELLER_PRESSURE() |
dmwahl | 3:1a0add40e308 | 83 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 84 | { |
dmwahl | 0:fc5c10fc5a05 | 85 | } |
dmwahl | 0:fc5c10fc5a05 | 86 | |
dmwahl | 3:1a0add40e308 | 87 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 88 | // Write out a single address byte to I2C bus, if the sensor returns an ACK the function returns true. |
dmwahl | 0:fc5c10fc5a05 | 89 | bool KELLER_PRESSURE::isAvailable() |
dmwahl | 3:1a0add40e308 | 90 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 91 | { |
dmwahl | 0:fc5c10fc5a05 | 92 | uint8_t i = false; |
dmwahl | 0:fc5c10fc5a05 | 93 | i2c.start(); |
dmwahl | 0:fc5c10fc5a05 | 94 | i = i2c.write(mi2cAddress|I2C_WRITE); |
dmwahl | 0:fc5c10fc5a05 | 95 | i2c.stop(); |
dmwahl | 0:fc5c10fc5a05 | 96 | if (i == 1) { |
dmwahl | 0:fc5c10fc5a05 | 97 | return true; |
dmwahl | 0:fc5c10fc5a05 | 98 | } else { |
dmwahl | 0:fc5c10fc5a05 | 99 | return false; |
dmwahl | 0:fc5c10fc5a05 | 100 | } |
dmwahl | 0:fc5c10fc5a05 | 101 | } |
dmwahl | 0:fc5c10fc5a05 | 102 | |
dmwahl | 3:1a0add40e308 | 103 | //=========================================================================== |
dmwahl | 3:1a0add40e308 | 104 | // Read out status byte from sensor. First byte after any read request is status, |
dmwahl | 3:1a0add40e308 | 105 | // following bytes are pressure/temperature. |
dmwahl | 0:fc5c10fc5a05 | 106 | char KELLER_PRESSURE::getStatus() |
dmwahl | 3:1a0add40e308 | 107 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 108 | { |
dmwahl | 0:fc5c10fc5a05 | 109 | char result = 0xFF; |
dmwahl | 0:fc5c10fc5a05 | 110 | i2c.start(); |
dmwahl | 0:fc5c10fc5a05 | 111 | i2c.write(mi2cAddress|I2C_READ); |
dmwahl | 0:fc5c10fc5a05 | 112 | result = i2c.read(0); |
dmwahl | 0:fc5c10fc5a05 | 113 | i2c.stop(); |
dmwahl | 0:fc5c10fc5a05 | 114 | return result; |
dmwahl | 0:fc5c10fc5a05 | 115 | } |
dmwahl | 0:fc5c10fc5a05 | 116 | |
dmwahl | 3:1a0add40e308 | 117 | //=========================================================================== |
dmwahl | 3:1a0add40e308 | 118 | // Read pressure and temperature. Return 1 if error, 0 if OK. |
dmwahl | 3:1a0add40e308 | 119 | // Byte 1: status, Bytes 2-3: pressure, Bytes 4-5: temperature |
dmwahl | 3:1a0add40e308 | 120 | char KELLER_PRESSURE::readPT() |
dmwahl | 3:1a0add40e308 | 121 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 122 | { |
dmwahl | 3:1a0add40e308 | 123 | char error = 0; |
dmwahl | 0:fc5c10fc5a05 | 124 | char data[5]; |
dmwahl | 3:1a0add40e308 | 125 | |
dmwahl | 3:1a0add40e308 | 126 | error |= _read_multibyte(KELLER_PRESSURE_REQUEST_MEASUREMENT, data, 5); |
dmwahl | 0:fc5c10fc5a05 | 127 | status = data[0]; |
dmwahl | 0:fc5c10fc5a05 | 128 | pressure = (data[1] << 8) | data[2]; |
dmwahl | 0:fc5c10fc5a05 | 129 | temperature = (data[3] << 8) | data[4]; |
dmwahl | 1:805ee7853062 | 130 | |
dmwahl | 0:fc5c10fc5a05 | 131 | pressureBAR = ((pressure - 16384)*(pmax-pmin))/32768+pmin; |
dmwahl | 0:fc5c10fc5a05 | 132 | pressurePSI = pressureBAR*14.5038; |
dmwahl | 0:fc5c10fc5a05 | 133 | pressureKPA = pressureBAR*100; |
dmwahl | 1:805ee7853062 | 134 | |
dmwahl | 0:fc5c10fc5a05 | 135 | temperatureC = (temperature - 384)*0.003125-50; |
dmwahl | 0:fc5c10fc5a05 | 136 | temperatureF = (temperatureC*1.8+32); |
dmwahl | 3:1a0add40e308 | 137 | return error; |
dmwahl | 0:fc5c10fc5a05 | 138 | } |
dmwahl | 0:fc5c10fc5a05 | 139 | |
dmwahl | 3:1a0add40e308 | 140 | //=========================================================================== |
dmwahl | 7:6bca43eedca6 | 141 | // Read pressure only. Return 1 if error, 0 if OK. |
dmwahl | 7:6bca43eedca6 | 142 | // Byte 1: status, Bytes 2-3: pressure |
dmwahl | 7:6bca43eedca6 | 143 | char KELLER_PRESSURE::readP() |
dmwahl | 7:6bca43eedca6 | 144 | //=========================================================================== |
dmwahl | 7:6bca43eedca6 | 145 | { |
dmwahl | 7:6bca43eedca6 | 146 | char error = 0; |
dmwahl | 7:6bca43eedca6 | 147 | char data[3]; |
dmwahl | 7:6bca43eedca6 | 148 | |
dmwahl | 7:6bca43eedca6 | 149 | error |= _read_multibyte(KELLER_PRESSURE_REQUEST_MEASUREMENT, data, 3); |
dmwahl | 7:6bca43eedca6 | 150 | status = data[0]; |
dmwahl | 7:6bca43eedca6 | 151 | pressure = (data[1] << 8) | data[2]; |
dmwahl | 7:6bca43eedca6 | 152 | |
dmwahl | 7:6bca43eedca6 | 153 | pressureBAR = ((pressure - 16384)*(pmax-pmin))/32768+pmin; |
dmwahl | 7:6bca43eedca6 | 154 | pressurePSI = pressureBAR*14.5038; |
dmwahl | 7:6bca43eedca6 | 155 | pressureKPA = pressureBAR*100; |
dmwahl | 7:6bca43eedca6 | 156 | |
dmwahl | 7:6bca43eedca6 | 157 | return error; |
dmwahl | 7:6bca43eedca6 | 158 | } |
dmwahl | 7:6bca43eedca6 | 159 | |
dmwahl | 7:6bca43eedca6 | 160 | //=========================================================================== |
dmwahl | 3:1a0add40e308 | 161 | char KELLER_PRESSURE::readUserInfo() |
dmwahl | 3:1a0add40e308 | 162 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 163 | { |
dmwahl | 3:1a0add40e308 | 164 | char error = 0; |
dmwahl | 0:fc5c10fc5a05 | 165 | char data[3]; |
dmwahl | 4:c298ec31dd93 | 166 | |
dmwahl | 3:1a0add40e308 | 167 | error |= _read_multibyte(KELLER_PRESSURE_CUST_ID0, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 168 | Cust_ID0 = (data[1] << 8) | data[2]; |
dmwahl | 0:fc5c10fc5a05 | 169 | |
dmwahl | 3:1a0add40e308 | 170 | error |= _read_multibyte(KELLER_PRESSURE_CUST_ID1, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 171 | Cust_ID1 = (data[1] << 8) | data[2]; |
dmwahl | 0:fc5c10fc5a05 | 172 | |
dmwahl | 1:805ee7853062 | 173 | // Scaling0 contains date/mode information |
dmwahl | 3:1a0add40e308 | 174 | error |= _read_multibyte(KELLER_PRESSURE_SCALING0, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 175 | Scaling0 = (data[1] << 8) | data[2]; |
dmwahl | 0:fc5c10fc5a05 | 176 | |
dmwahl | 1:805ee7853062 | 177 | //Scaling1 and Scaling2 contain lower pressure limit |
dmwahl | 3:1a0add40e308 | 178 | error |= _read_multibyte(KELLER_PRESSURE_SCALING1, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 179 | Scaling1 = (data[1] << 8) | data[2]; |
dmwahl | 1:805ee7853062 | 180 | u.c[3] = data[1]; |
dmwahl | 1:805ee7853062 | 181 | u.c[2] = data[2]; |
dmwahl | 0:fc5c10fc5a05 | 182 | |
dmwahl | 3:1a0add40e308 | 183 | error |= _read_multibyte(KELLER_PRESSURE_SCALING2, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 184 | Scaling2 = (data[1] << 8) | data[2]; |
dmwahl | 1:805ee7853062 | 185 | u.c[1] = data[1]; |
dmwahl | 1:805ee7853062 | 186 | u.c[0] = data[2]; |
dmwahl | 1:805ee7853062 | 187 | pmin = u.f; |
dmwahl | 0:fc5c10fc5a05 | 188 | |
dmwahl | 1:805ee7853062 | 189 | //Scaling3 and Scaling4 contain upper pressure limit |
dmwahl | 3:1a0add40e308 | 190 | error |= _read_multibyte(KELLER_PRESSURE_SCALING3, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 191 | Scaling3 = (data[1] << 8) | data[2]; |
dmwahl | 1:805ee7853062 | 192 | u.c[3] = data[1]; |
dmwahl | 1:805ee7853062 | 193 | u.c[2] = data[2]; |
dmwahl | 0:fc5c10fc5a05 | 194 | |
dmwahl | 3:1a0add40e308 | 195 | error |= _read_multibyte(KELLER_PRESSURE_SCALING4, data, 3); |
dmwahl | 0:fc5c10fc5a05 | 196 | Scaling4 = (data[1] << 8) | data[2]; |
dmwahl | 1:805ee7853062 | 197 | u.c[1] = data[1]; |
dmwahl | 1:805ee7853062 | 198 | u.c[0] = data[2]; |
dmwahl | 1:805ee7853062 | 199 | pmax = u.f; |
dmwahl | 0:fc5c10fc5a05 | 200 | |
dmwahl | 1:805ee7853062 | 201 | // Read out date of manufacture information and sensor mode |
dmwahl | 0:fc5c10fc5a05 | 202 | year = ((Scaling0 & KELLER_PRESSURE_SCALING0_YEAR_MASK) >> 11) + 2010; |
dmwahl | 0:fc5c10fc5a05 | 203 | month = (Scaling0 & KELLER_PRESSURE_SCALING0_MONTH_MASK) >> 7; |
dmwahl | 0:fc5c10fc5a05 | 204 | day = (Scaling0 & KELLER_PRESSURE_SCALING0_DAY_MASK) >> 2; |
dmwahl | 0:fc5c10fc5a05 | 205 | mode = (Scaling0 & KELLER_PRESSURE_SCALING0_MODE_MASK); |
dmwahl | 0:fc5c10fc5a05 | 206 | |
dmwahl | 3:1a0add40e308 | 207 | return error; |
dmwahl | 0:fc5c10fc5a05 | 208 | } |
dmwahl | 0:fc5c10fc5a05 | 209 | |
dmwahl | 3:1a0add40e308 | 210 | //=========================================================================== |
dmwahl | 3:1a0add40e308 | 211 | char KELLER_PRESSURE::_write(char regAddress, char data) |
dmwahl | 3:1a0add40e308 | 212 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 213 | { |
dmwahl | 3:1a0add40e308 | 214 | char error = 0; |
dmwahl | 3:1a0add40e308 | 215 | char data_write[2] = {regAddress, data}; |
dmwahl | 3:1a0add40e308 | 216 | error |= i2c.write(mi2cAddress|I2C_WRITE, data_write, 1, false); |
dmwahl | 3:1a0add40e308 | 217 | return error; |
dmwahl | 0:fc5c10fc5a05 | 218 | } |
dmwahl | 0:fc5c10fc5a05 | 219 | |
dmwahl | 3:1a0add40e308 | 220 | //=========================================================================== |
dmwahl | 3:1a0add40e308 | 221 | char KELLER_PRESSURE::_read_multibyte(char regAddress, char* data, char count) |
dmwahl | 3:1a0add40e308 | 222 | //=========================================================================== |
dmwahl | 0:fc5c10fc5a05 | 223 | { |
dmwahl | 3:1a0add40e308 | 224 | char error = 0; |
dmwahl | 3:1a0add40e308 | 225 | error |= i2c.write(mi2cAddress|I2C_WRITE, ®Address, 1, false); |
dmwahl | 3:1a0add40e308 | 226 | for (int i = 0; i < 50; i++) { |
dmwahl | 3:1a0add40e308 | 227 | if(getStatus() == KELLER_PRESSURE_MEASUREMENT_DONE) { |
dmwahl | 3:1a0add40e308 | 228 | break; |
dmwahl | 3:1a0add40e308 | 229 | } |
dmwahl | 4:c298ec31dd93 | 230 | wait_us(200); |
dmwahl | 3:1a0add40e308 | 231 | if (i == 49) { |
dmwahl | 4:c298ec31dd93 | 232 | error |= 1; // Timout after 50 attempts |
dmwahl | 3:1a0add40e308 | 233 | } |
dmwahl | 0:fc5c10fc5a05 | 234 | } |
dmwahl | 3:1a0add40e308 | 235 | error |= i2c.read(mi2cAddress|I2C_READ, data, count, false); |
dmwahl | 3:1a0add40e308 | 236 | return error; |
dmwahl | 0:fc5c10fc5a05 | 237 | } |