Library to read from Keller Druck I2C Pressure sensors. Inputs are I2C object and address.

Dependents:   TestBenchSerenity-proto_F429ZI TestBenchFlow HSPFLOW1 TestBenchFlow1 ... more

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?

UserRevisionLine numberNew 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, &regAddress, 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 }