-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHTU21D.cpp
124 lines (101 loc) · 4.51 KB
/
HTU21D.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
HTU21D Humidity Sensor Library
By: Nathan Seidle, since modified by bgbnbigben
SparkFun Electronics
Date: v1.1.3: September 22nd, 2013
v1.2: April 12, 2019
License: This code is public domain but you buy me (Nathan Seidle) a beer if you use this and we meet someday (Beerware license).
This library allows an Arduino to read from the HTU21D low-cost high-precision humidity sensor.
Hardware Setup: The HTU21D lives on the I2C bus. Attach the SDA pin to A4, SCL to A5. If you are using the SparkFun
breakout board you *do not* need 4.7k pull-up resistors on the bus (they are built-in).
Datasheet: https://cdn-shop.adafruit.com/datasheets/1899_HTU21D.pdf
Software:
Call HTU21D.Begin() in setup.
HTU21D.SetResolution(byte: 0b.76543210) sets the resolution of the readings.
HTU21D.check_crc(message, check_value) verifies the 8-bit CRC generated by the sensor
HTU21D.read_user_register() returns the user register. Used to set resolution.
*/
#include <Bridge.h>
#include <Console.h>
#include <I2C.h>
#include "HTU21D.h"
#include "GreenhouseLibraries.h"
HTU21D::HTU21D() : _inFlight(false), _wireValue(0) {}
/* Start I2C communication, and also issues a soft reset command to the humidity sensor (p12)
*
* Uses the global default I2c port if none specified.
*/
void HTU21D::begin(const I2C& wirePort) {
_inFlight = false;
_i2cPort = &wirePort; //Grab which port the user wants us to use
_i2cPort->begin();
_i2cPort->write(HTU21D_ADDRESS, 0xFE); // Write soft reset
}
/** Initiates a new reading, if one currently is not in flight */
inline uint8_t HTU21D::triggerReading(byte cmd) {
if (!_inFlight) {
_inFlight = true;
return _i2cPort->write(HTU21D_ADDRESS, cmd);
}
}
/** Initiates a NO HOLD MASTER temperature reading. It is asynchronous. */
uint8_t HTU21D::triggerTemperatureReading() {
return triggerReading(TRIGGER_TEMP_MEASURE_NOHOLD);
}
/** Initiates a NO HOLD MASTER humidity reading. It is asynchronous. */
uint8_t HTU21D::triggerHumidityReading() {
return triggerReading(TRIGGER_HUMD_MEASURE_NOHOLD);
}
/** Checks to see if the result of the last requested humidity reading has been completed. */
bool HTU21D::isConversionComplete() {
if (!_inFlight) return true;
// resp will be 3 bytes, of the form {msb, lsb|status, checksum}
uint8_t resp[3] = { 0,0,0 };
if (_i2cPort->read(HTU21D_ADDRESS, 3, resp) != 0) return false;
_inFlight = false;
uint16_t rawValue = ((uint16_t)resp[0] << 8) | (uint16_t) resp[1];
resp[0] = __builtin_avr_insert_bits(0x01234567, resp[0], 0);
resp[1] = __builtin_avr_insert_bits(0x01234567, resp[1], 0);
resp[2] = __builtin_avr_insert_bits(0x01234567, resp[2], 0);
if (crc8(resp, 3) != 0) {
_wireValue = 0;
}
else {
_wireValue = rawValue & 0xFFFC; // Zero out bits 43 and 44 (p11), the 'status' bits indicating humidity or temperature response.
}
return true;
}
/** Gets the humidity from the last wire reading. */
float HTU21D::getHumidity() {
// Given the raw humidity data, calculate the actual relative humidity
// rh = wire * (125.0 / 65536.0) - 6.0; //From page 14
return divideFloatByPow2(_wireValue, 16) * 125 - 6;
}
/** Get the temperature from the last wire reading */
float HTU21D::getTemperature() {
// Given the raw temperature data, calculate the actual temperature
// T = wire * (175.72 / 65536.0) - 46.85; //From page 14
return divideFloatByPow2(_wireValue, 16) * 175.72 - 46.85;
}
// Set sensor resolution
/*******************************************************************************************/
// Sets the sensor resolution to one of four levels, determined by the 0th and 7th bit of "resolution"
// From p13, bit 7 controls RH and bit 0 controls Temperature.
// Use the USER_REGISTER_RESOLUTION_RHXX_TEMPYY values
// Default at power-on is 12bit RH 14bit Temp, and a soft-reset command does NOT modify the existing values.
void HTU21D::setResolution(byte resolution) {
// Write out what's already there, with the resolution bits both set to 0 and then or'd with the requested resolution.
// Done inline to prevent the creation of some temporaries in a non-optimising compiler
writeUserRegister((readUserRegister() & B01111110) | (resolution & B10000001));
}
// Read the user register
byte HTU21D::readUserRegister(void) {
byte userRegister;
_i2cPort->write(HTU21D_ADDRESS, READ_USER_REG);
_i2cPort->read(HTU21D_ADDRESS, sizeof userRegister, &userRegister);
return userRegister;
}
void HTU21D::writeUserRegister(byte val) {
_i2cPort->write(HTU21D_ADDRESS, WRITE_USER_REG);
_i2cPort->write(HTU21D_ADDRESS, val);
}