![]() |
Forum Index : Microcontroller and PC projects : DHT11 Humidity Sensor on an F4 (or any MMBasic)
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Hi Jim, Thanks for trying - it might be a Peter issue? Perhaps we need to shine the bat-light onto the clouds again? Cheers, Andrew |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
F4 Beta 12 also ms only. ARMmite MMBasic Version 5.07.00b12 Copyright 2011-2020 Geoff Graham Copyright 2016-2020 Peter Mather > setpin pe6, dout > timer =0 : pulse pe6, 1.234 : if pe6 = 0 then : ? timer : endif 1 > timer =0 : pulse pe6, 1.876 : if pe6 = 0 then : ? timer : endif 2 |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6274 |
The time wasn't wasted, I found a bug in the CMM2 DHT22 code. When I wanted a high res timer on the micromite 170, I used a PWM signal linked to a counting input. A bit of an overkill but it did work. Jim VK7JH MMedit |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6274 |
You always need a PLAN B The DHT has to be run of 3.3V to prevent overloading the ADC input You need to use a pin that is OK for ADC channel 1 I used pin 15 - PC0 (I prefer numbers rather than letters so I can use variables/constants) ' DHT11 decoder using ADC ' TassyJim May 2021 ' when using the ADC, the DHT** has to be run on 3.3V and use one of the ADC input pins ' The external 4.7k pullup to 3.3V is required. ' DIM FLOAT te, hu DIM FLOAT a_in(500) DIM INTEGER alldone DIM INTEGER dht_pin = 15 '15 on the F4, ?? on the CMM2 DO HUMID dht_pin,te,hu PAUSE 2000 HUMID dht_pin,te,hu ' take two reading to remove stale reading from the mix PRINT te,hu PAUSE 2000 dht11 dht_pin,te,hu PRINT te,hu PAUSE 15000 LOOP SUB dht11 pn, tem, hum LOCAL INTEGER n, count, running, x = 1 LOCAL INTEGER repl(5) LOCAL reply$ alldone = 0 PIN(pn) = 1 SETPIN pn, DOUT, OC PAUSE 2 PIN(pn) = 0 PAUSE 18 ' this is the start pulse length - 18 for the DHT11, 1 for DHT22 PIN(pn) = 1 SETPIN pn, OFF ' make way for the ADC to take over the pin ADC OPEN 100000,pn,,,adc_done ' sample every 10uS ADC START a_in() DO LOOP UNTIL alldone = 1 FOR n = 0 TO 500 IF running = 0 THEN IF a_in(n) < 1.6 THEN running = 1 ENDIF IF running THEN IF a_in(n) > 1.6 THEN count = count + 1 ELSE IF count > 0 THEN PRINT count; IF count > 5 THEN reply$= reply$+"1" ' we could use an integer instead of a string ELSE reply$ = reply$+"0" ENDIF count = 0 ENDIF ENDIF ENDIF NEXT n FOR n = 0 TO 4 repl(n) = VAL("&b"+MID$(reply$,n*8+x,8)) NEXT n hum = (repl(0)*256+repl(1))/10 tem = repl(2)*256+repl(3) IF tem > 32767 THEN tem = tem - 65536 tem = tem/10 PRINT reply$ PRINT repl(0),repl(1),repl(2),repl(3),repl(4)," ch_sum ";(repl(0)+repl(1)+repl(2)+repl(3)) AND 255 END SUB SUB adc_done alldone = 1 ADC CLOSE END SUB Output from a working DHT22 on my F4: 18.9 53.4 3 3 2 2 2 2 7 2 2 2 2 7 3 8 3 7 3 3 3 3 3 3 3 3 8 3 7 7 8 8 3 7 7 8 3 7 2 7 3 3 0000001000010101000000001011110111010100 2 21 0 189 212 ch_sum 212 18.9 53.3 18.9 53.3 3 2 2 2 2 2 7 2 2 2 2 7 3 8 3 7 3 3 3 3 3 3 3 3 8 3 7 7 8 8 2 7 7 8 3 7 2 7 3 3 0000001000010101000000001011110111010100 2 21 0 189 212 ch_sum 212 18.9 53.3 18.9 53.4 2 2 2 2 2 2 7 3 2 2 2 7 3 8 7 2 3 3 3 3 3 3 3 2 8 2 7 7 8 7 2 7 8 8 3 7 2 7 3 8 0000001000010110000000001011110111010101 2 22 0 189 213 ch_sum 213 18.9 53.4 This shows that short pulses (0) are 2 or 3 *10uS and long pulses are 7 or 8 *10uS I use >5 for the decision. I would be interested to see a DHT11 output. Jim VK7JH MMedit |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Jim, Thanks - I'm tied up at present - will get back to you ASAP. Andrew |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
Thanks Jim. You have put a lot of thought into this. Much appreciated. Maybe my DHT11 isn't prime quality, it came in a cheep sensors package. The temperature in here is not 333 degrees C 333K would be close to the mark. > RUN 1000 1000 2 8 2 2 7 7 8 2 2 2 2 3 3 2 2 2 2 3 3 2 7 7 7 3 3 2 2 2 2 3 3 3 2 7 3 7 7 7 3 3 0100111000000000000011100000000001011100 78 0 14 0 92 ch_sum 92 358.4 1996.8 1000 1000 2 8 2 2 7 7 2 8 2 2 2 3 3 2 2 2 2 3 3 3 7 7 7 3 3 2 2 2 2 3 3 3 2 7 3 7 7 2 7 7 0100110100000000000011100000000001011011 77 0 14 0 91 ch_sum 91 358.4 1971.2 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 3 7 7 3 7 2 3 3 3 7 3 3 7 2 8 7 3 3 2 7 3 0100110000000000000011010000100101100010 76 0 13 9 98 ch_sum 98 333.7 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 2 7 7 3 7 2 2 3 3 7 3 3 7 2 8 7 3 3 2 7 3 0100110000000000000011010000100101100010 76 0 13 9 98 ch_sum 98 333.7 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 2 7 7 3 7 2 3 3 3 7 3 3 7 2 8 7 3 3 2 7 3 0100110000000000000011010000100101100010 76 0 13 9 98 ch_sum 98 333.7 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 2 7 7 3 7 2 2 3 3 7 3 3 7 2 7 7 3 3 3 7 3 0100110000000000000011010000100101100010 76 0 13 9 98 ch_sum 98 333.7 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 3 7 7 3 7 2 3 3 3 7 3 3 3 2 7 7 2 2 3 3 7 0100110000000000000011010000100001100001 76 0 13 8 97 ch_sum 97 333.6 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 2 7 7 3 7 2 2 3 3 7 3 3 3 2 7 7 2 2 3 3 7 0100110000000000000011010000100001100001 76 0 13 8 97 ch_sum 97 333.6 1945.6 1000 1000 2 8 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 3 7 7 3 7 2 3 3 3 7 3 3 3 2 7 7 2 2 3 3 7 0100110000000000000011010000100001100001 76 0 13 8 97 ch_sum 97 333.6 1945.6 1000 1000 2 7 2 2 7 7 2 3 3 3 2 2 2 3 3 3 2 2 2 2 7 7 3 7 2 3 3 3 7 3 3 3 2 7 7 2 2 3 3 7 0100110000000000000011010000100001100001 76 0 13 8 97 ch_sum 97 333.6 1945.6 |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6274 |
Phil, The checksum is happy so we are getting the data OK. Just have to decode it correctly The data sheet is word for word the same as my DHT22 specs but obviously there is a difference. I'm not sure where you are located. What would the temperature be? and is 78% a likely humidity? Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
Jim, Kinglake, it's on the top of the dividing range (580m alt) so it's a cool 13 C in the shed. The humidity is fairly high - the laundry was on the line all day but didn't dry. Phil |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Jim, Here is what I get with my DHT11 (inside). I have a working DHT22 outside that says humidity is 62.6 and a DS18B20 within a metre that says the temp is 19.0C. If you like, I can, tomorrow, put both the DHT11 & 22 side by side on the F4??? Cheers, Andrew run 1000 1000 2 2 7 7 2 8 7 3 3 3 2 2 2 3 3 3 3 2 2 7 2 2 7 3 3 2 2 2 8 2 2 2 2 7 2 7 3 2 2 2 0011011000000000000100100000100001010000 54 0 18 8 80 ch_sum 80 461.6 1382.4 1000 1000 3 2 7 7 2 7 2 7 3 3 2 2 2 2 3 3 3 2 2 7 3 2 7 3 3 2 2 2 8 2 2 2 2 7 2 2 7 7 7 7 0011010100000000000100100000100001001111 53 0 18 8 79 ch_sum 79 461.6 1356.8 1000 1000 2 2 7 7 2 8 2 7 3 3 2 2 2 2 3 3 3 2 2 7 2 2 7 3 3 2 2 2 3 7 7 7 2 7 3 2 7 7 7 3 0011010100000000000100100000011101001110 53 0 18 7 78 ch_sum 78 461.5 1356.8 1000 1000 3 2 7 7 2 7 2 7 3 3 3 2 2 2 3 3 3 2 2 7 3 2 7 3 3 2 2 2 7 2 2 2 2 8 2 2 7 7 7 7 0011010100000000000100100000100001001111 53 0 18 8 79 ch_sum 79 461.6 1356.8 Edited 2021-05-29 19:26 by Andrew_G |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10288 |
The decode for the DHT11 and DHT22 are different - it isn't just the timing // we have all 40 bits // first validate against the checksum if( ( ( ((r >> 8) & 0xff) + ((r >> 16) & 0xff) + ((r >> 24) & 0xff) + ((r >> 32) & 0xff) ) & 0xff) != (r & 0xff)) goto error_exit; // returning temperature if(DHT22){ *temp = (MMFLOAT)((r >> 8) &0x7fff) / 10.0; // get the temperature if((r >> 8) &0x8000) *temp = -*temp; // the top bit is the sign *humid = (MMFLOAT)(r >> 24) / 10.0; // get the humidity } else { *temp = (MMFLOAT)((signed char)((r>>16) & 0xFF)); // get the temperature *humid = (MMFLOAT)((signed char)(r >> 32)); // get the humidity } |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6274 |
Both devices are easy enough to decode now I have some references to go with. I will fix the code and post a tidy version tomorrow although Peter might beat me to it. Jim Edited 2021-05-29 19:48 by TassyJim VK7JH MMedit |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10288 |
DHT11 now supported in V5.07.00b13 Edited 2021-05-29 20:02 by matherp |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Peter, You are a marvel - it works for me! Thanks. I have a 4K7 pullup and it is running at 3v3 - is 5V OK? Cheers, (and thanks again) Andrew |
||||
Andrew_G Guru ![]() Joined: 18/10/2016 Location: AustraliaPosts: 871 |
Peter, I've now been able to run a DHT11 and DHT22 side by side on my F4 and I notice that the 22 has temperature and humidity to one decimal place whereas the 11 has them only as an integer (i.e. zero DP). Is that a 'feature' of the software or is it a limitation of the device? Many thanks, Andrew Jim - I'm not sure that I thanked you adequately - thanks! |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6274 |
That is the limit of the DHT11 Considering that the precision is a few percent, fractional results are unnecessary Jim VK7JH MMedit |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
Yes, after looking at the data format temp. and humidity are each encoded with 2 bytes. One for the value to the left of the decimal point and the other for the remainder to the right. Because of the limited accuracy, compared to the 22 I think Peter has ignored the second byte of each. |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
If anyone wants 0.1 degree temperature resolution this version of TassyJim's decoder will give it. the DHT11 accuracy isn't very good so to make use of this you will need to measure the error with an accurate thermometer and make corrections in your code. A single point measurement would be ok in an airconditioned space, but if the temp. range is large two or more calibration points can be used to make a correction curve. The humidity decimal is also added, but it is always zero. The humidity sensor's accuracy is +/- 5% so there is no point really. (pun intended) To maintain even this limited accuracy the DHT11 should occasionally be heated to 50 C in dry air for 2 hours. Sub dht11 pn, tem, hum ' DHT11 decoder using ADC for ARMMiite-F4 ' TassyJim May 2021 ' when using the ADC, the DHT11 has to be run on 3.3V ' and use one of the ADC input pins. eg 15 (PC0) ' External 4.7k to 10k pullup to 3.3V is required. ' it may be possible use 5V power provided pullup goes to 3.3v ' Local FLOAT a_in(500) Local INTEGER n, count, running, x = 1 Local INTEGER repl(5) Local reply$ alldone = 0 Pin(pn) = 1 SetPin pn, DOUT, OC Pause 20 Pin(pn) = 0 Pause 20 ' this is the start pulse length - 20 for the DHT11 Pin(pn) = 1 SetPin pn, OFF ' make way for the ADC to take over the pin ADC OPEN 100000,pn,,,adc_done ' sample every 10uS ADC START a_in() Do Loop Until alldone = 1 For n = 0 To 500 If running = 0 Then If a_in(n) < 1.6 Then running = 1 EndIf If running Then If a_in(n) > 1.6 Then count = count + 1 Else If count > 0 Then If count > 5 Then reply$= reply$+"1" ' we could use an integer instead of a string Else reply$ = reply$+"0" EndIf count = 0 EndIf EndIf EndIf Next n For n = 0 To 4 repl(n) = Val("&b"+Mid$(reply$,n*8+x,8)) Next n hum = repl(0)+(repl(1)/10) tem = repl(2)+(repl(3)/10) If repl(4)<>((repl(0)+repl(1)+repl(2)+repl(3)) AND 255) Then :tem=1000:hum=1000: endif If (tem + hum) = 0 Then :tem=1000:hum=1000: endif 'output 1000 to indicate errors End Sub Sub adc_done alldone = 1 ADC CLOSE End Sub To compare this with Peters function load the above sub in program memory then, using pin15 (PC0) at the command prompt type:- do : dht11 15,T,H :? T,H, :pause 2000 : HUMID 15,T,H,1 :? T,H : pause 2000 :loop Edited 2021-06-22 15:05 by phil99 |
||||
phil99![]() Guru ![]() Joined: 11/02/2018 Location: AustraliaPosts: 2632 |
A Covid lockdown time waster. DHT11 sensors require a longer "wakeup" pulse and different decoding than the DHT22 but use the same communication protocol. The following does both. For MM2 and MM+ you will need the HUMID CSub from Humid.pdf in the documentation 'Reading DHT11 sensor using DHT22 CSub or HUMID function. 'Requires 2 pins. eg link pins 4 & 5 to DHT11 signal pin. 'Works on MM2 & MM+. ' On F4 & CMMs it gives 10ths of degrees. ' The normal DHT11 option does not. Do pin(5)=1 setpin 5,dout,oc pause 2000 pulse 20 pause 19 humid 4,T11,RH11 if RH11=1000 and T11=1000 then RH=1000 : T=1000 else T = fix(T11/25.6) + ((T11*10) MOD 256)/10 RH = fix(RH11/25.6) Endif setpin 5,off print "Temp ";T,"Humidity ";RH loop If you find it useful you can turn it into a Sub. If you have more than one DHT11 they can share the same pulse pin. Connect Schotky diodes from each DHT11 pin to the Pulse pin, with cathodes to the Pulse pin. Phil |
||||
toml_12953 Guru ![]() Joined: 13/02/2015 Location: United StatesPosts: 437 |
In the 05.07.01 manual it gives the syntax HUMID pinnum, temp, humidity [, DHT11] Where DHT11 is 1 if you're using the DHT11. It adjusts the timing to work with the 11. |
||||
matherp Guru ![]() Joined: 11/12/2012 Location: United KingdomPosts: 10288 |
This is available on the Armmite F4 and H7, the CMM2, and the PicoMite but not the MM2 or MM+ |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |