Skip to content

Commit

Permalink
sns(dht): another dht22 variant w/ 12bit values
Browse files Browse the repository at this point in the history
  • Loading branch information
mcspr committed Mar 5, 2025
1 parent 7476793 commit 40500b4
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 8 deletions.
31 changes: 23 additions & 8 deletions code/espurna/sensors/DHTSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ float dht_humidity(DHTChipType type, std::array<uint8_t, 2> pair) {
return out;
}

float dht_raw_impl(std::array<uint8_t, 2> pair) {
int16_t out;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
std::swap(pair[0], pair[1]);
#endif
std::memcpy(&out, pair.data(), sizeof(out));

return out;
}

float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
// binary representation varies between the original chip and its copies
// by default, check for generic sign-magnitude
Expand All @@ -92,6 +103,11 @@ float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
// it is enough to only check the sign bit neighbour; possible values are around [0...800]
constexpr auto NegativeTwoComplementMask = uint8_t{ 0b11000000 };

// another case is 12bit value instead of full 16bit
// in case of negative numbers we'd have to extend it to full 16bit
constexpr auto ShortVoidMask = uint8_t{ 0b11111000 };
constexpr auto ShortSignMask = uint8_t{ 0b00001000 };

float out;

switch (type) {
Expand Down Expand Up @@ -122,15 +138,14 @@ float dht_temperature(DHTChipType type, std::array<uint8_t, 2> pair) {
case DHT_CHIP_DHT22:
case DHT_CHIP_AM2301:
case DHT_CHIP_SI7021:
// special exception for negative numbers in twos-complement
// negative numbers in twos-complement
if ((pair[0] & NegativeTwoComplementMask) == NegativeTwoComplementMask) {
int16_t tmp;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
std::swap(pair[0], pair[1]);
#endif
std::memcpy(&tmp, pair.data(), sizeof(tmp));
out = tmp;
// fallback works both for the original chips and positive numbers
out = dht_raw_impl(pair);
// 12bit numbers have to be extended first
} else if ((pair[0] & ShortVoidMask) == ShortSignMask) {
pair[0] |= ShortVoidMask;
out = dht_raw_impl(pair);
// otherwise, use the standard copy
} else {
out = ((pair[0] & MagnitudeMask) << 8) | pair[1];
if (pair[0] & SignMask) {
Expand Down
50 changes: 50 additions & 0 deletions code/test/unit/src/sensor/sensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@
// TODO is ..._SUPPORT wrapping necessary inside of sensor includes?
// TODO ..._PORT should not be used in the class itself?

// TODO ignore -Wunused-value that comes up here from interrupts() / noInterrupts() usage
#undef xt_rsil
#define xt_rsil(X)

#define SENSOR_SUPPORT 1
#define CSE7766_SUPPORT 1
#define A02YYU_SUPPORT 1
#define DHT_SUPPORT 1

#include <espurna/config/sensors.h>
#include <espurna/sensors/CSE7766Sensor.h>
#include <espurna/sensors/A02YYUSensor.h>
#include <espurna/sensors/DHTSensor.h>

#include <memory>
#include <vector>
Expand Down Expand Up @@ -193,6 +199,49 @@ void test_a02yyu_data() {
TEST_ASSERT_EQUAL_DOUBLE(1.953, ptr->value(0));
}

void test_dht_data() {
constexpr auto a = 0b00011010;
constexpr auto b = 0b10000110;

TEST_ASSERT_EQUAL_FLOAT(56.8f,
dht_humidity(DHT_CHIP_DHT12, {0x38, 0x8}));
TEST_ASSERT_EQUAL_FLOAT(26.6f,
dht_temperature(DHT_CHIP_DHT12, {0x1a, 0x6}));
TEST_ASSERT_EQUAL_FLOAT(-26.6f,
dht_temperature(DHT_CHIP_DHT12, {0x1a, 0x86}));

TEST_ASSERT_EQUAL_FLOAT(44.9f,
dht_humidity(DHT_CHIP_DHT22, {0x1, 0xc1}));
TEST_ASSERT_EQUAL_FLOAT(0.2f,
dht_temperature(DHT_CHIP_DHT22, {0x0, 0x2}));
TEST_ASSERT_EQUAL_FLOAT(-0.2f,
dht_temperature(DHT_CHIP_DHT22, {0x80, 0x2}));

TEST_ASSERT_EQUAL_FLOAT(92.3f,
dht_humidity(DHT_CHIP_DHT22, {0x3, 0x9b}));
TEST_ASSERT_EQUAL_FLOAT(2.9f,
dht_temperature(DHT_CHIP_DHT22, {0x0, 0x1d}));

TEST_ASSERT_EQUAL_FLOAT(56.3f,
dht_humidity(DHT_CHIP_DHT22, {0x2, 0x33}));
TEST_ASSERT_EQUAL_FLOAT(-0.9f,
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xf7}));

TEST_ASSERT_EQUAL_FLOAT(93.0f,
dht_humidity(DHT_CHIP_DHT22, {0x3, 0xa2}));
TEST_ASSERT_EQUAL_FLOAT(-4.8f,
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd0}));
TEST_ASSERT_EQUAL_FLOAT(-4.7f,
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd1}));
TEST_ASSERT_EQUAL_FLOAT(-4.6f,
dht_temperature(DHT_CHIP_DHT22, {0xff, 0xd2}));

TEST_ASSERT_EQUAL_FLOAT(88.9f,
dht_humidity(DHT_CHIP_DHT22, {0x3, 0x79}));
TEST_ASSERT_EQUAL_FLOAT(-2.2f,
dht_temperature(DHT_CHIP_DHT22, {0xf, 0xea}));
}

} // namespace
} // namespace test
} // namespace espurna
Expand All @@ -202,5 +251,6 @@ int main(int, char**) {
using namespace espurna::test;
RUN_TEST(test_cse7766_data);
RUN_TEST(test_a02yyu_data);
RUN_TEST(test_dht_data);
return UNITY_END();
}

0 comments on commit 40500b4

Please sign in to comment.