Skip to content

Commit bf15299

Browse files
emdiohMarco Dondero
andauthored
Correct negative results in DHT driver (#3210)
* DHT module: fix the handling of negative temps. The macro handling the conversion from the 2 bytes buffer to a double was handling negative values by checking the sign bit and taking the negative value of the number minus the sign bit. Unfortunately this does not work as the negative values are represented in 1's complement, so for instance -1 was becoming -32767 * +1 = b0000_0000_0000_ 0001 * -1 = 1111_1111_1111_1111 This replace the spacial code with a signed 16 bits value. * Refactoring: removes some code duplication. * Fixed the conversion of the 8/16 bits values Co-authored-by: Marco Dondero <marco@dondero.eu>
1 parent 2fa63a1 commit bf15299

File tree

1 file changed

+51
-30
lines changed

1 file changed

+51
-30
lines changed

app/dht/dht.c

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,21 @@
4040
#define HIGH 1
4141
#endif /* ifndef HIGH */
4242

43-
#define COMBINE_HIGH_AND_LOW_BYTE(byte_high, byte_low) (((byte_high) << 8) | (byte_low))
44-
4543
static double dht_humidity;
4644
static double dht_temperature;
4745

4846
static uint8_t dht_bytes[5]; // buffer to receive data
47+
48+
typedef enum {
49+
Humidity = 0,
50+
Temperature,
51+
Humidity8,
52+
Temperature8
53+
} dht_Signal;
54+
4955
static int dht_readSensor(uint8_t pin, uint8_t wakeupDelay);
56+
static double getValue(dht_Signal s);
57+
static bool verifyChecksum();
5058

5159
/////////////////////////////////////////////////////
5260
//
@@ -91,19 +99,17 @@ int dht_read_universal(uint8_t pin)
9199
#endif // defined(DHT_DEBUG_BYTES)
92100

93101
// Assume it is DHT11
94-
// If it is DHT11, both bit[1] and bit[3] is 0
102+
// If it is DHT11, both temp and humidity's decimal
95103
if ((dht_bytes[1] == 0) && (dht_bytes[3] == 0))
96104
{
97105
// It may DHT11
98106
// CONVERT AND STORE
99107
DHT_DEBUG("DHT11 method\n");
100-
dht_humidity = dht_bytes[0]; // dht_bytes[1] == 0;
101-
dht_temperature = dht_bytes[2]; // dht_bytes[3] == 0;
108+
dht_humidity = getValue(Humidity8);
109+
dht_temperature = getValue(Temperature8);
102110

103111
// TEST CHECKSUM
104-
// dht_bytes[1] && dht_bytes[3] both 0
105-
uint8_t sum = dht_bytes[0] + dht_bytes[2];
106-
if (dht_bytes[4] != sum)
112+
if (!verifyChecksum())
107113
{
108114
// It may not DHT11
109115
dht_humidity = DHTLIB_INVALID_VALUE; // invalid value, or is NaN prefered?
@@ -119,16 +125,11 @@ int dht_read_universal(uint8_t pin)
119125
// Assume it is not DHT11
120126
// CONVERT AND STORE
121127
DHT_DEBUG("DHTxx method\n");
122-
dht_humidity = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
123-
dht_temperature = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
124-
if (dht_bytes[2] & 0x80) // negative dht_temperature
125-
{
126-
dht_temperature = -dht_temperature;
127-
}
128+
dht_humidity = getValue(Humidity);
129+
dht_temperature = getValue(Temperature);
128130

129131
// TEST CHECKSUM
130-
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
131-
if (dht_bytes[4] != sum)
132+
if (!verifyChecksum())
132133
{
133134
return DHTLIB_ERROR_CHECKSUM;
134135
}
@@ -151,13 +152,11 @@ int dht_read11(uint8_t pin)
151152
}
152153

153154
// CONVERT AND STORE
154-
dht_humidity = dht_bytes[0]; // dht_bytes[1] == 0;
155-
dht_temperature = dht_bytes[2]; // dht_bytes[3] == 0;
155+
dht_humidity = getValue(Humidity8);
156+
dht_temperature = getValue(Temperature8);
156157

157158
// TEST CHECKSUM
158-
// dht_bytes[1] && dht_bytes[3] both 0
159-
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
160-
if (dht_bytes[4] != sum) return DHTLIB_ERROR_CHECKSUM;
159+
if (!verifyChecksum()) return DHTLIB_ERROR_CHECKSUM;
161160

162161
return DHTLIB_OK;
163162
}
@@ -179,16 +178,11 @@ int dht_read(uint8_t pin)
179178
}
180179

181180
// CONVERT AND STORE
182-
dht_humidity = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[0], dht_bytes[1]) * 0.1;
183-
dht_temperature = (double)COMBINE_HIGH_AND_LOW_BYTE(dht_bytes[2] & 0x7F, dht_bytes[3]) * 0.1;
184-
if (dht_bytes[2] & 0x80) // negative dht_temperature
185-
{
186-
dht_temperature = -dht_temperature;
187-
}
181+
dht_humidity = getValue(Humidity);
182+
dht_temperature = getValue(Temperature);
188183

189184
// TEST CHECKSUM
190-
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
191-
if (dht_bytes[4] != sum)
185+
if (!verifyChecksum())
192186
{
193187
return DHTLIB_ERROR_CHECKSUM;
194188
}
@@ -242,7 +236,7 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
242236
// volatile uint8_t *PIR = portInputRegister(port);
243237

244238
// EMPTY BUFFER
245-
for (i = 0; i < 5; i++) dht_bytes[i] = 0;
239+
memset(dht_bytes, sizeof(uint8_t)*5, 0);
246240

247241
// REQUEST SAMPLE
248242
// pinMode(pin, OUTPUT);
@@ -314,6 +308,33 @@ int dht_readSensor(uint8_t pin, uint8_t wakeupDelay)
314308

315309
return DHTLIB_OK;
316310
}
311+
312+
// Assembles the high and low byte in a signed 16bit value
313+
static double getValue(dht_Signal s)
314+
{
315+
uint8_t high=0, low=0;
316+
317+
// the '8' variants leave the low byte set to 0
318+
switch(s){
319+
case Humidity:
320+
low = dht_bytes[1];
321+
case Humidity8:
322+
high = dht_bytes[0];
323+
break;
324+
case Temperature:
325+
low = dht_bytes[3];
326+
case Temperature8:
327+
high = dht_bytes[2];
328+
break;
329+
}
330+
return ((high << 8) | low) * 0.1;
331+
}
332+
333+
static bool verifyChecksum(){
334+
uint8_t sum = dht_bytes[0] + dht_bytes[1] + dht_bytes[2] + dht_bytes[3];
335+
return (dht_bytes[4] == sum);
336+
}
337+
317338
//
318339
// END OF FILE
319340
//

0 commit comments

Comments
 (0)