Skip to content

Commit 40500b4

Browse files
committed
sns(dht): another dht22 variant w/ 12bit values
1 parent 7476793 commit 40500b4

File tree

2 files changed

+73
-8
lines changed

2 files changed

+73
-8
lines changed

code/espurna/sensors/DHTSensor.h

+23-8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@ float dht_humidity(DHTChipType type, std::array<uint8_t, 2> pair) {
8282
return out;
8383
}
8484

85+
float dht_raw_impl(std::array<uint8_t, 2> pair) {
86+
int16_t out;
87+
88+
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
89+
std::swap(pair[0], pair[1]);
90+
#endif
91+
std::memcpy(&out, pair.data(), sizeof(out));
92+
93+
return out;
94+
}
95+
8596
float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
8697
// binary representation varies between the original chip and its copies
8798
// by default, check for generic sign-magnitude
@@ -92,6 +103,11 @@ float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
92103
// it is enough to only check the sign bit neighbour; possible values are around [0...800]
93104
constexpr auto NegativeTwoComplementMask = uint8_t{ 0b11000000 };
94105

106+
// another case is 12bit value instead of full 16bit
107+
// in case of negative numbers we'd have to extend it to full 16bit
108+
constexpr auto ShortVoidMask = uint8_t{ 0b11111000 };
109+
constexpr auto ShortSignMask = uint8_t{ 0b00001000 };
110+
95111
float out;
96112

97113
switch (type) {
@@ -122,15 +138,14 @@ float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
122138
case DHT_CHIP_DHT22:
123139
case DHT_CHIP_AM2301:
124140
case DHT_CHIP_SI7021:
125-
// special exception for negative numbers in twos-complement
141+
// negative numbers in twos-complement
126142
if ((pair[0] & NegativeTwoComplementMask) == NegativeTwoComplementMask) {
127-
int16_t tmp;
128-
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
129-
std::swap(pair[0], pair[1]);
130-
#endif
131-
std::memcpy(&tmp, pair.data(), sizeof(tmp));
132-
out = tmp;
133-
// fallback works both for the original chips and positive numbers
143+
out = dht_raw_impl(pair);
144+
// 12bit numbers have to be extended first
145+
} else if ((pair[0] & ShortVoidMask) == ShortSignMask) {
146+
pair[0] |= ShortVoidMask;
147+
out = dht_raw_impl(pair);
148+
// otherwise, use the standard copy
134149
} else {
135150
out = ((pair[0] & MagnitudeMask) << 8) | pair[1];
136151
if (pair[0] & SignMask) {

code/test/unit/src/sensor/sensor.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,19 @@
1515
// TODO is ..._SUPPORT wrapping necessary inside of sensor includes?
1616
// TODO ..._PORT should not be used in the class itself?
1717

18+
// TODO ignore -Wunused-value that comes up here from interrupts() / noInterrupts() usage
19+
#undef xt_rsil
20+
#define xt_rsil(X)
21+
1822
#define SENSOR_SUPPORT 1
1923
#define CSE7766_SUPPORT 1
2024
#define A02YYU_SUPPORT 1
25+
#define DHT_SUPPORT 1
2126

2227
#include <espurna/config/sensors.h>
2328
#include <espurna/sensors/CSE7766Sensor.h>
2429
#include <espurna/sensors/A02YYUSensor.h>
30+
#include <espurna/sensors/DHTSensor.h>
2531

2632
#include <memory>
2733
#include <vector>
@@ -193,6 +199,49 @@ void test_a02yyu_data() {
193199
TEST_ASSERT_EQUAL_DOUBLE(1.953, ptr->value(0));
194200
}
195201

202+
void test_dht_data() {
203+
constexpr auto a = 0b00011010;
204+
constexpr auto b = 0b10000110;
205+
206+
TEST_ASSERT_EQUAL_FLOAT(56.8f,
207+
dht_humidity(DHT_CHIP_DHT12, {0x38, 0x8}));
208+
TEST_ASSERT_EQUAL_FLOAT(26.6f,
209+
dht_temperature(DHT_CHIP_DHT12, {0x1a, 0x6}));
210+
TEST_ASSERT_EQUAL_FLOAT(-26.6f,
211+
dht_temperature(DHT_CHIP_DHT12, {0x1a, 0x86}));
212+
213+
TEST_ASSERT_EQUAL_FLOAT(44.9f,
214+
dht_humidity(DHT_CHIP_DHT22, {0x1, 0xc1}));
215+
TEST_ASSERT_EQUAL_FLOAT(0.2f,
216+
dht_temperature(DHT_CHIP_DHT22, {0x0, 0x2}));
217+
TEST_ASSERT_EQUAL_FLOAT(-0.2f,
218+
dht_temperature(DHT_CHIP_DHT22, {0x80, 0x2}));
219+
220+
TEST_ASSERT_EQUAL_FLOAT(92.3f,
221+
dht_humidity(DHT_CHIP_DHT22, {0x3, 0x9b}));
222+
TEST_ASSERT_EQUAL_FLOAT(2.9f,
223+
dht_temperature(DHT_CHIP_DHT22, {0x0, 0x1d}));
224+
225+
TEST_ASSERT_EQUAL_FLOAT(56.3f,
226+
dht_humidity(DHT_CHIP_DHT22, {0x2, 0x33}));
227+
TEST_ASSERT_EQUAL_FLOAT(-0.9f,
228+
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xf7}));
229+
230+
TEST_ASSERT_EQUAL_FLOAT(93.0f,
231+
dht_humidity(DHT_CHIP_DHT22, {0x3, 0xa2}));
232+
TEST_ASSERT_EQUAL_FLOAT(-4.8f,
233+
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd0}));
234+
TEST_ASSERT_EQUAL_FLOAT(-4.7f,
235+
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd1}));
236+
TEST_ASSERT_EQUAL_FLOAT(-4.6f,
237+
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd2}));
238+
239+
TEST_ASSERT_EQUAL_FLOAT(88.9f,
240+
dht_humidity(DHT_CHIP_DHT22, {0x3, 0x79}));
241+
TEST_ASSERT_EQUAL_FLOAT(-2.2f,
242+
dht_temperature(DHT_CHIP_DHT22, {0xf, 0xea}));
243+
}
244+
196245
} // namespace
197246
} // namespace test
198247
} // namespace espurna
@@ -202,5 +251,6 @@ int main(int, char**) {
202251
using namespace espurna::test;
203252
RUN_TEST(test_cse7766_data);
204253
RUN_TEST(test_a02yyu_data);
254+
RUN_TEST(test_dht_data);
205255
return UNITY_END();
206256
}

0 commit comments

Comments
 (0)