1 wire & 4 tane DS18B20 ile sıcaklık okuma

Başlatan gtekdemir, 14 Ekim 2009, 23:40:58

gtekdemir

Projemde 1 wire protokolünü kullanan 4 adet DS18B20 sıcaklık sensöründen gelen sıcaklık bilgileri 2*16 ekranda gösterilmekte. Program ilk çalıştığında menü tuşuna basıldıktan sonra  Portd.2 portuna bağlanan 1 wire cihazın ROM kodunu okumakta ve ekranda göstermektedir. 1 wire protokolünde bilindiği gibi cihazların ROM kodlarına göre veri alışverişi yapılmakta. Portd.2 portuna bağlanan yeni cihazın ROM kodunu okuduktan sonra 1wire hattına (portd.0) yeni cihazlar eklenebilir, tabiiki program içindeki gerekli değişiklikler yapıldıktan sonra eklenen yeni cihazlar kullanılabir. Eğer yeni cihaz eklemek istemiyorsanız Rom kodu okuma kısmını iptal edebilirsiniz. Umarım faydalı bir çalışma olmuştur. Proton kaynak kodu ve proteus dosyası linkte



Edit:Programdaki Xtal tanımlama satırının altındaki PORTD.1=1 ifadesi TRISD.1=1 şeklinde düzeltilecek


'OREAD ve OWRITE komutlarındaki mode ifadesinin ne anlama geldiği(mode 0-7 seçilebilir)
'--------------------------------------------------------------
'Mode Bit Number	 Effect
'       0	          1 = send reset pulse before data
'       1	          1 = send reset pulse after data
'       2	          0 = byte-sized data, 1 = bit-sized data
'--------------------------------------------------------------
'Mode Bit Number	 Decimal Value	    Effect
'2 	   1	 0
'--------------        --------         ------------------------
'0	   0	 0	           0	        Byte-sized data, no reset pulse
'0	   0	 1	           1	        Send reset pulse before byte-sized data
'0	   1	 0	           2	        Send reset pulse after byte-sized data
'0	   1	 1	           3	        Send reset pulse before & after byte-sized data
'1	   0	 0	           4	        Bit-sized data, no reset pulse
'1	   0	 1	           5	        Send reset pulse before bit-sized data
'1	   1	 0	           6	        Send reset pulse after bit-sized data
'1	   1	 1	           7	        Send reset pulse before & after bit-sized data
'----------------------------------------------------------------

Device 16F877A
XTAL 4
PORTD.1=1                   'portd.1 giriş

Declare LCD_DTPIN PORTB.4	'DATA girişi PORTB'nin 4. ucundan başlayacak
Declare LCD_ENPIN PORTB.3	'LCD'nin Enable ucu
Declare LCD_RSPIN PORTB.2	'LCD'nin Register Select ucu
Declare LCD_INTERFACE 4	    'LCD veri yolu 4 bit olacak
Declare LCD_LINES 2		    'LCD 2 satırdan oluşuyor
Cls					        'Ekranı temizler ve 30 ms gecikme sağlar

Symbol termdata = PORTD.0   'portd.0 1-wire data hattı
Symbol DERECE = 223         ' ' Derece işareti
Dim mesgul As Bit           'sensör okumasını tamamladımı
Dim okunan As Word          'sensörden gelen 16 bitlik veri
Dim hesaplanan As Word      '16 bitlik verinin 'C cinsinden gösterimi için gerekli değişken
Dim isaret As Byte          'sıcaklık - yada +
Dim onda As Word            ' "," den sonrası hesaplama için değişken
Dim a1 As Byte              'hesaplama ve ekran döngüsü için değişken
Dim a2 As Byte              'sensör bekleme döngüsü için değişken
Dim ID[8] As Byte           '8 elamanlı ID dizisi 64-bit ROM kod için

GoSub menu 'Rom kodu okumak için menü etiketine git
Basla:

'Sensör 1 okunuyor 
'-----------------------------------------------------------------------------------------   
Temp_1:
     ' 1.sensör rom kodu $28 $30 $C5 $B8 $00 $00 $00  CRC kodu $8E
    OWrite termdata, 1, [$55,$28,$30,$C5,$B8,$00,$00,$00,$8E,$44]  
        
W1: 
    GoSub bekleyelim
    ORead termdata, 4, [mesgul] ' Çevrim devam ediyormu kontrol ediliyor,
                                ' mode4 ile veri alınıyor
    If mesgul = 0 Then W1' musgul "0" sa hala meşgul, O zaman W1 etiketine git
        
    OWrite termdata, 1,[$55,$28,$30,$C5,$B8,$00,$00,$00,$8E,$BE] '1.sensör okuduğu 
                                                                 'sıcaklık değerini göndersin
        
    ORead termdata, 2, [okunan.LowByte,okunan.HighByte]' iki Byte oku ve iletişimi sonlandır
    a1=1 '1.sensör hesaplama ve ekran için case döngüsü değişkeni
    GoSub hesaplcd 'hesaplama ve ekran etiketine git
   
'Sensör 2 okunuyor    
'-----------------------------------------------------------------------------------------
Temp_2:
         ' 2.sensör rom kodu $28 $31 $C5 $B8 $00 $00 $00  CRC kodu $B9
    OWrite termdata, 1, [$55,$28,$31,$C5,$B8,$00,$00,$00,$B9,$44]
    
W2:
    GoSub bekleyelim
    ORead termdata, 4, [mesgul] ' Çevrim devam ediyormu kontrol ediliyor,
                                ' mode4 ile veri alınıyor
    If mesgul = 0 Then W2' mesgul "0" sa hala meşgul, O zaman W2 etiketine git
    OWrite termdata, 1, [$55,$28,$31,$C5,$B8,$00,$00,$00,$B9,$BE]'2.sensör okuduğu 
                                                                 'sıcaklık değerini göndersin
    ORead termdata, 2, [okunan.LowByte,okunan.HighByte]' iki byte oku ve iletişimi sonlandır 
    a1=2 '2.sensör hesaplama ve ekran için case döngüsü değişkeni
    GoSub hesaplcd 'hesaplama ve ekran etiketine git

'Sensör 3 okunuyor
'-----------------------------------------------------------------------------------------
Temp_3:
         ' 3.sensör rom kodu $28 $32 $C5 $B8 $00 $00 $00  CRC kodu $E0
    OWrite termdata, 1, [$55,$28,$32,$C5,$B8,$00,$00,$00,$E0,$44]
W3: 
    GoSub bekleyelim
    ORead termdata, 4, [mesgul] ' Çevrim devam ediyormu kontrol ediliyor,
                                ' mode4 ile veri alınıyor
    If mesgul = 0 Then W3' musgul "0" sa hala meşgul, O zaman W4 etiketine git
    OWrite termdata, 1,[$55,$28,$32,$C5,$B8,$00,$00,$00,$E0,$BE] '3.sensör okuduğu 
                                                                 'sıcaklık değerini göndersin
        
    ORead termdata, 2, [okunan.LowByte,okunan.HighByte]' iki Byte oku ve iletişimi sonlandır
    a1=3 '3.sensör hesaplama ve ekran için case döngüsü değişkeni
    GoSub hesaplcd 'hesaplama ve ekran etiketine git

'Sensör 4 okunuyor
'-----------------------------------------------------------------------------------------
Temp_4:
         ' 4.sensör rom kodu $28 $33 $C5 $B8 $00 $00 $00  CRC kodu $D7
    OWrite termdata, 1, [$55,$28,$33,$C5,$B8,$00,$00,$00,$D7,$44]
    
W4: 
    GoSub bekleyelim
    ORead termdata, 4, [mesgul] ' Çevrim devam ediyormu kontrol ediliyor,
                                ' mode4 ile veri alınıyor
    If mesgul = 0 Then W4' musgul "0" sa hala meşgul, O zaman W4 etiketine git
    OWrite termdata, 1,[$55,$28,$33,$C5,$B8,$00,$00,$00,$D7,$BE] '4.sensör okuduğu 
                                                                 'sıcaklık değerini göndersin
        
    ORead termdata, 2, [okunan.LowByte,okunan.HighByte]' iki Byte oku ve iletişimi sonlandır
    a1=4 '4.sensör hesaplama ve ekran için case döngüsü değişkeni
    GoSub hesaplcd 'hesaplama ve ekran etiketine git

GoTo Basla    

'Sıcaklık hesaplama ve ekran
'-------------------------------------------------------------------------
hesaplcd:

    If okunan.15=1 Then ' o zaman sıcaklık 0 ın altndadır  
        isaret="-"      ' Sıcaklık (-) hesaplanıyor
        hesaplanan=($FFFF-okunan+1)
        hesaplanan=hesaplanan/16
        onda = (okunan.LowByte & %00001111)
        onda = %10000 - onda
        onda = (onda * 625)
        onda = onda / 1000 'ondalık kısmında tek hane olması için
    Else     
        isaret="+"      'Sıcaklık (+) hesaplanıyor
        hesaplanan=okunan/16
        onda = (okunan.LowByte & %00001111)
        onda = (onda * 625)
        onda = onda / 1000 'ondalık kısmında tek hane olması için
    EndIf  

'a1 değişkenine göre sıcaklık değeri ekrana basılıyor
'-----------------------------------------------------------------------------
    Select a1
    
          Case 1                 ' a1 değişkeni değeri 1 mi ?
            Print At 1,1,isaret,DEC3 hesaplanan,".",DEC1 onda,DERECE      '1.sensör 1.satır 1.sütun
           
          Case 2                 ' a1 değişkeni değeri 2 mi ?
            Print At 1,9,isaret,DEC3 hesaplanan,".",DEC1 onda,DERECE,"C" '2.sensör 1.satır 9.sütun
        
          Case 3                 'a1 değişkeni değeri 3 mü ?
            Print At 2,1,isaret,DEC3 hesaplanan,".",DEC1 onda,DERECE     '3.sensör 2.satır 1.sütun
            
          Case 4                 'a1 değişkeni değeri 4 mü ?
            Print At 2,9,isaret,DEC3 hesaplanan,".",DEC1 onda,DERECE,"C" '4.sensör 2.satır 9.sütun
           Break
    EndSelect
Return   'döngü bitti geri dön

'Sensörlerin daha sağlıklı okuma yapması için bekleme kısmı
'-----------------------------------------------------------------------
bekleyelim:
    For a2=0 To 255 ' ~765ms bekleme süresi
        DelayMS 3
    Next: a2=0
Return 

'Cihaz ROM kodu okuma menüsü
'------------------------------------------------------------------------
menu:
If PORTD.1=1 Then    'menü tuşuna basılmadığı sürece döngüde
    Print At 1,1,"4xDS18B20 1-wire"
    Print At 2,1,"ROM; MENU'ye bas"    'Cihaz ROM kodu için menü tuşuna bas
    GoTo menu
EndIf
While PORTD.1=0:Wend 'menü tuşu bırakılana kadar döngüde
Cls   
Symbol rom = PORTD.2 'ROM kodu okunacak sensör PORTD.2 'ye bağlanacak

ROMoku:
If PORTD.1=1 Then        'menü tuşuna basılmadığı sürece döngüde
    OWrite rom, 1, [$33] 'ROM komutu gönderiliyor 
    DelayMS 100:DelayMS 100:DelayMS 100:DelayMS 100:DelayMS 100 '500ms gecikme
    ORead rom, 0, [Str ID\8]  ' Cihaz ID'si 8bit dizi olarak alınıyor
    Print At 1,1,"Fmly=",HEX2 ID[0],"h"," CRC=",HEX2 ID[7],"h"  'Aile kodu(28h,22h sıcaklık sensörü)
                                                                've CRC 1. satırda
    Print At 2,1,"SN=",HEX2 ID[1],HEX2 ID[2],_      'serino alt satırdan devam 
    HEX2 ID[3],HEX2 ID[4],HEX2 ID[5],HEX2 ID[6],"h" 'serino 2.satırda gösteriliyor
    GoTo ROMoku
EndIf : While PORTD.1=0:Wend 'Tekrardan Menü tuşuna basılıp-çekilerek rom okuma bitirilir
Cls 
Return

End 'program sonu

Maxim

bu id numarasını başka bir uçtan okumak zorundamıyız ?

zaten tek kablo üzerinden bağlı olan hattan, 4 tane sensor ilk açılışta bir kere okunup her birinin id numarası eeproma kayıt edilse otomatik ?
mümkünmü ?

gtekdemir

Tabiiki mümkün, kod üzerinde biraz daha çalışmak gerek sadece. Hattaki cihazları arama ve bulunan cihaz ID 'lerini eeproma yazıp/okuyacak kod satırlarını eklemek gerekiyor. Şimdilik ihtiyaç duymadığım için programı bu haliyle bıraktım, ilerleyen zamanlarda üstünde çalışabilirim.