Y

DHT11 Sensörünü okuyamıyorum.

Başlatan yilber92, 12 Ocak 2013, 21:58:01

yilber92

Selamın Aleykun, günlerdir DHT11 sensörümü çalıştırmaya çalışıyorum. İnternet'te gezmediğim site, okumadığım yazı kalmadı ama bir türlü proton ile yazılmış DHT11 sensör okuma kodunu bulamadım.

16f877a (20mhz) kullanıyorum lütfen yardımcı olabilir misiniz. Öğrenci olduğum için pahalı nem sensörü alamıyorum, yardımlarınızı bekliyorum.

F®T

Re: DHT11 anyone?
by red_kooga » Mon Jul 18, 2011 8:44 am

I have found a more recent version that works properly, it is working on an amicus board.
I have also got it working with oshonsoft basic with assembler if you are interested.

Syntax: (code.bas) [ Download ] [ Hide ]
Using proton Syntax Highlighting
'Declare Xtal 16  'declare xtal to give exact delays
Dim ip As Byte  'hi pulse from sensor
Dim temp As Byte
Dim hum As Byte
Dim chksm As Byte
Dim temp1 As Byte
Dim hum1 As Byte
Dim temp2 As Word
Dim hum2 As Word
Dim test As Byte
Dim i As Byte
DelayMS 1000    'give sensor time to settle
loop:
chksm=0
TRISB.0 = 0     'portb o/p
PORTB.0=1        'make high
DelayMS 50    'wait for a while
PORTB.0=0:DelayMS 18 'send 18ms low
PORTB.0=1:DelayUS 30 'send 30us hi
ip = PulsIn PORTB.0,1  'wait for hi
If ip < 130 Then GoTo loop1  ' if < 80us loop
ip = 0
For i = 7 To 0 Step -1
ip = PulsIn PORTB.0,1  'recieve pulses from sensor
If ip >70 Then
SetBit hum,i
Else
ClearBit hum,i
EndIf
Next i
For i = 7 To 0 Step -1
ip = PulsIn PORTB.0,1  'recieve pulses from sensor
If ip >70 Then
SetBit hum1,i
Else
ClearBit hum1,i
EndIf
Next i
For i = 7 To 0 Step -1
ip = PulsIn PORTB.0,High  'recieve pulses from sensor
If ip >70 Then
SetBit temp,i
Else
ClearBit temp,i
EndIf
Next i
For i = 7 To 0 Step -1
ip = PulsIn PORTB.0,High  'recieve pulses from sensor
If ip >70 Then
SetBit temp1,i
Else
ClearBit temp1,i
EndIf
Next i
For i = 7 To 0 Step -1
ip = PulsIn PORTB.0,High
If ip >70 Then
SetBit chksm,i
Else
ClearBit chksm,i
EndIf
Next i
HRSOut "check sum ",Dec chksm,13 ' = chksm -1   'fudge to correct mis-read?

HRSOut "humidity ",Dec hum,".",Dec hum1,"%"
HRSOut  "  temperature ",Dec temp,".",Dec temp1,"C",13

test = (temp1 + hum1 + hum + temp)
If chksm <> test Then HRSOut "error",13

DelayMS 3000 'give sensor time to settle
GoTo loop
loop1:
HRSOut "sensor not ready",13
GoTo loop


sadece google a yazdım bu kod çıktı.
http://digital-diy.com/forum/proton-basic/dht11-anyone-t1716-10.html

"Hakk" şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

yilber92

#2
Evet bende bu kodu gördüm ve 16f877a için uyarladım fakat sensör çalışmadı. birde bu kodda 80ums yazıyor fakat 130 yazılmış. burayıda tam anlayamadım. belkide sorunum buradadır.

ete

Önclikle örnek kodların yanlış olduğunu söylemekle başlayayım. Neden yanlış olduğunu anlatmak epeyce uzun sürebilir. Bu nedenle öylece kabul edin verdiğim örnekle karşılaştırın. Bu sensörü henüz fiziksel olarak elime alamadım. Ancak data sheet'i açıp şöyle bir göz gezdirdim. Bence berbat bir haberleşme mantığı var. Her neyse  devam edelim.
Bu sensörün okunabilmesi için 3 şartın yerine getirilmesi gerekiyor.
1. Sensöre okuma yapacağını bildirmen gerekiyor. Bu başlangıç aşaması
2. Sensöe yaptığın bildirimden sonra onun bundan haberi oldumu diye cevabını alman gerekiyor
3. Cevap doğru geldi ise her şey yolundadır deyip 40 bitlik verileri okuman gerekiyor.
1. maddeden başlayalım.
Sensöre Okuma yapmak istediğini nasıl bildireceksin?
Data sheet şöyle söylüyor,
Data pinini LOW'a çek 18ms bekle Sonra HIGH yap ve 30-40us bekle
Bunun komut karşılığı şöyle;
OUTPUT DTA  'data pinini çıkış yaptık
LOW DTA      'pini LOW'a çektik
Pause 18     '18ms bekledik
HIGH DTA    'pini bu seferde HIGH yaptık
PAUSEUS 40  '40 us bekledik.
INPUT DTA    'cevap alabilmemiz için Data pinini INPUT yaptık.

2. Maddeye geçersek Data sheet şöyle söylüyor,
Sensör 54us süre ile Data pinini LOW a çekecek ve ardından 80us süre ile HIGH da tutacak.
Burada yazacağımız komut illaki data hattının önce low'a sonrada High'a sırası ile bakmasını gerektirmiyor bence.
Yalnızca HIGH beklersek işimizi halledebiliriz. O halde şöyle bir kod yazabiliriz.
PULSIN DTA,1,SURE 
IF SURE > 8 then HATAVAR
Burada HIGH süresi olarak puls miktarını okumaya çalışıyoruz. PULSIN komutu 4 Mhz lik krsital ile çalışıldığı durumda 10us nin katları şeklinde okuma yapar. Yukarıda verilen kodlardaki hatalardan biriside budur. 80us lik bir HIGH okunacak ise bu PULSIN komutunda 8us olarak kayıt edilir. Süre8 den büyük ise (yani 80 den büyük ise demektir) hata var demek olur ve ne yapılacak sa yapılmalıdır.
Buraya kadar işlerin yolunda gittiğini varsayalım. Şimdi artık 3. maddeye yani 40 bitlik verileri okumaya geçebiliriz demektir.
Data sheet veriler hakkında şunu söylüyor.
LOW biti için 54us LOW ve ardından 24us HIGH
HIGH biti için 54us LOW ve ardından 70us HIGH olması gerekiyor.
Dikkat ederseniz bir bitlik bilgi iki bit ile ifade edilmiş. Ancak bitlerin LOW süreleri bir birlerine eşit. O halde bize düşen HIGH bitlerinin sürelerini  kayıt ederek onların 24us mi yoksa 70us olduklarına bakarak bitlerin Hıgh mi yoksa Low mu olduklarına karar vereceğiz.
O halde öncelikle değişken tanımlama kısmında 40bitlik bir dizi değişkeni tanımlamak gerekir.  Değişkenimiz AL[40] şeklinde tanımlanmış olsun.
Önce 0 ile 39 arasında çalışacak bir döngü kurarım.
FOR I=0 to 39
  PULSIN DTA,1,AL[I]
Next
Bu şekilde 40 adet bitin sürelerini bu şekilde okurum.
Sonra bunları ayıklamak gerekecek. Okunan datalar MSBfirst yani yüksek duyarlıklı bit önce okunduğu için yerleştirme yaparkenbuna dikkat etmem gerekiyor.
Önce Rutubet Tamsayı kısmı buna TAM_RUT diyelim.
TAM_RUT=0:X=7
FOR I=0 to 7
  IF  AL[I]=7 THEN TAM_RUT.0[X]=1  (Buraya IF AL[I]>2 THEN TAM_RUT.0[X]=1 de denilebilir)
  X=X-1
Next
Buraya kadar okunan değerlere göre Rutubet tamsayı kısmını elde etmiş olacağız. Şimdi Rutubet Ondalıkkısmını alalım.
ONDA_RUT=0:X=7
FOR I=8 to 15
    IF AL[I]=7 THEN ONDA_RUT.0[X]=1
    X=X-1
Next
Buraya kadar ondalık rutubeti de okumuş olduk.

Şimdi Sıcaklık Tam sayı kısmını alalım.
TAM_ISI=0:X=7
FOR I=16 to 23
  IF AL[I]=7 then TAM_ISI.0[X]=1
  X=X-1
Next
Şimdi Sıcaklıkondalıkkısmını alalım.
ONDA_ISI=0:X=7
FOR I=24 to 31
  IF AL[I]=7 then ONDA_ISI.0[X]=1
  X=X-1
Next
Böylece okuma işlemini tamamlamış oluyoruz. Artık bundan sonrası okunanları ekrana vermek olacaktır. Onuda yaparsınız her halde.

Örnek programda PULSIN kullanılmış ama okuma formatı dikkate alınmamış.
Bu yazdığım kod örnekleri PBP ya göre yazıldı. Birisi onları Proton'a çevirebilir sanırım. Yada diğer örnek içine monte edebilirsiniz.

Ete

yilber92

Çok teşekkür ediyorum zaman ayırdığınız için. Allah razı olsun.

Eğer çalıştırabilirsem kodu burada paylaşaçağım. Hayırlı geceler.

Reytabu

Ete Hocam

Derslerinizden ve bu konudaki açıklamınızdan faydalanarak DHT 11 ile sıcaklık ve nem ölçmeye çalışıyorum.
Ekteki devreyi kurdum ve ekteki programı pic'e attım. Ekrana programın başında atamış olduğum
sıcaklık=0, nem=0 değerleri geliyor. Programı bir gözden geçirebilir misiniz?

Saygılarımla

ete

Gördüğüm kadarı ile programdaki iki eksik bulunuyor.
Birincisi;
A portunu digital yapması gereken  "CMCON=7" komutu
Bir diğeride programın hangi kristal frekansında çalıştığını belirleyen "Define OSC 4 " komutu.
Bir defa bu komutların programa eklenmesi gerekiyor. AKsi taktirde program doğru bile olsa çalışmayacaktır.
Bunlarıda ilave ettikten sonra yeniden dene. Ancak Sensör okuma kısmından sonra okunan değerleri ekrana vermek gerekir.
Bunun için programda  başla satırından sonra yer alan LCD komutlarını kaldır ve aşağıdakileri sensör okumadan sonra ilave et.

LCDOUT $FE,$80,"ISI =",dec TAMRUT,",",Dec1 ONDARUT
LCDOUT $FE,$C0,"NEM=",dec TAMISI,",",Dec1 ONDAISI
PAUSE 100

Ete

Reytabu

#7
Sayın Hocam

Dediğiniz gibi cmcon=7 ve define osc 4 komutlarını ilave edip
lcd komutlarını da okuma bölümünden sonraya aldım. Ekteki dosyada
fotoda gözüktüğü gibi ısı ve nemi 0,0 gösteriyor.
Anladığım kadarıyla aşağıdaki komutları uygulayarak  Sensörün yanıt için gönderdiği SURE değişkeninde izlenen high 'ın
değerini aşağıdaki komutlarla ekrana göstermek istedim sure=0 çıkıyor.


@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF


PORTA=0
TRISA=0
PORTB=0
TRISB=0

CMCON=7
define OSC 4 
   

DEFINE LCD_DREG PORTB 'LCD data bacakları PortB de bağlı
DEFINE LCD_DBIT 4 'LCD data bacakları 4. bitten başlıyor
DEFINE LCD_EREG PORTB 'LCD Enable Bacağı PortB de bağlı
DEFINE LCD_EBIT 3 'LCD Enable Bacağı 3. bite bağlı
DEFINE LCD_RWREG    PORTB 'LCD RW Bacağı PortB de bağlı
DEFINE LCD_RWBIT      2 'LCD RW Bacağı  2. bite bağlı
DEFINE LCD_RSREG PORTB 'LCD RS Bacağı PortB de bağlı
DEFINE LCD_RSBIT 1 'LCD RS bacağı 1. Bite bağlı
DEFINE LCD_BITS 4 'LCD 4 bit  olarak bağlı
DEFINE LCD_LINES 2 'LCD 2 sıra olarak çalışıyor.


SURE var byte
I VAR BYTE
AL VAR BYTE[40]
TAMRUT VAR BYTE
ONDARUT VAR BYTE
TAMISI VAR BYTE
ONDAISI VAR BYTE
X VAR BYTE
symbol dta=portA.1 'sensor dATA PİNİ PORTA.1 A BAĞLI



OUTPUT DTA 'data pinini çıkış yaptık
HIGH DTA
PAUSE 50
LOW DTA 'pini LOW'a çektik
Pause 18 '18ms bekledik
HIGH DTA 'pini bu seferde HIGH yaptık
PAUSEUS 40 '40 us bekledik.
INPUT DTA 'cevap alabilmemiz için Data pinini INPUT yaptık.
PULSIN DTA,0,SURE

LOW PORTB.2      'RW bacağı ekrana yazmaya imkan vermek için LOW yapıldı.
PAUSE 200                    ' LCD nin kullanıma hazır hale gelebilmesi için gerekli süre
LCDOUT $FE,1              'Önce Ekranı siliyoruz.
LCDOUT $FE,$80,"SURE =",dec SURE

End
      

Sizce mantığım doğru mu? Doğru ise sensör yanıt vermiyor mu (arıza vs) acaba?

Saygılarımla

ete

Bir programın program olabilmesi için kurallara uygun olarak yazılması gerekir. Senin programında kural falan yok. Amacını anlamış değilim. Sensörden okuma yapmadan ne görmeyi bekliyorsun?
İlk yazılanlar doğru idi bu son yazılanda okuma kodları eksik neden ?
Ete

Reytabu

Alıntı yapılan: ete - 12 Ocak 2013, 23:27:08
Önclikle örnek kodların yanlış olduğunu söylemekle başlayayım. Neden yanlış olduğunu anlatmak epeyce uzun sürebilir. Bu nedenle öylece kabul edin verdiğim örnekle karşılaştırın. Bu sensörü henüz fiziksel olarak elime alamadım. Ancak data sheet'i açıp şöyle bir göz gezdirdim. Bence berbat bir haberleşme mantığı var. Her neyse  devam edelim.
Bu sensörün okunabilmesi için 3 şartın yerine getirilmesi gerekiyor.
1. Sensöre okuma yapacağını bildirmen gerekiyor. Bu başlangıç aşaması
2. Sensöe yaptığın bildirimden sonra onun bundan haberi oldumu diye cevabını alman gerekiyor
3. Cevap doğru geldi ise her şey yolundadır deyip 40 bitlik verileri okuman gerekiyor.
1. maddeden başlayalım.
Sensöre Okuma yapmak istediğini nasıl bildireceksin?
Data sheet şöyle söylüyor,
Data pinini LOW'a çek 18ms bekle Sonra HIGH yap ve 30-40us bekle
Bunun komut karşılığı şöyle;
OUTPUT DTA  'data pinini çıkış yaptık
LOW DTA      'pini LOW'a çektik
Pause 18     '18ms bekledik
HIGH DTA    'pini bu seferde HIGH yaptık
PAUSEUS 40  '40 us bekledik.
INPUT DTA    'cevap alabilmemiz için Data pinini INPUT yaptık.

2. Maddeye geçersek Data sheet şöyle söylüyor,
Sensör 54us süre ile Data pinini LOW a çekecek ve ardından 80us süre ile HIGH da tutacak.
Burada yazacağımız komut illaki data hattının önce low'a sonrada High'a sırası ile bakmasını gerektirmiyor bence.
Yalnızca HIGH beklersek işimizi halledebiliriz. O halde şöyle bir kod yazabiliriz.
PULSIN DTA,1,SURE 

Ete


Sayın Ete ben ısı ve nem değerlerini sıfır olarak ekranda görünce kendimce  hatanın nereden kaynaklandığını tespit etmek amacıyla:
Yazınız 1. maddede gönderdiğimiz 18 ms low, 40 us high tan sonra sensörün göndermesi gereken (yazınızdaki 2. madde) 80 us high ı gönderip göndermediğini ölçmek istemiştim sadece. Demiştiniz ya 1. ve 2. maddede şartlar sağlandıktan sonra ısı ve nem değerleri okunabilir diye. 1. ve 2. maddeki şartların sağlandığını test etmek istemiştim.
Yoksa tabiiki programın o bölümüyle sensördeki ısı ve nem bilgileri  okunamayacak.


ete

#10
Reytabu,
Amacının sensörün cevap verip vermediğini tespit etmek olduğuynu varsayalım. Bu ana kadar yazdıklarını yok sayalım.
Aşağıda yeniden ne yapılması gerektiğini yeniden belirleyelim.
OUTPUT DTA   'Data pinini Çıkış yap
DTA=0            'data pinini LOW a çek
Pause 18       '18 ms bekle
DTA=1           'Data pinini High yap
Pauseus 40   '40 us bekle
Input DTA      '
While DTA=0:Wend
Pulsin DTA,1,Sure
LCDOUT $fe,$c0,"sure=",dec sure
şeklinde geçen süreye bakmak gerekiyor. Süre 8 civarında bir rakam ise sensörü okuyabiliyorsun demektir.
Değilse ya bağlantıların yanlış yada sensör arızalıdır.  Bir üçüncü alternatif daha varki oda bizim daha doğrusu benim data sheet den anladıklarım ve buna karşı ortaya koyduğum kod örnekleri yanlış.

Ete

Reytabu

#11
Ete Hocam,

Öncelikle çok teşekkür ederim hızlı yanıtlarınız için.
Ben PİC programlamayı sizden öğrenmeye çalışıyorum. Ayrıca elektronikçi de değilim onu da öğrenmeye çalışıyorum
Bu bakımdan bazı konuları tam anlayamıyorum ve derdimi de tam anlatamıyorum . Ama ne yapmak istediğimi anlamışsınız.
Dediğiniz gibi amacım sensörü test etmek idi.
Verdiğiniz kodları pic e aşağıdaki şekilde attım.
TRISA=0  'A portu çıkış olarak ayarlandı.
TRISB=0  'B portu çıkış olarak ayarlandı.
PORTA=0
CMCON=7


DEFINE OSC 4
SURE var byte
symbol dta=portA.1 'sensor dATA PİNİ PORTA.1 A BAĞLI
PAUSE 200

BASLA:
OUTPUT DTA   'Data pinini Çıkış yap

DTA=0            'data pinini LOW a çek
Pause 18       '18 ms bekle
DTA=1           'Data pinini High yap
Pauseus 40   '40 us bekle
Input DTA      '
While DTA=1:Wend
Pulsin DTA,1,Sure
PAUSE 200
LCDOUT $fe,$c0,"sure=",dec sure
GOTO BASLA
End

                  

Çok şükür sonuç tahmin ettiğiniz gibi sure=8 çıktı.
Bu durumda sonuç alamadığım 12.24 saatli mesajım ekindeki programda bir değişiklik önerecek misiniz?

ete

Sensör ile haberleşmeni sağladığıma göre gerisini halledersin diye umuyordum. Öneri beklemen gerekmiyor.
İlk programda yazdıklarını deneyerek ama sensörü test eden kısmı yeni verilenle değiştirerek haberleşmeyi sağlayabilirsin.

Ete

ete

#13
Bir ses çıkmadı ya yapamadın yada uğraşamadın.
Her neyse biraz daha yön verelim o zaman.
Bildiğiniz üzere bu sensörle haberleşmek için,
- Önce istek yapmak gerekiyor. DTA hattını 18 ms süresince LOW da tutmak ardından 40us süresince High da tutmak bu işi yerine getiriyor.
- Sonra yapılan isteğe karşılık sensörden gelen cevabı algılamak gerekiyor. Buda DTA hattını giriş yapıp önce 54us lik low ve ardından 80us lik high peryodunu yakalamak şeklinde yapılıyor.
- Bu işlemlerden sonra sensör artık verilerim hazır okuyabilirsin diyor. O halde yapılacak iş 40 adet puls okumak şeklinde uygulanıyor.
Sensör verdiği bilgiyi iki bit ile ifade ediyor. 54us lik bir low ve ardından 24us lik bir High sinyali LOW bitini ifade ediyor.
Yine 54us lik bir Low ve ardından 70us lik bir High sinyali ise HIGH bitini ifade etmektedir. Başlangıç bitleri ikisinde de aynı olduğuna göre bizim yapmamız gereken yalnızca HIGH pitlerini süre oalrak kayıt edip sonra bunu inceleyip bitler konusunda karar vermek olmalıdır.
İşe baştan başlayalım,
OUTPUT DTA
DTA=0
PAUSE 18
DTA=1
PAUSEUS 40
INPUT DTA
PULSIN DTA,1,SURE  'burada sensör cevabının yalnızca High olan kısmını algılıyoruz. Oda paket başlangıcını doğru bulmak için.
FOR I=0 to 39
  PULSIN DTA,1,AL[I]
NEXT
Şimdi ayıklama işini yapalım.
TAM_RUT=0:X=7 'bu satırlar ile rutubet değeri tamsayı kısmını ayıklıyoruz.
FOR I=0 to 7
  IF AL[I]>2 THEN TAM_RUT.0[X]=1
  X=X-1
Next
Şimdi Rutubet ondalık kısmını ayıklayalım,
ONDA_RUT=0:X=7 'bu satırlar ile rutubet değeri Ondalık kısmını ayıklıyoruz.
FOR I=8 to 15
  IF AL[I]>2 THEN ONDA_RUT.0[X]=1
  X=X-1
Next
Şimdi Sıcaklık Tamsayı kısmını ayıralım,
TAM_ISI=0:X=7
FOR I=16 to 23
  IF AL[I]>2  Then TAM_ISI.0[X]=1
  X=X-1
Next
Şimdi Sıcaklık ondalık kısmını alalım.
ONDA_ISI=0:X=7
FOR I=24 to 31
  IF AL[I]>2 Then ONDA_ISI.0[X]=1
  X=X-1
Next

Bütün bilgiyi ayırmış olduk. Geriye bunların ekrana yazdırılması kalırki onuda anlatmaya gerek yok sanırım.

Ete





Reytabu

#14
Hocam

Çaresizce çabalayıp dururken imdadıma yetiştiniz.
Program sensörle haberleşip okumaya geçiyor ama sonuç ısı=0,0 nem=0,0 olarak gelmektedir.
programı bütünüyle bir inceleyebilir misiniz.

BASLA:
OUTPUT DTA   'Data pinini Çıkış yap

DTA=0            'data pinini LOW a çek
Pause 18       '18 ms bekle
DTA=1           'Data pinini High yap
Pauseus 40   '40 us bekle
Input DTA      ' data pinini giriş yap
Pulsin DTA,1,Sure 'high süresini yaz
IF SURE <> 8 THEN hata

FOR I=0 to 39
PULSIN DTA,1,AL[I]
Next

TAMRUT=0:X=7
FOR I=0 to 7
IF AL[I]>2 THEN TAMRUT.0[X]=1
X=X-1
Next

ONDARUT=0:X=7
FOR I=8 to 15
IF AL[I]>2 THEN ONDARUT.0[X]=1
X=X-1
Next

TAMISI=0:X=7
FOR I=16 to 23
IF AL[I]>2  Then TAMISI.0[X]=1
X=X-1
Next

ONDAISI=0:X=7
FOR I=24 to 31
IF AL[I]>2 Then ONDAISI.0[X]=1
X=X-1
Next

LCDOUT $FE,$80,"ISI =",dec TAMRUT,",",Dec1 ONDARUT
LCDOUT $FE,$C0,"NEM=",dec TAMISI,",",Dec1 ONDAISI
PAUSE 100

GOTO BASLA

hata:
LCDOUT $FE,$80,"SENSOR HATASI"
End

Powered by EzPortal