Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : DHT11
Author | Message | ||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
Hi Could one the CFunction gurus (Matherp or Peter)be so kind as to put together a library for the DHT11 sensor I know the DHT22 is better but I got a few DHT11's that would be nice to use on the UMite Thanks in advance Jman |
||||
Oldbitcollector Senior Member Joined: 16/05/2014 Location: United StatesPosts: 172 |
For reference: (jman, this may or may/not help you) There is Ardunio (C code) on the page that might give you a starting point for this device. Reading through this, it appears that you "might" be able to do this in MMBASIC without a Cfunction, but I don't have a DHT11 to test here. Jeff My Propeller/Micromite mini-computer project. |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8603 |
jman Have a look at this thread - should be easy enough for you to port: DHT11 in software Key posts are by Goeytex |
||||
G8JCF Guru Joined: 15/05/2014 Location: United KingdomPosts: 676 |
Sorry JMAN, I don't have either of those devices, but the links PeterM has given you look very helpful Peter The only Konstant is Change |
||||
Goeytex Regular Member Joined: 12/05/2014 Location: United StatesPosts: 74 |
I am afraid that the command latency/processor overhead of the Micromite will prevent it from reading a DHT11 sensor using MMBASIC alone. The DHT-11 sends out a pulse stream of 40 bits, but there is only 50us between bits. The Micromite has a command latency of about 70 us so bits will be missed using pulsein. It may work with the addition of a one shot used as a pulse stretcher to stretch the 50us between bits, but I think a better solution would be a C function. Whether the one shot will work depends upon the actual overhead of the pulsein command. If it can read a 7us pulse into memory and jump to the next pulsein command before the next pulse arises then it will work. A uMite may be too slow, but testing should be easy enough. Here's another link |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3677 |
And thus the request for a CFunction! John |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8603 |
That is a really boring chip - in future can we have requests for interesting stuff Unfortunately I found one in my "useless old things I'm never going to use again" box. So: NB: currently only works on pin 2: Also, note the chip is only specified down to 3.5V so operation may be marginal on 3.3V. option default integer option explicit cpu 40 dim float temperature,humidity dht11(temperature,humidity) print "Temperature is ",temperature,"C : Relative Humidity is ",humidity,"%" end ' sub dht11(temp as float, humi as float) local integer rawdata(41),i,scale,th,tl,hh,hl,ck pin(2)=1 setpin 2,dout pulse 2,2 '2msec pulse to trigger conversion setpin 2,din 'set the pin to input must be pulled high by resistor, 4K7 tested i= DHT11conv(rawdata()) if i=-1 then 'no return from chip temperature=-1000 humidity=-1000 else th=0 tl=0 hh=0 hl=0 ck=0 scale=rawdata(0) \2 'get the reported length of an 40usec pulse for i=0 to 7 if rawdata(i+1)>scale then hh=hh or (1<<(7-i)) if rawdata(i+9)>scale then hl=hl or (1<<(7-i)) if rawdata(i+17)>scale then th=th or (1<<(7-i)) if rawdata(i+25)>scale then tl=tl or (1<<(7-i)) if rawdata(i+33)>scale then ck=ck or (1<<(7-i)) next i if ((hh+hl+th+tl) and &HFF)<>ck then 'checksum failed temperature=-1000 humidity=-1000 else i=1 if th and &H80 then i=-1 th=th and &H7F temp=(th+tl/10)*i humi=hh+hl/10 endif endif end sub ' CFunction dht11conv 00000000 3c02bf80 34038030 ac430600 ac400610 3c03bf88 3c06bf80 3405ea60 8c626020 30420001 10400005 3c02bf80 8cc20610 0045102b 1440fff9 3c02bf80 8c430610 3402ea60 0062102b 2406ffff 10400043 2407ffff 3c02bf80 34038010 ac430600 ac400610 3c03bf88 3c06bf80 34059c40 8c626020 30420001 14400005 3c02bf80 8cc20610 0045102b 1440fff9 3c02bf80 8c430610 34029c40 0062102b 2406ffff 1040002e 2407ffff 3c02bf80 ac400610 00004821 34039c40 3c05bf88 10000022 240b0029 8ca86020 31080001 11000005 00000000 8c480610 0103402b 1500fff9 00000000 8c4a0610 000940c0 00884021 ad0a0000 ad000004 8c480610 0103402b 11000003 00000000 ac400610 25290001 8ca86020 31080001 15000005 00000000 8c480610 0103402b 1500fff9 00000000 8c480610 0103402b 55000001 ac400610 112b0005 01203021 8c480610 0103402b 1500ffdc 01203021 00003821 00c01021 03e00008 00e01821 End CFunction long long dht11conv(long long log[]){ unsigned int i; #define tmr1con *(volatile unsigned int *)0xbf800600 //timer 1 configuration register #define tmr1 *(volatile unsigned int *)0xbf800610 //timer 1 counter #define porta *(volatile unsigned int *)0xbf886020 //port a tmr1con=0x8030; //turn on with scale 256 i=0; tmr1=0; while (((porta&1)==1) && (tmr1<60000)); //wait for low while dht processes if(tmr1>=60000) return -1; tmr1con=0x8010; //rescale 8 tmr1=0; while (((porta&1)==0) && (tmr1<40000)); //wait for the next high if(tmr1>=40000) return -1; tmr1=0; //reset the timer while (tmr1<40000){ while (((porta&1)==1) && (tmr1<40000)); //wait for low log=tmr1; if (tmr1<40000){ tmr1=0; i++; } while (((porta&1)==0) && (tmr1<40000)); //wait for the next high if (tmr1<40000) tmr1=0; //valid pulse so reset timer if (i==41) break; } return i; } |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
@matherp Thanks for this works a treat Promise I look for an "Interesting item next" :) Regards Jman |
||||
viscomjim Guru Joined: 08/01/2014 Location: United StatesPosts: 925 |
the max7219 8x8 matrix looks pretty interesting..... just sayin' |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8603 |
Here is a version that should work for any valid pin on a 28 or 40 pin processor. If there is anyone who can test on a 40 pin version that would be appreciated. As always this stupid board puts unwanted spaces into the listings, make sure you remove them from the p28$ and p40$ strings. option default integer option explicit cpu 40 dim float temperature,humidity dht11(16,temperature,humidity) print "Temperature is ",temperature,"C : Relative Humidity is ",humidity,"%" end ' function getpin(MMpin as integer,portnum as integer,pinnum as integer) const P28$="N/AA00A01B00B01B02B03N/AA02A03B04A04N/AB05B06B07B08B09 N/AN/AB10B11B12B13B14B15N/AN/A" const P40$="B09C06C07C08C09N/AN/AB10B11B12B13A10A07B14B15N/AN/AN/A A00A01B00B01B02B03C00C01C02N/AN/AA02A03A08B04A04A09C03C04C05 N/AN/AB05B06B07B08" local i local a$ length 3 i=(MMpin-1)*3 +1 if (peek(word &HBF80F220) and &HFFFFFFF) = &H6610053 then if MMpin>=1 and MMpin<=28 then a$=mid$(p28$,i,3) else a$="N/A" endif else if MMpin>=1 and MMpin<=40 then a$=mid$(p40$,i,3) else a$="N/A" endif endif if a$="N/A" then getpin=0 else portnum=asc(left$(a$,1))-65 pinnum=val(right$(a$,2)) getpin=1 endif end function ' sub dht11(pinnum as integer,temp as float, humi as float) local integer rawdata(41),i,scale,th,tl,hh,hl,ck,myport,mypin pin(pinnum)=1 setpin pinnum,dout pulse pinnum,2 '2msec pulse to trigger conversion setpin pinnum,din 'set the pin to input must be pulled high by resistor 4K7 tested if getpin(pinnum,myport,mypin) then i= DHT11conv(myPort,mypin,rawdata()) if i=-1 then temperature=-1000 humidity=-1000 else th=0 tl=0 hh=0 hl=0 ck=0 scale=rawdata(0) \2 'get the reported length of an 40usec pulse for i=0 to 7 if rawdata(i+1)>scale then hh=hh or (1<<(7-i)) if rawdata(i+9)>scale then hl=hl or (1<<(7-i)) if rawdata(i+17)>scale then th=th or (1<<(7-i)) if rawdata(i+25)>scale then tl=tl or (1<<(7-i)) if rawdata(i+33)>scale then ck=ck or (1<<(7-i)) next i if ((hh+hl+th+tl) and &HFF)<>ck then temperature=-1000 humidity=-1000 else i=1 if th and &H80 then i=-1 th=th and &H7F temp=(th+tl/10)*i humi=hh+hl/10 endif endif else temperature=-1000 humidity=-1000 endif end sub ' CFunction dht11conv 00000000 8c830000 24040001 10640005 24040002 10640006 3c08bf88 10000005 25086020 3c08bf88 10000002 25086120 25086220 34048030 3c03bf80 ac640600 8ca30000 24070001 00673804 3c05bf80 3404ea60 8d030000 00671824 10600005 3c03bf80 8ca30610 0064182b 1460fff9 3c03bf80 8c640610 3403ea60 0083182b 2404ffff 10600040 2405ffff 3c03bf80 34048010 ac640600 ac600610 3c05bf80 34049c40 8d030000 00671824 14600005 3c03bf80 8ca30610 0064182b 1460fff9 3c03bf80 8c640610 34039c40 0083182b 2404ffff 1060002c 2405ffff 3c03bf80 ac600610 34099c40 10000022 240c0029 8d0a0000 01475024 11400005 00000000 8c6a0610 0149502b 1540fff9 00000000 8c6b0610 000250c0 00ca5021 ad4b0000 ad400004 8c6a0610 0149502b 11400003 00000000 ac600610 24420001 8d0a0000 01475024 15400005 00000000 8c6a0610 0149502b 1540fff9 00000000 8c6a0610 0149502b 55400001 ac600610 104c0005 00e02021 8c6a0610 0149502b 1540ffdc 00e02021 00002821 00801021 03e00008 00a01821 End CFunction long long dht11conv(unsigned int *portname,long long *mypin,long long log[]){ unsigned int i,j; #define mytmr1con *(volatile unsigned int *)0xbf800600 //timer 1 configuration register #define mytmr1 *(volatile unsigned int *)0xbf800610 //timer 1 counter unsigned int volatile * myport; if(*portname==0) myport=(volatile unsigned int *)0xbf886020; if(*portname==1) myport=(volatile unsigned int *)0xbf886120; if(*portname==2) myport=(volatile unsigned int *)0xbf886220; mytmr1con=0x8030; //turn on with scale 256 j=1<<*mypin; while (((*myport&j)!=0) && (mytmr1<60000)); //wait for low while dht processes if(mytmr1>=60000) return -1; mytmr1con=0x8010; //rescale 8 mytmr1=0; while (((*myport&j)==0) && (tmr1<40000)); //wait for the next high if(mytmr1>=40000) return -1; mytmr1=0; //reset the timer while (mytmr1<40000){ while (((*myport&j)!=0) && (mytmr1<40000)); //wait for low log=mytmr1; if (mytmr1<40000){ mytmr1=0; i++; } while (((*myport&j)==0) && (mytmr1<40000)); //wait for the next high if (mytmr1<40000) mytmr1=0; //valid pulse so reset timer if (i==41) break; } return j; } |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
@matherp Thank you very much for the updated any pin version Unfortunately I don't have a MX170 44 pin to test with While testing on 28pin version I noticed an issue with running the process more than once see output below Temperature is 25 C : Relative Humidity is 38 % [41] Pin(pinnum)=1 Error: Pin is not an output To resolve this the two lines below need to be swopped around now we have the following output Temperature is 25 C : Relative Humidity is 39 % Temperature is 25 C : Relative Humidity is 39 % Temperature is 25 C : Relative Humidity is 39 % blah blah [code] pin(pinnum)=1 setpin pinnum,dout [/code] [code] setpin pinnum,dout pin(pinnum)=1 [/code] |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Hi jman I note there is a very similar line in the "garden"code Option autorun on WatchDog 60 * 1000 Pin(2) = 0 SetPin 2, dout It is also in the origonal code from Geoffg. Has this caused any errors. interested cliff Cliff |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 5923 |
It is OK and advisable to set the pin level before setting it to an output. This can be done before the pin direction is set and prevents spurious pulses. I suspect that 'CFunction dht11conv' is leaving the pin as an input. 'I think' that: The option to set the pin level is only valid before any direction setting is done. Once the pin direction has been set to IN, the pin(x)=y command throws an error. In Geoff's code the pin is set once at the beginning of the code and only ever runs the one time. Jim VK7JH MMedit MMBasic Help |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3167 |
That is correct. The only issue is that MMBasic does not know what is going on inside the CFunction so it will think that the pin is still set as an output. There is a subtle bug which might be causing this issue. This only happens if a program has set a pin as an output and it is high. In that case, when the program is RUN a second time, the pin will be pulled low for about 2uS before the BASIC program starts running. I don't know if this is the cause of the problem but it will be fixed in the next beta due out in a day or two. Geoff Geoff Graham - http://geoffg.net |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Hi jman Can you layout the process for updating the ESP module. Thanks cliff Cliff |
||||
viscomjim Guru Joined: 08/01/2014 Location: United StatesPosts: 925 |
Hi Centrex, take a look here |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Hi viscomjim You lost me, in the update section it mention an update 9022 or something like that but it does not appear to be a bin file like the one jman mentions in another post. Also where is xtcomutil.zip nothing comes up when googled. My device is still on the the slow boat from and only one of them, I want to be sure of what I am doing before committing power. thanks for your trouble cliff Cliff |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8603 |
Sorry I hadn't realised this. pin(x)=1 should appear in the main program before the first call to dht11 and outside any loop. Then as jman identifies the order should be switched inside dht11. The issue is just to make sure that we don't get an initial low output on the sensor which would trigger a reading. The cFunction does not change the DIN, DOUT status of the pin |
||||
Print this page |