Picproje Elektronik Sitesi

MİKRODENETLEYİCİLER => Microchip PIC => Konuyu başlatan: gtekdemir - 14 Ekim 2009, 23:40:58

Başlık: 1 wire & 4 tane DS18B20 ile sıcaklık okuma
Gönderen: gtekdemir - 14 Ekim 2009, 23:40:58
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 (http://rapidshare.com/files/293057619/1_wire.rar.html)

(http://img240.imageshack.us/img240/9840/coksens.th.png) (http://img240.imageshack.us/i/coksens.png/)

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
Başlık: 1 wire & 4 tane DS18B20 ile sıcaklık okuma
Gönderen: Maxim - 15 Ekim 2009, 00:42:22
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ü ?
Başlık: 1 wire & 4 tane DS18B20 ile sıcaklık okuma
Gönderen: gtekdemir - 15 Ekim 2009, 01:07:47
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.