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
- Committer:
- dmwahl
- Date:
- 2019-05-06
- Revision:
- 9:8df18eb9c0af
- Parent:
- 8:0d45e94faf0f
File content as of revision 9:8df18eb9c0af:
///----------------------------------------------------------------- /// Description: Read from Keller-Druck I2C pressure sensor /// Author: David Wahl /// Date: 5-APR-2018 /// Notes: Added readP function /// /// Revision History: /// Name: Date: Description: /// 6-MAY-2019 Added check on startup to detect whether or not a sensor is plugged in (initFailed bool) ///----------------------------------------------------------------- // Sample code /* #include <mbed.h> #include "keller_pressure.h" DigitalOut myled(LED1); Serial pc(SERIAL_TX, SERIAL_RX); // an I2C sub-class that provides a constructed default class I2CPreInit : public I2C { public: I2CPreInit(PinName sda, PinName scl, int freq) : I2C(sda, scl) { frequency(freq); }; }; //I2CPreInit gI2C1(I2C_SDA, I2C_SCL, I2C frequency); I2CPreInit i2c(PB_9, PB_8, 100000); KELLER_PRESSURE pumpP(i2c, 0x40); int main() { pc.baud(115200); pc.printf("Starting up...\n\r"); if (pumpP.isAvailable()) { pc.printf("ACK\r\n"); pumpP.readPT(); pc.printf("Pmin: %.03f Pmax: %.03f\r\n", pumpP.pmin, pumpP.pmax); pc.printf("Year: %d Month: %d Day: %d Mode: %d\r\n", pumpP.year, pumpP.month, pumpP.day, pumpP.mode); pc.printf("Status: 0x%x\r\n", pumpP.getStatus()); pc.printf("%.02fkPa %.02fpsi %.02fC\r\n", pumpP.pressureKPA, pumpP.pressurePSI, pumpP.temperatureC); } while (1) { // Main loop if (pumpP.isAvailable()) { pumpP.readPT(); pc.printf("%.02fkPa %.02fpsi %.02fC\r\n", pumpP.pressureKPA, pumpP.pressurePSI, pumpP.temperatureC); } wait(1); } } */ // End sample code #include "keller_pressure.h" union { char c[4]; float f; } u; //=========================================================================== // Default constructor, input is the I2C address followed by min/max pressures (psi) KELLER_PRESSURE::KELLER_PRESSURE(I2C &i2c, int i2cAddress) : i2c(i2c), mi2cAddress(i2cAddress << 1) //=========================================================================== { // Read scaling factors from sensor. If the sensor doesn't respond, set all outputs to unobtanium values if (readUserInfo() != 0) { initFailed = true; pressureBAR = -1; pressurePSI = -1; pressureKPA = -1; temperatureC = -273.15; temperatureF = -459.67; } else { initFailed = false; } }; //=========================================================================== KELLER_PRESSURE::~KELLER_PRESSURE() //=========================================================================== { } //=========================================================================== // Write out a single address byte to I2C bus, if the sensor returns an ACK the function returns true. bool KELLER_PRESSURE::isAvailable() //=========================================================================== { uint8_t i = false; i2c.start(); i = i2c.write(mi2cAddress|I2C_WRITE); i2c.stop(); if (i == 1) { return true; } else { return false; } } //=========================================================================== // Read out status byte from sensor. First byte after any read request is status, // following bytes are pressure/temperature. char KELLER_PRESSURE::getStatus() //=========================================================================== { char result = 0xFF; i2c.start(); i2c.write(mi2cAddress|I2C_READ); result = i2c.read(0); i2c.stop(); return result; } //=========================================================================== // Read pressure and temperature. Return 1 if error, 0 if OK. // Byte 1: status, Bytes 2-3: pressure, Bytes 4-5: temperature char KELLER_PRESSURE::readPT() //=========================================================================== { char error = 0; char data[5]; error |= _read_multibyte(KELLER_PRESSURE_REQUEST_MEASUREMENT, data, 5); status = data[0]; pressure = (data[1] << 8) | data[2]; temperature = (data[3] << 8) | data[4]; pressureBAR = ((pressure - 16384)*(pmax-pmin))/32768+pmin; pressurePSI = pressureBAR*14.5038; pressureKPA = pressureBAR*100; temperatureC = (temperature - 384)*0.003125-50; temperatureF = (temperatureC*1.8+32); return error; } //=========================================================================== // Read pressure only. Return 1 if error, 0 if OK. // Byte 1: status, Bytes 2-3: pressure char KELLER_PRESSURE::readP() //=========================================================================== { char error = 0; char data[3]; error |= _read_multibyte(KELLER_PRESSURE_REQUEST_MEASUREMENT, data, 3); status = data[0]; pressure = (data[1] << 8) | data[2]; pressureBAR = ((pressure - 16384)*(pmax-pmin))/32768+pmin; pressurePSI = pressureBAR*14.5038; pressureKPA = pressureBAR*100; return error; } //=========================================================================== char KELLER_PRESSURE::readUserInfo() //=========================================================================== { char error = 0; char data[3]; error |= _read_multibyte(KELLER_PRESSURE_CUST_ID0, data, 3); Cust_ID0 = (data[1] << 8) | data[2]; error |= _read_multibyte(KELLER_PRESSURE_CUST_ID1, data, 3); Cust_ID1 = (data[1] << 8) | data[2]; // Scaling0 contains date/mode information error |= _read_multibyte(KELLER_PRESSURE_SCALING0, data, 3); Scaling0 = (data[1] << 8) | data[2]; //Scaling1 and Scaling2 contain lower pressure limit error |= _read_multibyte(KELLER_PRESSURE_SCALING1, data, 3); Scaling1 = (data[1] << 8) | data[2]; u.c[3] = data[1]; u.c[2] = data[2]; error |= _read_multibyte(KELLER_PRESSURE_SCALING2, data, 3); Scaling2 = (data[1] << 8) | data[2]; u.c[1] = data[1]; u.c[0] = data[2]; pmin = u.f; //Scaling3 and Scaling4 contain upper pressure limit error |= _read_multibyte(KELLER_PRESSURE_SCALING3, data, 3); Scaling3 = (data[1] << 8) | data[2]; u.c[3] = data[1]; u.c[2] = data[2]; error |= _read_multibyte(KELLER_PRESSURE_SCALING4, data, 3); Scaling4 = (data[1] << 8) | data[2]; u.c[1] = data[1]; u.c[0] = data[2]; pmax = u.f; // Read out date of manufacture information and sensor mode year = ((Scaling0 & KELLER_PRESSURE_SCALING0_YEAR_MASK) >> 11) + 2010; month = (Scaling0 & KELLER_PRESSURE_SCALING0_MONTH_MASK) >> 7; day = (Scaling0 & KELLER_PRESSURE_SCALING0_DAY_MASK) >> 2; mode = (Scaling0 & KELLER_PRESSURE_SCALING0_MODE_MASK); return error; } //=========================================================================== char KELLER_PRESSURE::_write(char regAddress, char data) //=========================================================================== { char error = 0; char data_write[2] = {regAddress, data}; error |= i2c.write(mi2cAddress|I2C_WRITE, data_write, 1, false); return error; } //=========================================================================== char KELLER_PRESSURE::_read_multibyte(char regAddress, char* data, char count) //=========================================================================== { char error = 0; error |= i2c.write(mi2cAddress|I2C_WRITE, ®Address, 1, false); for (int i = 0; i < 50; i++) { if(getStatus() == KELLER_PRESSURE_MEASUREMENT_DONE) { break; } wait_us(200); if (i == 49) { error |= 1; // Timout after 50 attempts } } error |= i2c.read(mi2cAddress|I2C_READ, data, count, false); return error; }