ds18b20 den bigi okuma

Başlatan fahrettink, 04 Mayıs 2012, 14:21:53

fahrettink

Herkese merhaba,

Ete hocanın derslerinden 74hc595 mantığı üzerine çalışıyorum.

Olayı kavradım diyebilirim. Hatta bu mantıkla bir kaç butonlu sayıcı devresi yapıp çalıştırdm.

Şimdi aynı mantığı kullanarak 3 digit termometre üzerinde çalışıyorum. (İlk ikisi tamsayı, 3. sü ondalık olacak)

Fakat ds18b20 den gelen veriyi tamsayı ve bir ondalık olarak nasıl gösterebilirim çözemedim.

Yani sensörden bir veri geliyor bunu iki haneli tamsayısını hesaplayıp ilk rakamı dig1 e ikinci rakamı dig2 ye sonrada ondalık kısmı hesaplayıp dig3 e değişkenler vasitasıyla aktarmak istiyorum.

Aşağıdaki programda ilk önce sadece 3. digitte ondalık sayıyı göstermeye çalıştım. Programı inceleyip bilgi verebilecek arkadaşlardan Allah razı olsun.


TRISA=%11111 'A portu Çıkış olarak ayarlandı
TRISB=%00000000
PORTA=0
PORTB=0
'-----------------------------------------------------------------
SENSOR VAR PORTA.0 'Sensör PORTA.0 da bağlı
MESGUL VAR BYTE 'Çeşitli değişken tanımlamaları
BILGI VAR WORD
ONDA1 VAR WORD
ARA VAR WORD
DEGER VAR BYTE
ISARET VAR WORD
SAYI VAR BYTE
'-----------------------------------------------------------------
BASLA: 'Dongüye gir.
OWOUT SENSOR,1,[$CC,$44] 'Sensöre sıcaklığı okumasını söyle.
BEKLE: 'Sensör hazır olana kadar bekle.
OWIN SENSOR,4,[MESGUL]
IF MESGUL=0 THEN
GOTO BEKLE
ENDIF

DEVAM:
OWOUT SENSOR,1,[$CC,$BE] 'Sensöre okuduğu değeri göndermesini söyle.
OWIN SENSOR,0,[BILGI.LOWBYTE,BILGI.HIGHBYTE] 'Gelen 16 bitlik bilgiyi al.
ARA=BILGI*625 '12 bit hassasiyet kullandığımız için her değer 0.0625 santigrat dereceye denk geliyor.
DEGER=DIV32 10000
ONDA1= DIV32 1000
ONDA1=ONDA1-(DEGER*10)
GOSUB YAZ
GOTO BASLA 'BASLA etiketine dön

YAZ:
GOSUB TABLO
SHIFTOUT PORTB.0,PORTB.1,1,[SAYI] 'isaret degerini registere yaz
PORTB.4=1
PAUSEUS 2
PORTB.4=0
PAUSE 200
RETURN

TABLO: LOOKUP ONDA1,[63,6,91,79,102,109,125,7,127,111],SAYI
RETURN

END



Devre şeması;

[IMG]http://www.fotocu.org/?di=FS8K[/img]
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

fahrettink

Aslında burada benim için en önemli olan sensörden gelen verinin ilk hali ne, nasıl hesaplanıyor ve sonra nasıl tamsayı ve ondalıklara ayrılıp değişkenlere atanabiliyor? Kodun yazılıp hazır verilmesini istemiyorum. Mantığını anlamaya çalışıyorum.

Teşekkür ederim.
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

ete

#2
Ondlıklı sayı gösterimi için daima gösterilecek sayıyı 10 ile çarpılmış halde hesaplayınız.
Sıcaklık 23,6 derece ise siz bunu sensörden mutlaka 236 olarak hesaplayıp alınız. Bu şekilde yaparsanız işiniz son derece kolay.
Hesap kısmına sonra geçeceğim. Gösterme meselesinde elinde 236 sayısı olunca bütün yapman gerekenler şunlar,
ONDALIK=SAYI//10   Buna mod alma işlemi denir. Amacı bir sayıyı bir başka sayıya bölerek kalanı hesaplar. Burada SAYI içindeki değer 10'a bölünerek kalan ONDALIK değişkenine atılıyor. 236 sayısını 10 a bölersen 23,6 olur. Pic de  bu işlem aslında 23 değerini verir. Ama // işlemi sana 6 sayısını verecektir. Böylece en sağdaki displayde gösterilecek sayıyı elde ettin demektir.
Şimdi TAM=SAYI/10 şeklinde işlem yaparak 23 sayısını elde edersin. Bunuda Birler=TAM DIG 0  ve Onlar=TAM Dig 1 şeklinde her bir hanenin değerini alırsın. Bu işlemler sonucunda Onlar=2 olur, Birler=3 olur, Ondalık=6 olur.
Gerisinde bunları displeylere vermek kalıyorki artık onu anlatmıyacağım.
Şimdi gelelim hesap işine.
DS18B20 normalde 12 bit sıcaklık okur. Okunan ham değer birim ham değer başına sıcaklık değerini veren 0,0625 sayısı çarpılırsa sonucu 12 bit sıcaklık değeri olarak hesaplayabiliyoruz. Bir sayının 0,0625 ile çarpılması demek o sayının 16ya bölünmesi ile eşdeğerdir. Çünki 1/16=0,0625 dir.  Bu durmda bize sonucun 10 ile çarpılmış hali lazım olduğu için sayıyı önce 10 ile çarpar sonra 16 ya bölersem istediğimi elde etmiş olurum.
Bir örnek yapalım. 10,125 derecelik sıcaklığın ham değeri 162 dir.  Şimdi sensörden 162 okuduğumuz zaman bunu sıcaklık olarak hesap edelim.
SIC=HAM*10/16=162*10/16 =1620/16=101,25 olarak hesaplanır ancak pic de bu sonuç bize 101 olarak gelir.
Bu durumda sıcaklık 10,1 şeklinde algılanacaktır.

Aynı hesabı başka şekilde de yapmak mümkün. Mademki ham değer ile 0,0625 sayısını çarpacağız veya 10 la çarpılmış hali için 0,0625 değilde 0,625 ile çarpacağımızı varsayarsak;
0,625 x256=160 değerini bize verir. Bu durumda okunan ham değeri */ işlemi kullanarak 160 ile çarpılır ise sonuç yine bize 101 olarak gelecektir.A */B şeklindeki  işlem açık matematikte şöyle yapılır. A * B/256. Çünki */ işlem sonucu bize 256 ya bölünmüş olarak verir. Bu durumda formülü şöyle kurabilirsin. ,
SIC=HAM */160
ONDA=SIC//10
TAM=SIV/10

Hepsi bu kadar.
Ete

fahrettink

#3
ETE hocam,

Verdiğiniz bilgiler sayesinde işin mantığını çözdüğümü düşünüyorum.

Devre ve yazılım isis'te çalıştı. Sadece bir kaç soru işaretim kaldı.

1- Devre İsis'te ilk çalıştığında yaklaşık 1 sn. kadar "850" rakamını gösteriyor ve hemen arkasından doğru dereceyi göstermeye başlıyor. Sonrasında da uzun aralıklarda göstergelerde bir titreme olup "959" rakamını gösteriyor. (Sadece İsis'i step olarak çalıştırdığımda görülebiliyor.) Bu simülasyondan kaynaklanan bir şey olabilir mi? İsis'in hata mesajlarında ısı sensörü için RAM COMMAND UNSUPPORTED mesajını görüyorum.

2- Tam sayıyı birler ve onlara ayırmak için verdiğiniz örnekte "Birler=TAM DIG 0  ve Onlar=TAM Dig 1" şeklinde olur yazmıştınız. Bende ise doğru sonucu alabilmek için birler hanesi "DIG 2" ve onlar hanesi "DIG 1" yazmam gerekti. Nerede hata yapıyor olabilirim?

Hocam İsis ve hex dosyası ektedir. Müsait olduğunuz zaman bakabilirseniz sevinirim.
Yazdığım kodlarla ilgili bir mantık hatası ya da çok kısa yazılabilecek bir şeyi uzun yoldan yaptığım şeklinde bir durum varsa bunları değerli yorumlarınızla düzeltmek isterim.

Sonrasında devreye bir digit daha ekleyip "+" ve "-" olayınıda sisteme dahil ederek, üye projelerinde yayınlamak istiyorum.

İlgi ve alakanıza çok teşekkür ederim.

fahrettink
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

ete

Bas dosyasını vermemişsin. Yalnızca Hex dosyası ile bir yapmam mümkün değildi.
O nedenle önceki verdiğin program üzerinden biraz değişiklik yapıp devre şemasınıda biraz sadeleştirdim.
Buhali ile kusursuz çalışmaktadır.

Ete

fahrettink

Hocam,

Verdiğiniz şemayı açıp yine verdiğiniz hex ile çalıştırdım.

Ama sadece ilk digitte rakam var. Sağdaki iki digitte hiç bir şey yok. Benim İsis'ten mi kaynaklanıyor acaba? (7.10)

Ekte benim yazdığım pbp dosyasını da ekledim hocam.
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

ete

#6
Şema nın Çalışır halini kayıt etmemiş olabilirim.  Bakarım. Ama güzel çalışıyordu.
Ete

Yolladığım Rar dosyası içinde Fahri_ete diye kayıt ettiğim bir isis dosyası var ama onu kullanma diğerini kullan.
İsimler karışmış anlaşılan.


fahrettink

Teşekkürler, yazdığınız kod bloğu çok daha kısa tek çıkıştan tüm digitlere veri gidiyor.

Üzerinde düşünüp tam olarak anlamaya çalışacağım.

Bu arada değişkenlerin yanına verdiğiniz adresleri sadece isis'te takip için mi kullanmamız gerekiyor yoksa devreyi gerçekten kurduğumuzda da olması gerekir mi hocam?

Tekrar teşekkürler...
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

ete

verilen değerler isisde onları izlemek içindir.

Ete

fatih88

program dogru ama isis cizimi yanlis oldu galiba bir bak
bilgi paylaştıkça çoğalır!!

www.fayelektronik.com

fahrettink

#10
Alıntı yapılan: fatih88 - 06 Mayıs 2012, 14:12:42
program dogru ama isis cizimi yanlis oldu galiba bir bak

Ete hoca düzeltmesini yayınlamıştı, ilginize teşekkürler.
Alıntı Yap
Yolladığım Rar dosyası içinde Fahri_ete diye kayıt ettiğim bir isis dosyası var ama onu kullanma diğerini kullan.
İsimler karışmış anlaşılan.
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

fahrettink

Hocam,

Benim programımda sensörün meşgul olma durumuna karşı bir if döngüsü vardı.

Siz bunu sensör okumayı programın en başına alıp altına "pause 200" koyarak çözmüşsünüz ve gayet güzel çalışıyor.

Bu durumda ds18b20 için meşgul olma süresi aşımında pause 200 yapmak kesinlikle yeterlidir ve daha fazla beklemeye gerek yok diyebilir miyiz?

Bu iletiyi yazarken bir tarafta da datasheet açıktı, oradan anladığım kadarıyla okuma süresi max 60 ms görünüyor, bu da demekki pause 200 yeterli :)

Umarım datasheet i doğru anlamışımdır hocam.
"Dahilik %1 ilham, %99 çalışmanın eseridir." Thomas Alva EDISON

ete

12 bit okumada DS18B20 sensörünün sıcaklığı alma süresi 750 ms dir. Bu süre aslında Oku emrini verdikten sonra sıcaklığın alınması için beklenmesi gereken süredir. Program ilk çalıştığında Basla etiketinden önce sıcaklığı oku emrini verip (OWOUT SENSOR,1,[$CC,$44]) sonra 200 ms bekletiyorum. Ayrıca basla etiketinden sonrada bir 600 ms lik bekleme koydum.
Sonradan yer alan komut gecikmelerinide hesaba katarak bekleme süresinin yaklaşık 750 ms olacağını hesapladım. Tahmini bir değerdir bu. Ama tuttu ve sorunsuz okuma yapılabiliyor.
Dikkat edersen  GOSUB YAZ etiketindenönce yeniden bir sıcaklığı okuma emri veriyorum. Diğer işlerle birlikte +600 ms lik gecikme ile süreleri tutturduğum kanaatindeyimki okumalar kesintisiz , titremesiz yapılabiliyor.

Ete

BİDİL

Akadaşlar Merhaba;

18f4550 ile thermometre yapmaya çalışlıyorum, LM35 ile başladım ama bir hayli tutarsızlıklar yaşadım. Bu nedenle DS18B20 ile deneme yapmaya çalışıyorum. Deney yaptığım ortamda iki üç adet thermometre var ortalama değerleri 22-23 derecelerde iken DS18B20 28 dereceleri gösteriyor. Hesaplamada bir yanlışlıkmı yapıyorum diye düşündüm ve ekrana ham değeri yazdırdım sonuç 45 değeri idi.
Formüle göre 45*10/16=28 dereceyi tutuyor yani formül doğru ama diğer cihazlarla olan 5 derecelik fark neden kaynaklanabilir?
PORTA=0:portb=0:PORTD=0
TRISB=%000000000
TRISD=0   
TRISA=%111110110
DEFINE OSC 4
asm                             
    __CONFIG _CONFIG1L, _PLLDIV_1_1L & _CPUDIV_OSC1_PLL2_1L ; 4MHZ
    __CONFIG _CONFIG1H, _FOSC_XT_XT_1H &_IESO_OFF_1H;4 MHZ
    __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L &  _VREGEN_OFF_2L
    __CONFIG _CONFIG2H, _WDT_OFF_2H   
    __CONFIG _CONFIG3H, _MCLRE_OFF_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_OFF_3H   
    __CONFIG _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L &_XINST_OFF_4L  & _DEBUG_OFF_4L   
    __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L 
    __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
    __CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H  & _WRTD_OFF_6H
    __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
endasm
'*******************************OSC AYARLARI************************************
ADCON1 = %00001111 '7. bit 1 yapıldı 10 bit sonuç almak için.
CMCON=7
'----------------------------------------------------------------------------
BILGI    VAR WORD
ISI      VAR BYTE     
ARA      VAR WORD       
ISARET   VAR BYTE       
SAYI  VAR BYTE 
X VAR  BYTE

SYMBOL  DTA=PortB.0
SYMBOL  CLK=PORTB.1
SYMBOL  SENSOR=PORTA.0


pause 200
OWOUT SENSOR,1,[$CC,$44]
pause 200
'-----------------------------------------------------------------
BASLA: 'Dongüye gir.
pause 600
DEVAM:
OWOUT SENSOR,1,[$CC,$BE] 'Sensöre okuduğu değeri göndermesini söyle.
OWIN SENSOR,2,[BILGI.LOWBYTE,BILGI.HIGHBYTE] 'Gelen 16 bitlik bilgiyi al.
ISI=BILGI/16 '12 bit hassasiyet kullandığımız için her değer 0.0625 santigrat dereceye denk geliyor.


GOSUB YAZ
OWOUT SENSOR,1,[$CC,$44] 'Sensöre sıcaklığı okumasını söyle.
pause 200
GOTO BASLA 'BASLA etiketine dön

YAZ:

X= (ISI DIG 3):GOSUB AL:SHIFTOUT DTA,CLK,1,[SAYI]HIGH PORTB.2:PAUSEUS 5:LOW PORTB.2
X= (ISI DIG 2):GOSUB AL:SHIFTOUT  DTA,CLK,1,[SAYI]:HIGH PORTB.3:PAUSEUS 5:LOW PORTB.3
X=10:GOSUB AL:SHIFTOUT  DTA,CLK,1,[SAYI]:HIGH PORTB.4:PAUSEUS 5:LOW PORTB.4
:X=11:GOSUB AL:SHIFTOUT  DTA,CLK,1,[SAYI]:HIGH PORTB.5:PAUSEUS 5:LOW PORTB.5 
RETURN

AL:LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57],SAYI :RETURN

END

ete

Sensör direk karta monte edilmiş ise oradaki malzemelerin ısısından etkilendiğini söylemek mümkün. Z,ra bu sensörü yüzlerce defa kullandım ve ne zaman karta direk monte ettim ise biraz yüksek değerler verdi. aynı şekilde tamamen kapalı bir kutunun içine de koyarsanız benzer sonuçlar veriyor. Bence sensör bu konuda haklı. Kaplı ortamda bulunan yada kartın üzerine monte edilmiş sensör etrafında oluşan gizli ısıdan etkilenerek aslında doğru sıcaklığı göstermesine rağmen dışarıdan bakanlara bu sıcaklık fazla gelmektedir. Yaptığım bütün projelerde bu sensörü 10-20cm lik bir kablo ile mutlaka kutu dışna taşıyorum artık ve sensör bu durumda kusursuz çalışıyor. Bunun yanı sıra etrafta bulunan diğer sensörlerin çoğu termistör kaynaklı sensörler. Ne olursa olsun onların gösterdiği bence çok doğru değil. Hatta birde şunu söylemek mümkün aynı oda içinde yer alan bütün sensörlerin doğru sıcaklığı göstermesi için hepsinin aynı yükseklikte ve aynı havalndırma olanaklarına sahip olmaları gerekir. Aksi halde aynı cins sensör bile kullansanız aralarında fark olduğunu görürsünüz. Titizliğinize bağlı olarak bu fark 0,1 dereceden 1,5-2 derecelere kadar çıkabiliyor. Sıcaklık ölçmek gerçekten dikkat edilmesi gereken bir husustur. Sensörün mutlaka serbest bir şekilde kapalı ortamda olmayacak şekilde yerleştirilmesi gerekir.

Ete

Powered by EzPortal