1765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/*
2765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Author: William Penner <william.penner@intel.com>
3765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Copyright (c) 2014 Intel Corporation.
4765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
5765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Permission is hereby granted, free of charge, to any person obtaining a copy
6765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * of this software and associated documentation files (the "Software"), to deal
7765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * in the Software without restriction, including without limitation the rights
8765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * copies of the Software, and to permit persons to whom the Software is
10765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * furnished to do so, subject to the following conditions:
11765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
12765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * The above copyright notice and this permission notice shall be included in
13765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * all copies or substantial portions of the Software.
14765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
15765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * THE SOFTWARE.
22765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
23765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
24765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#pragma once
25765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
26765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <string>
27765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <mraa/i2c.hpp>
28765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#include <math.h>
29765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
30765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_NAME "htu21d"
31765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_I2C_ADDRESS 0x40
32765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
33765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* HTU21D Commands */
34765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_READ_TEMP_HOLD     0xE3
35765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_READ_HUMIDITY_HOLD 0xE5
36765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_WRITE_USER_REG     0xE6
37765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_READ_USER_REG      0xE7
38765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_SOFT_RESET         0xFE
39765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
40765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/* User Register Bit Definition */
41765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_DISABLE_OTP        0x02
42765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_HEATER_ENABLE      0x04
43765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_END_OF_BATTERY     0x40
44765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_RESO_RH12_T14      0x00
45765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_RESO_RH8_T12       0x01
46765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_RESO_RH10_T13      0x80
47765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang#define HTU21D_RESO_RH11_T11      0x81
48765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
49765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangnamespace upm {
50765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
51765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/**
52765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @brief HTU21D Humidity Sensor library
53765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @defgroup htu21d libupm-htu21d
54765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @ingroup seeed adafruit sparkfun i2c temp
55765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
56765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
57765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang/**
58765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @library htu21d
59765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @sensor htu21d
60765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @comname HTU21D Temperature & Humidity Sensor
61765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @type temp
62765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @man seeed adafruit sparkfun
63765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @web http://www.meas-spec.com/downloads/HTU21D.pdf
64765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @con i2c
65765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
66765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @brief API for the HTU21D Temperature & Humidity Sensor
67765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
68765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * HTU21D by Measurement Specialties is a digital humidity sensor with
69765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * temperature output.
70765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * RH reports between 0 and 100%, and the temperature range is
71765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * -40 to +125 degC. Note: getCompRH is the preferred
72765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * function below (passing true to cause a measurement cycle). If
73765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * actual values used for the compensated ready are necessary, use
74765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * the getHumidity(false) and getTemperature(false) functions following
75765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * the getCompRH call.
76765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * Also note the sensor should not perform more than a couple of
77765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * measurements per second to limit the heating of the sensor.
78765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang *
79765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @image html htu21d.jpeg
80765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang * @snippet htu21d.cxx Interesting
81765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang */
82765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhangclass HTU21D {
83765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    public:
84765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
85765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Instantiates an HTU21D object
86765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
87765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param bus Number of the used bus
88765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param devAddr Address of the used I2C device
89765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param mode HTU21D oversampling
90765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
91765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        HTU21D (int bus, int devAddr=HTU21D_I2C_ADDRESS);
92765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
93765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
94765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Initiates a temperature/pressure mesasurement and waits for the function
95765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * to complete. The humidity and temperature registers can be read
96765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * after this call.
97765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
98765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int sampleData(void);
99765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
100765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
101765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Gets the current measured humidity [RH]
102765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
103765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        float getHumidity(int bSampleData = false);
104765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
105765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
106765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Gets the humidity cell temperature [degC]
107765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
108765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        float getTemperature(int bSampleData = false);
109765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
110765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
111765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Using the current humidity and temperature, the function
112765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * calculates the compensated RH using the equation from
113765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * the datasheet.
114765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
115765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        float getCompRH(int bSampleData = true);
116765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
117765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
118765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Sets the heater state. The heater is used to test
119765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * the sensor functionality since the temperature should increase
120765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * 0.5 to 1.5 degC, and the humidity should decrease. The
121765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * testSensor() function below uses the heater.
122765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
123765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param bEnable Sets to non-zero to turn the heater on
124765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
125765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         int setHeater(int bEnable = false);
126765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
127765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
128765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Performs a soft reset of the MPL3115A2 device to ensure
129765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * it is in a known state. This function can be used to reset
130765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * the min/max temperature and pressure values.
131765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
132765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        void resetSensor(void);
133765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
134765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
135765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Tests the device and verifies it
136765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * is operating correctly.
137765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
138765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
139765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int testSensor(void);
140765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
141765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
142765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Writes to a one-byte register
143765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
144765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param reg Address of the register
145765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param value Byte to be written
146765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
147765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        mraa::Result i2cWriteReg (uint8_t reg, uint8_t value);
148765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
149765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
150765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Reads a two-byte register
151765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
152765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param reg Address of the register
153765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
154765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        uint16_t i2cReadReg_16 (int reg);
155765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
156765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
157765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Reads a one-byte register
158765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         *
159765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * @param reg Address of the register
160765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
161765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        uint8_t i2cReadReg_8 (int reg);
162765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
163765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang    private:
164765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
165765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
166765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Converts the temperature register to degC * 1000
167765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
168765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int32_t convertTemp(int32_t regval);
169765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
170765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        /**
171765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         * Converts the RH register to %RH * 1000
172765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang         */
173765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int32_t convertRH(int32_t regval);
174765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
175765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        std::string m_name;
176765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
177765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int m_controlAddr;
178765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int m_bus;
179765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        mraa::I2c m_i2ControlCtx;
180765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
181765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int32_t m_temperature;
182765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang        int32_t m_humidity;
183765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang};
184765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang
185765adb95dc941c32690d6c43bc08b9d07d197fcbJianxun Zhang}
186