mirror of
https://github.com/eclipse/upm.git
synced 2025-03-14 20:47:30 +03:00
htu21d: sensor added
Signed-off-by: William Penner <william.penner@intel.com> Signed-off-by: Brendan Le Foll <brendan.le.foll@intel.com>
This commit is contained in:
parent
9ab215b6fd
commit
b53881a8d6
BIN
docs/images/htu21d.jpeg
Normal file
BIN
docs/images/htu21d.jpeg
Normal file
Binary file not shown.
After Width: | Height: | Size: 134 KiB |
@ -42,6 +42,7 @@ add_executable (joystick12-example joystick12-example.cxx)
|
||||
add_executable (lol-example lol-example.cxx)
|
||||
add_executable (nrf_ble_broadcast-example ble_broadcast.cxx)
|
||||
add_executable (tsl2561-example tsl2561.cxx)
|
||||
add_executable (htu21d-example htu21d.cxx)
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/hmc5883l)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/grove)
|
||||
@ -75,6 +76,7 @@ include_directories (${PROJECT_SOURCE_DIR}/src/lsm303)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/joystick12)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/lol)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/tsl2561)
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src/htu21d)
|
||||
|
||||
target_link_libraries (hmc5883l-example hmc5883l ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (groveled-example grove ${CMAKE_THREAD_LIBS_INIT})
|
||||
@ -120,3 +122,4 @@ target_link_libraries (joystick12-example joystick12 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (lol-example lol ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (nrf_ble_broadcast-example nrf24l01 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (tsl2561-example tsl2561 ${CMAKE_THREAD_LIBS_INIT})
|
||||
target_link_libraries (htu21d-example htu21d ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
72
examples/htu21d.cxx
Executable file
72
examples/htu21d.cxx
Executable file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Author: William Penner <william.penner@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <iostream>
|
||||
#include "htu21d.h"
|
||||
#include <signal.h>
|
||||
|
||||
int doWork = 0;
|
||||
upm::HTU21D *sensor = NULL;
|
||||
|
||||
void
|
||||
sig_handler(int signo)
|
||||
{
|
||||
printf("got signal\n");
|
||||
if (signo == SIGINT) {
|
||||
printf("exiting application\n");
|
||||
doWork = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
//! [Interesting]
|
||||
int32_t humidity = 0;
|
||||
int32_t temperature = 0;
|
||||
int32_t compRH = 0;
|
||||
|
||||
sensor = new upm::HTU21D(0, HTU21D_I2C_ADDRESS);
|
||||
|
||||
while (!doWork) {
|
||||
humidity = sensor->getRHumidity(&temperature);
|
||||
compRH = sensor->getCompRH();
|
||||
|
||||
std::cout << "humidity value = " <<
|
||||
(float)humidity / 1000.0 <<
|
||||
", temperature value = " <<
|
||||
(float)temperature / 1000.0 <<
|
||||
", compensated RH value = " <<
|
||||
(float)compRH / 1000.0 << std::endl;
|
||||
usleep (100000);
|
||||
}
|
||||
//! [Interesting]
|
||||
|
||||
std::cout << "exiting application" << std::endl;
|
||||
|
||||
delete sensor;
|
||||
|
||||
return 0;
|
||||
}
|
5
src/htu21d/CMakeLists.txt
Normal file
5
src/htu21d/CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
||||
set (libname "htu21d")
|
||||
set (libdescription "libupm Humidity Sensor")
|
||||
set (module_src ${libname}.cpp)
|
||||
set (module_h ${libname}.h)
|
||||
upm_module_init()
|
243
src/htu21d/htu21d.cpp
Normal file
243
src/htu21d/htu21d.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Author: William Penner <william.penner@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* This driver supports the HTU21D digital humidity and temperature
|
||||
* sensor. The datasheet is available from:
|
||||
* http://www.meas-spec.com/downloads/HTU21D.pdf
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "htu21d.h"
|
||||
|
||||
using namespace upm;
|
||||
|
||||
HTU21D::HTU21D(int bus, int devAddr) {
|
||||
m_temperature = 0;
|
||||
m_humidity = 0;
|
||||
|
||||
m_name = HTU21D_NAME;
|
||||
|
||||
m_controlAddr = devAddr;
|
||||
m_bus = bus;
|
||||
|
||||
m_i2ControlCtx = mraa_i2c_init(m_bus);
|
||||
|
||||
mraa_result_t ret = mraa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
||||
if (ret != MRAA_SUCCESS) {
|
||||
fprintf(stderr, "Error accessing i2c bus\n");
|
||||
}
|
||||
}
|
||||
|
||||
HTU21D::~HTU21D() {
|
||||
mraa_i2c_stop(m_i2ControlCtx);
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTU21D::htu21_temp_ticks_to_millicelsius(int ticks)
|
||||
{
|
||||
ticks &= ~0x0003; /* clear status bits */
|
||||
/*
|
||||
* Formula T = -46.85 + 175.72 * ST / 2^16 from datasheet p14,
|
||||
* optimized for integer fixed point (3 digits) arithmetic
|
||||
*/
|
||||
return ((21965 * (int32_t)ticks) >> 13) - 46850;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTU21D::htu21_rh_ticks_to_per_cent_mille(int ticks)
|
||||
{
|
||||
ticks &= ~0x0003; /* clear status bits */
|
||||
/*
|
||||
* Formula RH = -6 + 125 * SRH / 2^16 from datasheet p14,
|
||||
* optimized for integer fixed point (3 digits) arithmetic
|
||||
*/
|
||||
return ((15625 * (int32_t)ticks) >> 13) - 6000;
|
||||
}
|
||||
|
||||
int
|
||||
HTU21D::sampleData(void)
|
||||
{
|
||||
uint32_t itemp;
|
||||
|
||||
itemp = i2cReadReg_16(HTU21D_T_MEASUREMENT_HM);
|
||||
m_temperature = htu21_temp_ticks_to_millicelsius(itemp);
|
||||
|
||||
itemp = i2cReadReg_16(HTU21D_RH_MEASUREMENT_HM);
|
||||
m_humidity = htu21_rh_ticks_to_per_cent_mille(itemp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTU21D::getTemperature(void)
|
||||
{
|
||||
return m_temperature;
|
||||
}
|
||||
|
||||
int32_t
|
||||
HTU21D::getHumidity(void)
|
||||
{
|
||||
return m_humidity;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the primary function to read the data. It will initiate
|
||||
* a measurement cycle and will then return both the humidity and
|
||||
* temperature values. piTemperature can be NULL.
|
||||
*/
|
||||
|
||||
int32_t
|
||||
HTU21D::getRHumidity(int32_t* piTemperature)
|
||||
{
|
||||
sampleData();
|
||||
if (NULL != piTemperature)
|
||||
*piTemperature = m_temperature;
|
||||
return m_humidity;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the compensation equation from the datasheet to correct the
|
||||
* current reading
|
||||
* RHcomp = RHactualT + (25 - Tactual) * CoeffTemp
|
||||
* RHcomp is in units of %RH * 1000
|
||||
*/
|
||||
int32_t
|
||||
HTU21D::getCompRH(void)
|
||||
{
|
||||
return m_humidity + (25000 - m_temperature) * 3 / 20;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test function: when reading the HTU21D many times rapidly should
|
||||
* result in a temperature increase. This test will verify that the
|
||||
* value is changing from read to read
|
||||
*/
|
||||
|
||||
int
|
||||
HTU21D::testSensor(void)
|
||||
{
|
||||
int iError = 0;
|
||||
int i, j;
|
||||
int32_t iTemp, iHum;
|
||||
int32_t iTempMax, iTempMin;
|
||||
int32_t iHumMax, iHumMin;
|
||||
int32_t iHumFirst, iTempFirst;
|
||||
|
||||
fprintf(stdout, "Executing Sensor Test.\n Reading registers 100 times to look for operation\n" );
|
||||
|
||||
iHum = getRHumidity(&iTemp);
|
||||
iTempFirst = iTempMax = iTempMin = iTemp;
|
||||
iHumFirst = iHumMax = iHumMin = iHum;
|
||||
|
||||
for (i=0; i < 100; i++) {
|
||||
iHum = getRHumidity(&iTemp);
|
||||
if (iHum < iHumMin) iHumMin = iHum;
|
||||
if (iHum > iHumMax) iHumMax = iHum;
|
||||
if (iTemp < iTempMin) iTempMin = iTemp;
|
||||
if (iTemp > iTempMax) iTempMax = iTemp;
|
||||
// fprintf(stdout, "Temp: %d Humidity: %d\n", iTemp, iHum);
|
||||
}
|
||||
|
||||
if ((iTemp - iTempFirst) <= 0) {
|
||||
fprintf(stdout, "! Temperature should have increased, but didn't\n" );
|
||||
iError++;
|
||||
}
|
||||
|
||||
if (iHumMin == iHumMax) {
|
||||
fprintf(stdout, "! Humidity was unchanged - not working?\n" );
|
||||
iError++;
|
||||
}
|
||||
|
||||
if (iTempMin == iTempMax) {
|
||||
fprintf(stdout, "! Temperature was unchanged - not working?\n" );
|
||||
iError++;
|
||||
}
|
||||
|
||||
if (iError == 0) {
|
||||
fprintf(stdout, " Device appears functional\n" );
|
||||
}
|
||||
|
||||
fprintf(stdout, " Test complete\n" );
|
||||
|
||||
return iError;
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions to read and write data to the i2c device
|
||||
*/
|
||||
|
||||
mraa_result_t
|
||||
HTU21D::i2cReadRegValue(int reg, uint32_t* puint32, int ibytes) {
|
||||
uint32_t data = 0;
|
||||
|
||||
if (ibytes > 4)
|
||||
ibytes = 4;
|
||||
|
||||
mraa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
||||
mraa_i2c_write_byte(m_i2ControlCtx, reg);
|
||||
|
||||
mraa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
||||
mraa_i2c_read(m_i2ControlCtx, (uint8_t *)&data, ibytes);
|
||||
|
||||
fprintf(stdout, "reg data = %08x\n", data);
|
||||
*puint32 = be32toh(data) >> ((4-ibytes) * 8);
|
||||
fprintf(stdout, "reg return = %08x\n", *puint32);
|
||||
|
||||
return MRAA_SUCCESS;
|
||||
}
|
||||
|
||||
mraa_result_t
|
||||
HTU21D::i2cWriteReg (uint8_t reg, uint8_t value) {
|
||||
mraa_result_t error = MRAA_SUCCESS;
|
||||
|
||||
uint8_t data[2] = { reg, value };
|
||||
error = mraa_i2c_address (m_i2ControlCtx, m_controlAddr);
|
||||
error = mraa_i2c_write (m_i2ControlCtx, data, 2);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to read 16 bits starting at reg. This function
|
||||
* was replaced due to functionality of using read() to
|
||||
* access i2c data.
|
||||
*/
|
||||
uint16_t
|
||||
HTU21D::i2cReadReg_16 (int reg) {
|
||||
uint16_t data;
|
||||
mraa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
||||
data = (uint16_t)mraa_i2c_read_byte_data(m_i2ControlCtx, reg) << 8;
|
||||
data |= (uint16_t)mraa_i2c_read_byte_data(m_i2ControlCtx, reg+1);
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function to read 8 bits starting at reg. This function
|
||||
* was replaced due to functionality of using read() to
|
||||
* access i2c data.
|
||||
*/
|
||||
uint8_t
|
||||
HTU21D::i2cReadReg_8 (int reg) {
|
||||
mraa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
||||
return mraa_i2c_read_byte_data(m_i2ControlCtx, reg);
|
||||
}
|
||||
|
169
src/htu21d/htu21d.h
Normal file
169
src/htu21d/htu21d.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Author: William Penner <william.penner@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* Based on code adapted from the kernel HTU21 driver and
|
||||
* code by: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
||||
* Copyright (c) 2014 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mraa/i2c.h>
|
||||
#include <math.h>
|
||||
|
||||
#define HTU21D_NAME "htu21d"
|
||||
#define HTU21D_I2C_ADDRESS 0x40
|
||||
|
||||
/* HTU21 Commands */
|
||||
#define HTU21D_T_MEASUREMENT_HM 0xE3
|
||||
#define HTU21D_RH_MEASUREMENT_HM 0xE5
|
||||
|
||||
namespace upm {
|
||||
|
||||
/**
|
||||
* @brief HTU21D humidity sensor library
|
||||
* @defgroup htu21d libupm-htu21
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief C++ API for HTU21D chip (Atmospheric Pressure Sensor)
|
||||
*
|
||||
* Measurement Specialties [HTU21D]
|
||||
* (http://www.meas-spec.com/downloads/HTU21D.pdf)
|
||||
* is a digital humidity sensor with temperature output.
|
||||
* RH will report between 0 and 100% and temperature range is
|
||||
* -40 to +125 degC
|
||||
*
|
||||
* @ingroup htu21d i2c
|
||||
* @snippet htu21d.cxx Interesting
|
||||
* @image html htu21d.jpeg
|
||||
*/
|
||||
class HTU21D {
|
||||
public:
|
||||
/**
|
||||
* Instanciates a HTU21D object
|
||||
*
|
||||
* @param bus number of used bus
|
||||
* @param devAddr address of used i2c device
|
||||
* @param mode HTU21D oversampling
|
||||
*/
|
||||
HTU21D (int bus=0, int devAddr=HTU21D_I2C_ADDRESS);
|
||||
|
||||
/**
|
||||
* HTU21D object destructor, basicaly it close i2c connection.
|
||||
*/
|
||||
~HTU21D ();
|
||||
|
||||
/**
|
||||
* Initiate a temp/pressure mesasurement and wait for function
|
||||
* to complete. The humidity and temp registers can be read
|
||||
* after this call.
|
||||
*/
|
||||
int sampleData(void);
|
||||
|
||||
/**
|
||||
* Get the current measured humidity [RH * 1000]
|
||||
* To convert to Relative Humidity, divide by 1000
|
||||
*
|
||||
*/
|
||||
int32_t getHumidity(void);
|
||||
|
||||
/**
|
||||
* Get the humidity cell temperature [degC * 1000]
|
||||
* To convert to Temperature, divide by 1000
|
||||
*/
|
||||
int32_t getTemperature(void);
|
||||
|
||||
/**
|
||||
* Reads both temperature and humidity together
|
||||
* To convert to Relative Humidity, divide by 1000
|
||||
* To convert to Temperature, divide by 1000
|
||||
*
|
||||
* @param pointer to int32_t buffer for temp
|
||||
*/
|
||||
int32_t getRHumidity(int32_t* iTemperature);
|
||||
|
||||
/**
|
||||
* Using the current humidity and temperature the function
|
||||
* will calculate the compensated RH using the equation from
|
||||
* the datasheet.
|
||||
*/
|
||||
int32_t getCompRH(void);
|
||||
|
||||
/**
|
||||
* Function intended to test the device and verify it
|
||||
* is correctly operating.
|
||||
*
|
||||
*/
|
||||
int testSensor(void);
|
||||
|
||||
/**
|
||||
* Read 1 to 4 bytes from i2c registers
|
||||
*
|
||||
* @param reg address of a register
|
||||
* @param puint32 pointer to buffer for register data
|
||||
* @param ibytes number of bytes to be returned
|
||||
*/
|
||||
mraa_result_t i2cReadRegValue (int reg, uint32_t* puint32, int ibytes);
|
||||
|
||||
/**
|
||||
* Read two bytes register
|
||||
*
|
||||
* @param reg address of a register
|
||||
*/
|
||||
uint16_t i2cReadReg_16 (int reg);
|
||||
|
||||
/**
|
||||
* Write to one byte register
|
||||
*
|
||||
* @param reg address of a register
|
||||
* @param value byte to be written
|
||||
*/
|
||||
mraa_result_t i2cWriteReg (uint8_t reg, uint8_t value);
|
||||
|
||||
/**
|
||||
* Read one byte register
|
||||
*
|
||||
* @param reg address of a register
|
||||
*/
|
||||
uint8_t i2cReadReg_8 (int reg);
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Convert temp register to value * 1000
|
||||
*/
|
||||
int32_t htu21_temp_ticks_to_millicelsius(int ticks);
|
||||
|
||||
/**
|
||||
* Convert temp register to value * 1000
|
||||
*/
|
||||
int32_t htu21_rh_ticks_to_per_cent_mille(int ticks);
|
||||
|
||||
std::string m_name;
|
||||
|
||||
int m_controlAddr;
|
||||
int m_bus;
|
||||
mraa_i2c_context m_i2ControlCtx;
|
||||
|
||||
int32_t m_temperature;
|
||||
int32_t m_humidity;
|
||||
};
|
||||
|
||||
}
|
8
src/htu21d/jsupm_htu21d.i
Normal file
8
src/htu21d/jsupm_htu21d.i
Normal file
@ -0,0 +1,8 @@
|
||||
%module jsupm_htu21d
|
||||
%include "../upm.i"
|
||||
|
||||
%{
|
||||
#include "htu21d.h"
|
||||
%}
|
||||
|
||||
%include "htu21d.h"
|
13
src/htu21d/pyupm_htu21d.i
Normal file
13
src/htu21d/pyupm_htu21d.i
Normal file
@ -0,0 +1,13 @@
|
||||
%module pyupm_htu21d
|
||||
%include "../upm.i"
|
||||
|
||||
%feature("autodoc", "3");
|
||||
|
||||
#ifdef DOXYGEN
|
||||
%include "htu21d_doc.i"
|
||||
#endif
|
||||
|
||||
%include "htu21d.h"
|
||||
%{
|
||||
#include "htu21d.h"
|
||||
%}
|
Loading…
x
Reference in New Issue
Block a user