This repository was archived by the owner on May 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHS300x.h
209 lines (169 loc) · 5.6 KB
/
HS300x.h
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*
Module: Catena-HS300x.h
Function:
Definitions for the Catena library for the IDT HS300x sensor family.
Copyright and License:
See accompanying LICENSE file.
Author:
Terry Moore, MCCI Corporation June 2019
*/
#ifndef HS300X_H_
# define HS300X_H_
# pragma once
#include <cstdint>
#include <Wire.h>
namespace HS300x {
/****************************************************************************\
|
| Version boilerplate
|
\****************************************************************************/
// create a version number for comparison
static constexpr std::uint32_t
makeVersion(
std::uint8_t major, std::uint8_t minor, std::uint8_t patch, std::uint8_t local = 0
)
{
return ((std::uint32_t)major << 24u) | ((std::uint32_t)minor << 16u) | ((std::uint32_t)patch << 8u) | (std::uint32_t)local;
}
// extract major number from version
static constexpr std::uint8_t
getMajor(std::uint32_t v)
{
return std::uint8_t(v >> 24u);
}
// extract minor number from version
static constexpr std::uint8_t
getMinor(std::uint32_t v)
{
return std::uint8_t(v >> 16u);
}
// extract patch number from version
static constexpr std::uint8_t
getPatch(std::uint32_t v)
{
return std::uint8_t(v >> 8u);
}
// extract local number from version
static constexpr std::uint8_t
getLocal(std::uint32_t v)
{
return std::uint8_t(v);
}
// version of library, for use by clients in static_asserts
static constexpr std::uint32_t kVersion = makeVersion(0,2,0,0);
/****************************************************************************\
|
| The sensor class.
|
\****************************************************************************/
class cHS300x
{
private:
// control result of isDebug(); use for compiling code in/out.
static constexpr bool kfDebug = false;
// the device i2c address. This is fixed by design.
static constexpr std::int8_t kAddress = 0x44;
// millisec to delay before reading. This is the datasheet "typical"
// value of 16.9, rounded up a little.
static constexpr std::uint32_t kMeasurementDelayMs = 40;
// how many extra millis to wait before giving up on the data.
static constexpr std::uint32_t kGetTemperatureTimeoutMs = 100;
public:
// constructor:
cHS300x(TwoWire &wire)
: m_wire(&wire)
{}
// neither copyable nor movable
cHS300x(const cHS300x&) = delete;
cHS300x& operator=(const cHS300x&) = delete;
cHS300x(const cHS300x&&) = delete;
cHS300x& operator=(const cHS300x&&) = delete;
// convert raw temperature to celsius
static constexpr float rawTtoCelsius(std::uint16_t tfrac)
{
return -40.0f + 165.0f * ((tfrac & 0xFFFC) / float(0xFFFC));
}
// convert raw RH to percent.
static constexpr float rawRHtoPercent(std::uint16_t rhfrac)
{
return 100.0f * ((rhfrac & 0xFFFC) / float(0xFFFC));
}
// convert Celsius temperature to raw format.
/*static constexpr std::uint16_t celsiusToRawT(float t)
{
t += 40.0f;
uint16_t var;
if (t < 0.0f)
return 0;
else if (t > 165.0)
return 0xFFFCu;
else
return (std::uint16_t) ((t / 165.0f) * float(0xFFFC));
}
// convert RH as percentage to raw format.
static constexpr std::uint16_t percentRHtoRaw(float rh)
{
if (rh > 100.0)
return 0xFFFCu;
else if (rh < 0.0)
return 0;
else
return (std::uint16_t) (float(0xFFFC) * (rh / 100.0));
}
*/
// raw measurements as a collection.
struct MeasurementsRaw
{
std::uint16_t TemperatureBits;
std::uint16_t HumidityBits;
void extract(std::uint16_t &a_t, std::uint16_t &a_rh) const
{
a_t = this->TemperatureBits;
a_rh = this->HumidityBits;
}
};
// measurements, as a collection.
struct Measurements
{
float Temperature;
float Humidity;
void set(const MeasurementsRaw &mRaw)
{
this->Temperature = rawTtoCelsius(mRaw.TemperatureBits);
this->Humidity = rawRHtoPercent(mRaw.HumidityBits);
}
void extract(float &a_t, float &a_rh) const
{
a_t = this->Temperature;
a_rh = this->Humidity;
}
};
// Start operation (return true if successful)
bool begin();
// End operation
void end();
// get temperature and humidity as normalized 16-bit fractions
bool getTemperatureHumidityRaw(MeasurementsRaw &mRaw) const;
// get temperature and humidity as floats in engineering units
bool getTemperatureHumidity(Measurements &m) const;
// start a measurement; return the millis to delay before expecting an answer
std::uint32_t startMeasurement(void) const;
// get asynch measurement results, if available.
bool getMeasurementResults(Measurements &m) const;
// get raw measurement results, if available.
bool getMeasurementResultsRaw(MeasurementsRaw &mRaw) const;
// return true if configured for debugging; compile-time constant.
static constexpr bool isDebug() { return kfDebug; }
// return the address; for compatibility.
static constexpr std::int8_t getAddress()
{ return kAddress; }
protected:
// address the device and read an nBuf-byte response.
bool readResponse(std::uint8_t *buf, size_t nBuf) const;
private:
// the I2C bus to use for communication.
TwoWire *m_wire;
};
} // namespace McciCatenaHs300x
#endif /* _CATENA_HS300X_H_ */