diff --git a/src/htu21d/htu21d.cpp b/src/htu21d/htu21d.cpp index 540d381d..3dc5cc19 100644 --- a/src/htu21d/htu21d.cpp +++ b/src/htu21d/htu21d.cpp @@ -27,6 +27,7 @@ #include #include +#include #include "htu21d.hpp" @@ -52,7 +53,7 @@ HTU21D::HTU21D(int bus, int devAddr) : m_i2ControlCtx(bus) { void HTU21D::resetSensor(void) { - uint8_t data; + uint8_t data = HTU21D_SOFT_RESET; m_i2ControlCtx.address (m_controlAddr); m_i2ControlCtx.write (&data, 1); usleep(20000); @@ -71,7 +72,7 @@ HTU21D::convertTemp(int32_t regval) * Convert register value to %RH * 1000 */ int32_t -HTU21D::convertRH(int regval) +HTU21D::convertRH(int32_t regval) { return ((15625 * (regval & 0xFFFC)) >> 13) - 6000; } @@ -81,13 +82,13 @@ HTU21D::sampleData(void) { uint32_t itemp; - itemp = i2cReadReg_16(HTU21D_READ_TEMP_HOLD); + itemp = be16toh(i2cReadReg_16(HTU21D_READ_TEMP_HOLD)); m_temperature = convertTemp(itemp); - itemp = i2cReadReg_16(HTU21D_READ_HUMIDITY_HOLD); + itemp = be16toh(i2cReadReg_16(HTU21D_READ_HUMIDITY_HOLD)); m_humidity = convertRH(itemp); - return 0; + return itemp == 0xFFFF; } float @@ -139,6 +140,55 @@ HTU21D::setHeater(int bEnable) return 0; } +/* + * Use the equation from the datasheet to calculate the partial pressure + * and then calculate the dew point temperature in degree C. Typical + * use would be after reading the temp and humidity the partial + * pressure can be caculated using the previously read values. + */ + +float +HTU21D::getDewPoint(int bSampleData) +{ + if (bSampleData) { + sampleData(); + } + + float fA = 8.1332; + float fB = 1762.39; + float fC = 235.66; + float fT = getTemperature(false); + float fRH = getHumidity(false); + float fPP = exp10(fA - (fB / (fT + fC))); + float fDP = -(fB / (log10(fRH * fPP / 100) - fA) + fC); + + return (fDP); +} + +/* + * Function to optimize reading of values from the device. + * This function will always initiate a read from the sensor + * and return the values and dew point calculated value + */ + +int +HTU21D::getHumidityData(float* pfHum, float* pfHumTemp, float* pfDewPt) +{ + float fHum = getHumidity(true); + float fTemp = getTemperature(false); + float fDewPt = getDewPoint(false); + float fCHum = getCompRH(false); + + if (pfHum) + *pfHum = fCHum; + if (pfHumTemp) + *pfHumTemp = fTemp; + if (pfDewPt) + *pfDewPt = fDewPt; + + return 0; +} + /* * Test function: when reading the HTU21D many times rapidly should * result in a temperature increase. This test will verify that the @@ -223,9 +273,7 @@ uint16_t HTU21D::i2cReadReg_16 (int reg) { uint16_t data; m_i2ControlCtx.address(m_controlAddr); - data = (uint16_t)m_i2ControlCtx.readReg(reg) << 8; - data |= (uint16_t)m_i2ControlCtx.readReg(reg+1); - return data; + return m_i2ControlCtx.readWordReg(reg); } uint8_t diff --git a/src/htu21d/htu21d.hpp b/src/htu21d/htu21d.hpp index 910d351b..55de56e4 100644 --- a/src/htu21d/htu21d.hpp +++ b/src/htu21d/htu21d.hpp @@ -86,12 +86,11 @@ class HTU21D { * * @param bus Number of the used bus * @param devAddr Address of the used I2C device - * @param mode HTU21D oversampling */ HTU21D (int bus, int devAddr=HTU21D_I2C_ADDRESS); /** - * Initiates a temperature/pressure mesasurement and waits for the function + * Initiates a temperature/pressure mesasurement and waits * to complete. The humidity and temperature registers can be read * after this call. */ @@ -99,11 +98,17 @@ class HTU21D { /** * Gets the current measured humidity [RH] + * + * @param bSampleData Flag to read sensor + * @return The humidity sensor temp in degC */ float getHumidity(int bSampleData = false); /** * Gets the humidity cell temperature [degC] + * + * @param bSampleData Flag to read sensor + * @return The humidity sensor temp in degC */ float getTemperature(int bSampleData = false); @@ -111,8 +116,31 @@ class HTU21D { * Using the current humidity and temperature, the function * calculates the compensated RH using the equation from * the datasheet. + * + * @param bSampleData Flag to read sensor */ - float getCompRH(int bSampleData = true); + float getCompRH(int bSampleData = false); + + /** + * Using the current humidity and temperature the function + * will calculate the dew point in degreeC based on equation + * from the datasheet. + * + * @param bSampleData Flag to read sensor + */ + float getDewPoint(int bSampleData = false); + + /** + * Function will attempt to get the best measurement for humidity + * using the heater in cases where humidity is high to keep the + * sesnsor dry. The heater setting is returned + * + * @param fHum pointer to float for relative humidity %RH + * @param fHumTemp pointer to float for temperature degC + * @param fDewPt pointer to float for calculated dew point degC + * @return 0 if success or 1 if sensor is not functioning + */ + int getHumidityData(float* fHum, float* fHumTemp, float* fDewPt); /** * Sets the heater state. The heater is used to test @@ -120,7 +148,8 @@ class HTU21D { * 0.5 to 1.5 degC, and the humidity should decrease. The * testSensor() function below uses the heater. * - * @param bEnable Sets to non-zero to turn the heater on + * @param bEnable Sets to non-zero to turn the heater on + * @return 0 on success */ int setHeater(int bEnable = false); @@ -147,9 +176,11 @@ class HTU21D { mraa::Result i2cWriteReg (uint8_t reg, uint8_t value); /** - * Reads a two-byte register + * Reads a two-byte register. + * Note: byte ordering is hardware specific. * * @param reg Address of the register + * @return Value returned from register */ uint16_t i2cReadReg_16 (int reg); @@ -157,6 +188,7 @@ class HTU21D { * Reads a one-byte register * * @param reg Address of the register + * @return Value returned from register */ uint8_t i2cReadReg_8 (int reg);