Some candidates for investigations:
I double checked both code and wiring to be on the safe side.
I am confident that the protocol implementation matches the transmission of DHT11. So next I need recheck if the setup time (one second) and frequency of reading (every two seconds) are the correct requirement.
I also have an English Aosong DHT11 datasheet that seems outdated. Aosong doesn’t seem to allow redistribution of their datasheet so most online vendor have made their own based on that English version.
The English datasheet states the temperature range as 0~50℃, the humidity range to be 20~95%RH and recommend a reading frequency greater than 5 seconds.
The Chinese datasheet states the temperature range as -20~60°C, the humidity range to be 0~95%RH and recommend a reading frequency greater than 2 seconds. It also explains the encoding of negative temperature.
My implementation is based on the latest Chinese version. I can retest with a longer interval between readings in case I am using a chip that follows the older specification (5 seconds interval instead of 2).
In dht11main.c I just need to change the test if( 1 & last)
to if( 2 == (last % 15))
in order to read every 15 seconds after
a setup time of 2 seconds. If this works better, I can retry for shorter
intervals by changing the modulo value.
When I test with readings every 15 seconds, I get stable humidity value around 25~26%RH. As I have changed both interval and setup time, I need confirm that it is the interval time that matters.
With intervals of 5 and 6 seconds, the reading jumps above 37%RH. So it’s clearly a problem with the interval.
I want to make a round number of samples per minute, so I need retest to check if 10 and 12 seconds work the same as 15, but before I do fine tuning, I better check if this is not just a problem with that particular DHT11.
Defects happen! No production line output is 100% perfect, so I may just have a defective or damaged chip. As this particular product is low cost, I have several boards on hands I bought from different suppliers, I would be very unlucky if they end up all coming from the same bad production batch or all damaged by mishandling.
Testing the four DHT11 I have, I find that three of them are working in their precision range when sampled every five seconds. Understanding that humidity precision is ±5%RH and temperature precision is ±2℃, there is still room for quite some variation between readings from different devices.
I select the most accurate chip at my current environment humidity and temperature to do further test.
I need to use a 5V tolerant GPIO pin for this test, so I switch to GPIOA 13 (SWDIO). By default that pin is configured as ALT SWDIO, floating input with weak pull-up, similar to the initial state for DHT11 Data IO pin.
The board needs to be powered by its USB connector 5V source instead of directly by the USB to Serial adapter, I make sure board and adapter are powered independently, the two being connected only by TX, RX and GND. I can then select the voltage of DHT11 according to what I want to test, 3.3V or 5V.
There is a difference in measurement, 3.3V giving slightly higher value than 5V, for this particular test: 2%RH more for humidity and 0.3℃ for temperature. There is no clear advantage to use 5V over 3.3V.
I am not doing precise voltage test as the precision of DHT11 and the variation between the chips I have would make the interpretation of the results irrelevant.
I have implemented dht11_read()
accordingly so I just need to
test at below zero ℃.
From my test, I can see that the values reported are negative but I found a difference versus the datasheet.
According to the datasheet, the temperature values are encoded as 1 byte for the integer part and 1 byte for the one decimal digit fractional part, the highest bit of the fractional part indicating the sign.
So when temperature crosses zero, I expects to see
0 + 2 => 0.2 0 + 1 => 0.1 0 + 0 => 0.0 0 - 1 => -0.1 0 - 2 => -0.2 ... 0 - 8 => -0.8 0 - 9 => -0.9 1 - 0 => -1.0 1 - 1 => -1.1 ...Instead the values transmitted are
0 + 2 => 0.2 0 + 1 => 0.1 0 + 0 => 0.0 0 - 9 => ??? 0 - 8 => ??? ... 0 - 2 0 - 1 0 - 0 => !!! 1 - 9 ...I have to modify my original implementation
dht11_tempc = values[ 2] ; dht11_tempf = values[ 3] ; if( dht11_tempf & 0x80) { dht11_tempc *= -1 ; dht11_tempf &= 0x7F ; }And retest after the following modification.
dht11_tempc = values[ 2] ; dht11_tempf = values[ 3] ; if( dht11_tempf & 0x80) { dht11_tempc *= -1 ; dht11_tempf = 10 - ( dht11_tempf & 0x7F) ; if( dht11_tempf == 10) { dht11_tempc -= 1 ; dht11_tempf = 0 ; } }
I found some difference between the Chinese datasheet and the behavior of the chips I have when it come to representation of temperature below 0℃.
Cost and one pin transmission interface are the two main advantages of this chipset.
I could use the DHT11 for monitoring temperature and humidity variations. For fast and accurate measurements, this is not the droid I am looking for.
Next, I will use another digital thermometer as a reference.