Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 14:00 05 May 2024 Privacy Policy
Jump to

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 Zealand
Posts: 711
Posted: 08:30am 03 Dec 2014
Copy link to clipboard 
Print this post

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 States
Posts: 172
Posted: 09:01am 03 Dec 2014
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 8592
Posted: 09:21am 03 Dec 2014
Copy link to clipboard 
Print this post

jman

Have a look at this thread - should be easy enough for you to port:


DHT11 in software

Key posts are by GoeytexEdited by matherp 2014-12-04
 
G8JCF

Guru

Joined: 15/05/2014
Location: United Kingdom
Posts: 676
Posted: 10:07am 03 Dec 2014
Copy link to clipboard 
Print this post

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 States
Posts: 74
Posted: 11:11pm 03 Dec 2014
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3663
Posted: 11:44pm 03 Dec 2014
Copy link to clipboard 
Print this post

And thus the request for a CFunction!

John
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 04:37am 04 Dec 2014
Copy link to clipboard 
Print this post

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;
}Edited by matherp 2014-12-05
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 08:54am 04 Dec 2014
Copy link to clipboard 
Print this post

@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 States
Posts: 925
Posted: 03:51pm 04 Dec 2014
Copy link to clipboard 
Print this post

the max7219 8x8 matrix looks pretty interesting..... just sayin'
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8592
Posted: 12:08am 05 Dec 2014
Copy link to clipboard 
Print this post

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;
}Edited by matherp 2014-12-06
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 10:15am 06 Dec 2014
Copy link to clipboard 
Print this post

@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: Australia
Posts: 320
Posted: 10:48am 06 Dec 2014
Copy link to clipboard 
Print this post

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: Australia
Posts: 5913
Posted: 11:10am 06 Dec 2014
Copy link to clipboard 
Print this post

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: Australia
Posts: 3165
Posted: 12:18pm 06 Dec 2014
Copy link to clipboard 
Print this post

  TassyJim said  '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.

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: Australia
Posts: 320
Posted: 01:59pm 06 Dec 2014
Copy link to clipboard 
Print this post

Hi jman
Can you layout the process for updating the ESP module.
Thanks
cliff
Cliff
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 05:36pm 06 Dec 2014
Copy link to clipboard 
Print this post

Hi Centrex, take a look here
 
centrex

Guru

Joined: 13/11/2011
Location: Australia
Posts: 320
Posted: 10:38pm 06 Dec 2014
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 8592
Posted: 11:18pm 06 Dec 2014
Copy link to clipboard 
Print this post

  Quote  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.


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 pinEdited by matherp 2014-12-08
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024