htu21d: fixed 16-bit i2c reads and added extra functionality

Fixed 16-bit read code to use the correct mraa function to align with
the datasheet.  Added code for dew point calculation and single function
to retreive temp, humidity, and dewpoint.  Other clean up as well.

Signed-off-by: Bill Penner <william.penner@intel.com>
Signed-off-by: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
This commit is contained in:
Bill Penner 2016-08-25 07:37:04 -07:00 committed by Mihai Tudor Panu
parent 372d3e980f
commit 77fbf49f93
2 changed files with 93 additions and 13 deletions

View File

@ -27,6 +27,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <endian.h>
#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

View File

@ -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);