RobTillaart / DHTNew

Arduino library for DHT11 and DHT22 with automatic sensor recognition
MIT License
99 stars 15 forks source link

Negative temp is calculated wrongly #100

Open Fihl opened 11 hours ago

Fihl commented 11 hours ago

It's getting cold out there..

When receiving _bits[2..3] = 0xffff as 0.1 degree, it gets converted to -3200 something, because 0x7fff is taken as 32000, and MSB of 0x8000 is taken as signbit and now makes -32000. Finally _temperature = -32000 * 0.1 = -3200

Code has to take 16 bits "as is", and move it directly into a int16_t. Then every is "as send" from DHT. And correctly interpreted. And no problem with -0.0, as minus-0 does not exists i the integer world. Code below also do the same with _humidity, but was correct before as long as DHT does not send negative values.

My fixed code in dhtnew.cpp:

  else               //  DHT22, DHT33, DHT44, compatible + Si7021
  {
    int16_t t1 = (_bits[0] << 8) + _bits[1]; // 16 bits, as raw int
    _humidity = t1 * 0.1;
    int16_t t2 = (_bits[2] << 8) + _bits[3]; // 16 bits, as raw int
    _temperature = t2 * 0.1;
  }

DHT11 code above also looks strange to my eyes. But I have not looked up the specs, and I do not use that part anyway.

/Christen

(updated code for syntax highlighting)

RobTillaart commented 11 hours ago

Thanks for reporting the issue.

This sounds serious given the library has been around for years. Need to investigate the datasheet and find a free sensor.

Q: which sensor do you use? DHT22 or compatible ? Q: have you tested the sensor with another DHT22 library e.g. Adafruit DHT22 library to rule out a broken sensor?

Might take a few days as I'm quite busy, but labeled it as bug to give priority.


DHT11 code above also looks strange to my eyes. But I have not looked up the specs, and I do not use that part anyway.

DHT11 does not support negative numbers, and the coding differs indeed.

RobTillaart commented 11 hours ago

It's getting cold out there..

Which country? Here in Netherlands its just around freezing.

RobTillaart commented 10 hours ago

Found a sensor DHT22 and did a quick test in my freezer.

Snippet from the log, removed the sensor from the fridge around sample 350. Log shows smooth transition from positive to negative values.

DHT_endless.ino
LIBRARY VERSION: 0.4.21

0   1   OK, 55.1,   21.1,   1004720,    22
2006    2   WFR,    55.1,   21.1,   8,  22
3007    3   OK, 55.0,   21.2,   4804,   22
4013    4   WFR,    55.0,   21.2,   4,  22
5014    5   OK, 55.7,   21.2,   4684,   22
6021    6   WFR,    55.7,   21.2,   8,  22
7021    7   OK, 56.5,   21.2,   4716,   22
8028    8   WFR,    56.5,   21.2,   4,  22
9029    9   OK, 56.6,   21.2,   4680,   22

....

OK  CRC     TOA     TOB     TOC     TOD     SNR     BS  WFR     UNK
150 0   0   0   0   0   0   0   149 0   

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
301185  300 WFR,    27.5,   1.3,    8,  22
302188  301 OK, 27.5,   1.1,    4736,   22
303194  302 WFR,    27.5,   1.1,    8,  22
304195  303 OK, 27.7,   1.0,    4536,   22
305202  304 WFR,    27.7,   1.0,    4,  22
306203  305 OK, 27.8,   0.9,    4540,   22
307209  306 WFR,    27.8,   0.9,    8,  22
308210  307 OK, 27.9,   0.7,    4784,   22
309217  308 WFR,    27.9,   0.7,    8,  22
310218  309 OK, 28.0,   0.6,    4660,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
311225  310 WFR,    28.0,   0.6,    8,  22
312225  311 OK, 28.1,   0.4,    4620,   22
313232  312 WFR,    28.1,   0.4,    4,  22
314233  313 OK, 28.1,   0.3,    4660,   22
315240  314 WFR,    28.1,   0.3,    4,  22
316240  315 OK, 28.3,   0.2,    4660,   22
317247  316 WFR,    28.3,   0.2,    8,  22
318248  317 OK, 28.3,   0.0,    4572,   22
319254  318 WFR,    28.3,   0.0,    4,  22
320256  319 OK, 28.5,   0.0,    4688,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
321262  320 WFR,    28.5,   0.0,    8,  22
322264  321 OK, 28.7,   -0.1,   4704,   22
323270  322 WFR,    28.7,   -0.1,   8,  22
324272  323 OK, 28.7,   -0.2,   4708,   22
325277  324 WFR,    28.7,   -0.2,   8,  22
326279  325 OK, 28.9,   -0.4,   4620,   22
327285  326 WFR,    28.9,   -0.4,   8,  22
328287  327 OK, 29.0,   -0.5,   4620,   22
329292  328 WFR,    29.0,   -0.5,   4,  22
330294  329 OK, 29.2,   -0.6,   4704,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
331300  330 WFR,    29.2,   -0.6,   8,  22
332302  331 OK, 29.2,   -0.8,   4656,   22
333308  332 WFR,    29.2,   -0.8,   8,  22
334309  333 OK, 29.4,   -0.9,   4660,   22
335315  334 WFR,    29.4,   -0.9,   8,  22
336317  335 OK, 29.5,   -1.0,   4744,   22
337324  336 WFR,    29.5,   -1.0,   8,  22
338325  337 OK, 29.6,   -1.1,   4696,   22
339331  338 WFR,    29.6,   -1.1,   8,  22
340332  339 OK, 29.7,   -1.2,   4740,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
341339  340 WFR,    29.7,   -1.2,   8,  22
342340  341 OK, 29.8,   -1.4,   4788,   22
343347  342 WFR,    29.8,   -1.4,   8,  22
344348  343 OK, 29.9,   -1.5,   4912,   22
345355  344 WFR,    29.9,   -1.5,   8,  22
346355  345 OK, 30.0,   -1.6,   4748,   22
347362  346 WFR,    30.0,   -1.6,   8,  22
348363  347 OK, 31.4,   -1.7,   4748,   22
349370  348 WFR,    31.4,   -1.7,   8,  22
350371  349 OK, 33.7,   -1.8,   4700,   22

OK  CRC     TOA     TOB     TOC     TOD     SNR     BS  WFR     UNK
175 0   0   0   0   0   0   0   174 0   

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
351381  350 WFR,    33.7,   -1.8,   8,  22
352385  351 OK, 36.1,   -1.8,   4828,   22
353391  352 WFR,    36.1,   -1.8,   4,  22
354393  353 OK, 39.2,   -1.7,   4620,   22
355398  354 WFR,    39.2,   -1.7,   8,  22
356400  355 OK, 42.0,   -1.7,   4708,   22
357406  356 WFR,    42.0,   -1.7,   8,  22
358408  357 OK, 44.5,   -1.6,   4784,   22
359413  358 WFR,    44.5,   -1.6,   4,  22
360415  359 OK, 47.0,   -1.5,   4868,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
361421  360 WFR,    47.0,   -1.5,   8,  22
362423  361 OK, 49.4,   -1.3,   4912,   22
363429  362 WFR,    49.4,   -1.3,   8,  22
364431  363 OK, 51.7,   -1.2,   4664,   22
365437  364 WFR,    51.7,   -1.2,   8,  22
366439  365 OK, 54.0,   -1.0,   4668,   22
367444  366 WFR,    54.0,   -1.0,   4,  22
368446  367 OK, 56.2,   -0.8,   4708,   22
369453  368 WFR,    56.2,   -0.8,   4,  22
370454  369 OK, 58.3,   -0.7,   4748,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
371461  370 WFR,    58.3,   -0.7,   8,  22
372461  371 OK, 60.4,   -0.5,   4780,   22
373468  372 WFR,    60.4,   -0.5,   8,  22
374469  373 OK, 62.4,   -0.3,   4784,   22
375476  374 WFR,    62.4,   -0.3,   8,  22
376477  375 OK, 64.3,   0.0,    4516,   22
377483  376 WFR,    64.3,   0.0,    8,  22
378484  377 OK, 66.1,   0.1,    4620,   22
379491  378 WFR,    66.1,   0.1,    4,  22
380492  379 OK, 67.9,   0.4,    4740,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
381498  380 WFR,    67.9,   0.4,    8,  22
382499  381 OK, 69.6,   0.6,    4620,   22
383506  382 WFR,    69.6,   0.6,    8,  22
384507  383 OK, 71.3,   0.9,    4700,   22
385513  384 WFR,    71.3,   0.9,    8,  22
386514  385 OK, 72.9,   1.2,    4828,   22
387521  386 WFR,    72.9,   1.2,    4,  22
388523  387 OK, 74.4,   1.5,    4864,   22
389529  388 WFR,    74.4,   1.5,    8,  22
390531  389 OK, 75.8,   1.8,    4696,   22

TIM CNT STAT    HUMI    TEMP    TIME    TYPE
391537  390 WFR,    75.8,   1.8,    4,  22
392539  391 OK, 77.1,   2.0,    4624,   22
393544  392 WFR,    77.1,   2.0,    8,  22
394546  393 OK, 78.5,   2.4,    4616,   22
395552  394 WFR,    78.5,   2.4,    8,  22
396554  395 OK, 79.8,   2.6,    4820,   22
397559  396 WFR,    79.8,   2.6,    4,  22
398561  397 OK, 81.1,   3.0,    4788,   22
399567  398 WFR,    81.1,   3.0,    4,  22
400569  399 OK, 82.3,   3.3,    4820,   22

OK  CRC     TOA     TOB     TOC     TOD     SNR     BS  WFR     UNK
200 0   0   0   0   0   0   0   199 0   
RobTillaart commented 10 hours ago

So I cannot reproduce the error.

Q: which version of the library do you use? Q: which board do you use?

Can you post the output of DHT_endless.ino example as I did above.

Fihl commented 6 hours ago

Version 0.4.21 (latest on Arduino 1.8), using ESP32 C3 Super Mini. DHT says it is "type 22", and also bought as DHT22 on ali.

Denmark here and now +1, but still 10cm snow. On sunday it is again 13 degrees! So I made a run in the freezer, and shows below all 6 bytes in _bits[]

I only blame the code, as the dht in fact does return 0xff-something, like 0xffff for minus 1 that gives -0.1 after times 0.1.

Manual test would be after real reading to reset _bits[] to known values, like _bits[2] = 0xff; _bits[3] = 0x9c; // => -10.0 degrees

My code (after making _bits[] public)

  float HumiVal = dht.getHumidity();
  float TempVal = dht.getTemperature();
  Serial.printf(F("(dht22: %02x %02x %02x %02x %02x temp=%.1f, humi=%.1f)"),
             dht._bits[0],dht._bits[1],dht._bits[2],dht._bits[3],dht._bits[4], TempVal, HumiVal);

Output with my code version. DHT model: 22

(dht22: 02 2a 00 57 83 temp=8.7, humi=55.4)
(dht22: 02 0e 00 50 60 temp=8.0, humi=52.6)
(dht22: 01 d8 00 48 21 temp=7.2, humi=47.2)
(dht22: 01 9d 00 40 de temp=6.4, humi=41.3)
(dht22: 01 62 00 37 9a temp=5.5, humi=35.4)
(dht22: 01 3d 00 2f 6d temp=4.7, humi=31.7)
(dht22: 01 2a 00 27 52 temp=3.9, humi=29.8)
(dht22: 01 1b 00 1e 3a temp=3.0, humi=28.3)
(dht22: 01 10 00 16 27 temp=2.2, humi=27.2)
(dht22: 01 12 00 0d 20 temp=1.3, humi=27.4)
(dht22: 01 11 00 06 18 temp=0.6, humi=27.3)
(dht22: 01 14 ff ff 13 temp=-0.1, humi=27.6)       0xFF FF starts here, going down
(dht22: 01 17 ff f7 0e temp=-0.9, humi=27.9)
(dht22: 01 1b ff ef 0a temp=-1.7, humi=28.3)
(dht22: 01 22 ff e8 0a temp=-2.4, humi=29.0)
(dht22: 01 28 ff e2 0a temp=-3.0, humi=29.6)
(dht22: 01 2f ff db 0a temp=-3.7, humi=30.3)
(dht22: 01 37 ff d6 0d temp=-4.2, humi=31.1)
(dht22: 01 3d ff d0 0d temp=-4.8, humi=31.7)
(dht22: 01 42 ff ca 0c temp=-5.4, humi=32.2)
(dht22: 01 48 ff c5 0d temp=-5.9, humi=32.8)
(dht22: 01 4d ff c0 0d temp=-6.4, humi=33.3)
(dht22: 01 56 ff bb 11 temp=-6.9, humi=34.2)
(dht22: 01 5c ff b6 12 temp=-7.4, humi=34.8)
(dht22: 01 65 ff b1 16 temp=-7.9, humi=35.7)
(dht22: 01 71 ff ad 1e temp=-8.3, humi=36.9)
(dht22: 01 76 ff a8 1e temp=-8.8, humi=37.4)
(dht22: 01 7b ff a3 1e temp=-9.3, humi=37.9)
(dht22: 01 81 ff a0 21 temp=-9.6, humi=38.5)
(dht22: 01 8a ff 9c 26 temp=-10.0, humi=39.4)
(dht22: 01 91 ff 99 2a temp=-10.3, humi=40.1)
(dht22: 01 98 ff 96 2e temp=-10.6, humi=40.8)
(dht22: 01 9e ff 92 30 temp=-11.0, humi=41.4)
(dht22: 01 a5 ff 8f 34 temp=-11.3, humi=42.1)
(dht22: 01 aa ff 8c 36 temp=-11.6, humi=42.6)
(dht22: 01 b0 ff 89 39 temp=-11.9, humi=43.2)
(dht22: 01 b5 ff 87 3c temp=-12.1, humi=43.7)
(dht22: 01 bb ff 84 3f temp=-12.4, humi=44.3)
(dht22: 01 c3 ff 80 43 temp=-12.8, humi=45.1)
(dht22: 01 c9 ff 7e 47 temp=-13.0, humi=45.7)
(dht22: 01 cd ff 7c 49 temp=-13.2, humi=46.1)
(dht22: 01 d3 ff 7a 4d temp=-13.4, humi=46.7)
(dht22: 01 da ff 78 52 temp=-13.6, humi=47.4)
(dht22: 01 e1 ff 76 57 temp=-13.8, humi=48.1)
(dht22: 01 e4 ff 74 58 temp=-14.0, humi=48.4)
(dht22: 01 e8 ff 73 5b temp=-14.1, humi=48.8)
(dht22: 01 ef ff 71 60 temp=-14.3, humi=49.5)
(dht22: 01 f0 ff 6f 5f temp=-14.5, humi=49.6)
(dht22: 01 f5 ff 6e 63 temp=-14.6, humi=50.1)
(dht22: 01 f8 ff 6c 64 temp=-14.8, humi=50.4)
(dht22: 01 fe ff 6b 69 temp=-14.9, humi=51.0)
(dht22: 02 00 ff 69 6a temp=-15.1, humi=51.2)
(dht22: 02 04 ff 68 6d temp=-15.2, humi=51.6)
(dht22: 02 0a ff 67 72 temp=-15.3, humi=52.2)
(dht22: 02 17 ff 63 7b temp=-15.7, humi=53.5)
(dht22: 02 1a ff 62 7d temp=-15.8, humi=53.8)
(dht22: 02 1c ff 61 7e temp=-15.9, humi=54.0)
(dht22: 02 21 ff 61 83 temp=-15.9, humi=54.5)
(dht22: 02 25 ff 5f 85 temp=-16.1, humi=54.9)
(dht22: 02 29 ff 5e 88 temp=-16.2, humi=55.3)
(dht22: 02 2c ff 5d 8a temp=-16.3, humi=55.6)
(dht22: 02 30 ff 5d 8e temp=-16.3, humi=56.0)
(dht22: 02 45 ff 56 9c temp=-17.0, humi=58.1)
(dht22: 02 5f ff 4c ac temp=-18.0, humi=60.7)
(dht22: 02 67 ff 48 b0 temp=-18.4, humi=61.5)

IMG_1148

Fihl commented 6 hours ago

I did a google and others also came to conclusion that base-2 normal layout is used, so t = ( highbyte <<8 ) + lowbyte is the way to read the value. Followed by times 0.1

I did find your dhtnew as my adafruit also failed. And one module fits all looked nice.

Have a go at stack xchg

Following explanation is very loose defined. (From AM2301 that issue #53 mentions) And wrong in my mind.

image
RobTillaart commented 5 hours ago

image

Slight layout variation of the print layout

100 00 88 00 2C B4      4.40    13.60
101 00 89 00 2A B3      4.20    13.70
102 00 89 00 28 B1      4.00    13.70
103 00 8A 00 26 B0      3.80    13.80
104 00 8B 00 24 AF      3.60    13.90
105 00 8C 00 22 AE      3.40    14.00
106 00 8D 00 20 AD      3.20    14.10
107 00 8D 00 1E AB      3.00    14.10
108 00 8E 00 1B A9      2.70    14.20
109 00 8F 00 19 A8      2.50    14.30
110 00 90 00 17 A7      2.30    14.40
111 00 91 00 15 A6      2.10    14.50
112 00 92 00 13 A5      1.90    14.60
113 00 92 00 11 A3      1.70    14.60
114 00 94 00 0F A3      1.50    14.80
115 00 94 00 0D A1      1.30    14.80
116 00 95 00 0B A0      1.10    14.90
117 00 96 00 0A A0      1.00    15.00
118 00 97 00 08 9F      0.80    15.10
119 00 98 00 06 9E      0.60    15.20
120 00 99 00 04 9D      0.40    15.30
121 00 9A 00 02 9C      0.20    15.40
122 00 9C 00 00 9C      0.00    15.60
123 00 9D 80 00 1D      0.00    15.70
124 00 9E 80 02 20      -0.20   15.80
125 00 9F 80 04 23      -0.40   15.90
126 00 A0 80 06 26      -0.60   16.00
127 00 A1 80 08 29      -0.80   16.10
128 00 A2 80 09 2B      -0.90   16.20
129 00 A3 80 0B 2E      -1.10   16.30
130 00 A4 80 0C 30      -1.20   16.40
131 00 A6 80 0E 34      -1.40   16.60
132 00 A7 80 10 37      -1.60   16.70
133 00 A8 80 11 39      -1.70   16.80
134 00 A9 80 12 3B      -1.80   16.90
135 00 AB 80 14 3F      -2.00   17.10
136 00 AB 80 16 41      -2.20   17.10
137 00 B2 80 17 49      -2.30   17.80
138 00 F2 80 18 8A      -2.40   24.20
139 01 0A 80 19 A4      -2.50   26.60
140 01 22 80 19 BC      -2.50   29.00
141 01 3D 80 19 D7      -2.50   31.70
142 01 56 80 19 F0      -2.50   34.20
143 01 70 80 19 0A      -2.50   36.80
144 01 89 80 19 23      -2.50   39.30
145 01 A1 80 18 3A      -2.40   41.70
146 01 B9 80 17 51      -2.30   44.10
147 01 D2 80 16 69      -2.20   46.60
148 01 E9 80 14 7E      -2.00   48.90
149 02 00 80 13 95      -1.90   51.20
150 02 16 80 11 A9      -1.70   53.40
151 02 2C 80 0F BD      -1.50   55.60
152 02 41 80 0D D0      -1.30   57.70
153 02 55 80 0B E2      -1.10   59.70
154 02 69 80 09 F4      -0.90   61.70
155 02 7C 80 07 05      -0.70   63.60
156 02 8E 80 04 14      -0.40   65.40
157 02 A0 80 00 22      0.00    67.20
158 02 B2 00 03 B7      0.30    69.00
159 02 C4 00 07 CD      0.70    70.80
160 02 D5 00 0B E2      1.10    72.50
161 02 E6 00 0E F6      1.40    74.20
162 02 F5 00 11 08      1.70    75.70
163 03 04 00 15 1C      2.10    77.20
164 03 12 00 19 2E      2.50    78.60
165 03 20 00 1D 40      2.90    80.00
166 03 2E 00 21 52      3.30    81.40
167 03 3B 00 25 63      3.70    82.70
168 03 47 00 29 73      4.10    83.90
169 03 53 00 2D 83      4.50    85.10
170 03 5E 00 31 92      4.90    86.20

So they spit out different bits when negative.

RobTillaart commented 5 hours ago

Datasheet DHT22 (does not tell how to interpret negative numbers, in fact it does not match the hardware at all)

image

Datasheet DHT33 (DHT44 + RHT04 shows same paragraph)

image

Datasheet AM2301

image

Datasheet CM2122

image

Fihl commented 5 hours ago

Wow, that is one way (your way :-) ) of sending data. Send value, and then add one bit to say if it is plus or minus. 80 02 => -0.2

The other way (my way and device) sends base-2, i.e. 100% as a cpu register saves plus/minus. FF FE => -0.2

Seems like you need to have a switch saying which version each device is using. Base-2 or "strange" mode.

The checksum says nothing about which way data is send. Just says that all 4 bytes are send correct.

RobTillaart commented 5 hours ago

@Fihl

So the code in the library is correct but "not correct enough", two sensors both named DHT22 produce different bits.

Q: how to solve this?

Requirements:

  1. The code should support the current negative algorithm
  2. The code should support the reported negative algorithm
  3. If possible the library should be able to detect which algorithm to use.

Given that the range of (negative) temperatures is something like -40 .. 80

This means that if we look at byte 2 which is in one case 1000 0000 and in the other case 1111 1111 So the highest bit indicates negative temperatures for sure.

So the second highest bit could be used to determine the algorithm used.

Fihl commented 4 hours ago

Now we (you) are talking :-) Autodetect.....

If negative bit 15 = 1 If bit 14 = 0, your code if bit 14 = 1, my code

Go for it

RobTillaart commented 4 hours ago

Will try to have a develop branch this evening. At the moment I am in a deadline for Monday.... Patience, breath in breath out . :)

Fihl commented 4 hours ago

I only have "my" DHT22 versions :-)

RobTillaart commented 4 hours ago

We can do both 50% of the test :)

RobTillaart commented 4 hours ago

@Fihl

Created a develop branch with a (non optimized) fix for this issue. Please test your 50% 😎,

Rob

Fihl commented 4 hours ago

Nice and clean I will give it a go tomorrow.