ONE-WİRE ( tek hatlı iletişim) hakkında

Başlatan Mucit23, 12 Ağustos 2010, 14:16:38

Mucit23

Anladım hocam tüm sensörlerin okunmasını beklemiyorsunuz. Diyelim 3 sensör varsa 1. yi okuyup ardından hemen saati okuyorsunuz ve ekrana gösteriyorsunuz. Sonra ikinciyi ve saati okuyup ekrana gösteriyoruz. Sonrada 3. yük okuyup saat okuma işlemi bittikten sonra döngü bitiyor. Program başa dönüyor.
Çok mantıklı güzel bir fikir.;)

CLR

Alıntı yapılan: M_B - 21 Aralık 2010, 22:37:26
Evet hocam orası oyle ama programda bır takım taklalar atarak saatın ekranda duzgun calısmasını gorebılırsınız. ( Saniye hareket kısmı )

Benim yaptıgım projenin ana bolumu
while(1)
			{
	ana:
	Tarihgoster();
	Saatgoster();
		

	if(OK==1)  // menuye girme kismi
				{
				Menu();
				goto menu_don;
				}
		
	Saatgoster();
						
				SicaklikOku(0x00);
	Saatgoster();
		 		nokia_gotoxy(2,3);
				nokia_printchar("Ic Isi");
				nokia_gotoxy(43,3);
				nokia_printchar(address);
				nokia_gotoxy(62,3);
				Derece();
		if(OK==1)  // menuye girme kismi
				{ 
				Menu();
				goto menu_don;
				}
	Saatgoster();
				SicaklikOku(0x08);
										Saatgoster();
				nokia_gotoxy(2,4);
				nokia_printchar("DisIsi");
				nokia_gotoxy(43,4);
				nokia_printchar(address);
				nokia_gotoxy(62,4);
				Derece();
		if(OK==1)  // menuye girme kismi
				{
				Menu();
				goto menu_don;
				}
	Saatgoster();
				SicaklikOku(0x10);
										Saatgoster();
				nokia_gotoxy(2,5);
				nokia_printchar("Motor");
				nokia_gotoxy(43,5);
				nokia_printchar(address);
				nokia_gotoxy(62,5);
				Derece();
		if(OK==1)  // menuye girme kismi
				{
				Menu();
				goto menu_don;
				}
				Motor_isi_Kontrol();			
			}

Hocam gordugunuz gibi ana dongu ıcınde sıcaklıkları okuduktan sonra hemen arkasında saat fonksıyonunu cagırıp ekrana yansıtıyorum
yoksa 3 sensorun okunmasını bekledıkten sonra saatı okuyup ekrana verirsem saatın saniyesinde hatalar meydana geliyor.( gecikmeler oluyor)




Merhaba,

DS18b20 okunurken 12bit okumada 750ms veya 9bitte 100ms beklemeye gerek yok, istediğin zaman içeriğini okuyabilirsin ama sadece 12bit ise 750ms'de, 9bit ise 100ms'de bir registerlerini günceller yani beklemeye gerek yok.
Dolayısıyla sizin bahsettiğiniz saniye hataları olmaz.
Knowledge and Experience are Power

seferuzan

Alıntı yapılan: mucit23 - 12 Ağustos 2010, 14:16:38
merhaba arkadaşlar şu ONE-WİRE sistemi hakkında pic basicle yapılmış örnek kod veya uygulama arıyorum Sistemin çalışma mantığını anlamam için bu kodlara ihtiyacım var Elinizde varsa paylaşırsanız çok sevinirim.
İyi günler

pic basic ile yok ama jalturk kutuphanei var belki mantığı anlamanda işine yarar.

-- ------------------------------------------------------------------
-- DS18B20(DALLAS 1WIRE) KÜTÜPHANESİ  4k7 PULL-UP DİRENCİ KULLANIN
-- ------------------------------------------------------------------
VAR VOLATILE BIT TekTel IS Pin_A3
VAR VOLATILE BIT TekTel_Yon IS Pin_A3_Yon
INCLUDE TEKTEL
-- --------------------------------------------------------------------
--  GNU GPL freeware  (Bedava, ticari uygulamalar icin de kullanlabilir.)
--  Copyright (C) 2008 JALTURK GELİŞTİRME EKİBİ JALTURK@GMAIL.COM
-----------------------------------------------------------------------

-- ------------------------------------------------------------------
-- KÜTÜPHANEDEKİ PROSEDÜRLER VE FONKSİYONLAR
-- ------------------------------------------------------------------
--PROCEDURE COZUNURLUK_DEGISTIR(BYTE IN COZUNURLUK) IS
--  DS1820 çözünürlüğünü değiştirir.
--PROCEDURE DS18B20_Oku( BYTE OUT Sicaklik, BIT OUT arti_eksi, WORD OUT Onda)
--  DS1820 entegresini okur.
--PROCEDURE DS18B20_Yaz (BYTE IN MSB , BYTE IN LSB ) IS

-- ------------------------------------------------------------------
-- ÖRNEK KULLANIM
-- ------------------------------------------------------------------
-- VAR VOLATILE BIT TekTel IS Pin_D0
-- VAR VOLATILE BIT TekTel_Yon IS Pin_D0_Yon
-- INCLUDE DS18B20
-- VAR BYTE DEGER, DEGER2
-- DS1820_Oku(DEGER,DEGER2)
-- ------------------------------------------------------------------

-- DS18B20 FONKSIYON KOMUTLARI
CONST BYTE DS18B20_Sicaklik_Cevir     = 0x44
CONST BYTE DS18B20_Scratchpad_Yaz     = 0x4E
CONST BYTE DS18B20_Scratchpad_Oku     = 0xBE
const BYTE DS18B20_Scratchpad_Kopyala = 0x48
const byte DS18B20_Eeprom_Cagir       = 0xB8
CONST BYTE DS18B20_GucKaynagi_oku     = 0xB4

--Çözünürlük ayar byteları
    --Configuration Registeri(ScratchPad Memory byte4)
    --R1(6.bit) ve R0(5.Bit) ile ayarlanıyor
CONST BYTE DS18B20_9bit   = 0b_0001_1111
CONST BYTE DS18B20_10bit  = 0b_0011_1111
CONST BYTE DS18B20_11bit  = 0b_0101_1111
CONST BYTE DS18B20_12bit  = 0b_0111_1111


------------------------------------------------------------------------
-- DS18B20 ÇÖZÜNÜRLÜK AYARI
-- KULLANIM:COZUNURLUK_DEGISTIR(10)
------------------------------------------------------------------------
PROCEDURE DS1820_COZUNURLUK_DEGISTIR(BYTE IN COZUNURLUK) IS

VAR BYTE Alarm_Alt=0, Alarm_Ust=0

    IF TekTel_Reset==0 THEN
        Tektel_Yaz(DS_Rom_Atla)
        Tektel_yaz(DS18B20_Scratchpad_Yaz)
        Tektel_yaz(Alarm_Ust)
        Tektel_yaz(Alarm_Alt)
    END IF
    CASE cozunurluk OF
         12 : Tektel_yaz(DS18B20_12bit)
         11 : Tektel_yaz(DS18B20_11bit)
         10 : Tektel_yaz(DS18B20_10bit)
         9  : Tektel_yaz(DS18B20_9bit)
    END CASE
END PROCEDURE
-----------------------------------------------------------------------------

-----------------------------------------------------------------------------
--Bu PROCEDURE DS18B20 yi okur ve tüm değerleri ana programa gönderir.
-----------------------------------------------------------------------------
PROCEDURE DS18B20_Oku( BYTE OUT sicaklik, BIT OUT arti_eksi) IS--, WORD OUT onda) IS

    VAR BYTE alt , ust
;    VAR VOLATILE BIT virgul0 at alt : 0   -- ondalik BIT 0
;    VAR VOLATILE BIT virgul1 at alt : 1   -- ondalik BIT 1
;    VAR VOLATILE BIT virgul2 at alt : 2   -- ondalik BIT 2
;    VAR VOLATILE BIT virgul3 at alt : 3   -- ondalik BIT 3

    VAR VOLATILE BIT tam0 at alt : 4      -- Tam BIT 0
    VAR VOLATILE BIT tam1 at alt : 5      -- Tam BIT 1
    VAR VOLATILE BIT tam2 at alt : 6      -- Tam BIT 2
    VAR VOLATILE BIT tam3 at alt : 7      -- Tam BIT 3
    VAR VOLATILE BIT tam4 at ust : 0      -- Tam BIT 4
    VAR VOLATILE BIT tam5 at ust : 1      -- Tam BIT 5
    VAR VOLATILE BIT tam6 at ust : 2      -- Tam BIT 6
    VAR VOLATILE BIT isaret at ust : 7    -- İşaret için kullanılıyor

    sicaklik =0 -- Sicaklik ve onda değişkenleri sıfırlanıyor
;    onda = 0

    IF (TekTel_Reset==0) THEN         -- Eğer hazır sinyali alınırsa
        Tektel_Yaz(DS_Rom_Atla)    -- ROM OKUMAYI İPTAL ET kkomutu
        Tektel_Yaz(DS18B20_Sicaklik_Cevir) -- Sıcaklığı ölç

        WHILE (tektel_oku==0) LOOP END LOOP -- sıcaklık ölçülene kadar bekle

        IF (TekTel_Reset==0) THEN         -- Eğer hazır sinyali alınırsa
           Tektel_Yaz(DS_Rom_Atla)    -- ROM OKUMAYI İPTAL ET kkomutu)
           Tektel_Yaz(DS18B20_Scratchpad_Oku)--Scratchpad i oku

           alt = Tektel_oku -- sıcaklık alt BYTE ı oku
           ust = Tektel_oku -- sıcaklık üst BYTE ı oku
           arti_eksi = isaret -- işaret i kaydet

           IF tam0 THEN sicaklik = sicaklik+1 END IF-- Sıcaklık değerini hesapla
           IF tam1 THEN sicaklik = sicaklik+2 END IF
           IF tam2 THEN sicaklik = sicaklik+4 END IF
           IF tam3 THEN sicaklik = sicaklik+8 END IF
           IF tam4 THEN sicaklik = sicaklik+16 END IF
           IF tam5 THEN sicaklik = sicaklik+32 END IF
           IF tam6 THEN sicaklik = sicaklik+64 END IF

           IF (arti_eksi==1) THEN--eğer sıcaklık negatif ise
               sicaklik=127-sicaklik -- negatif olarak sıcaklığı hesapla
;               virgul0=!virgul0--onda hesabı için bitleri tersle
;               virgul1=!virgul1
;               virgul2=!virgul2
;               virgul3=!virgul3

           END IF

;           IF virgul0 THEN onda = onda + 62 END IF -- ondalık kısmı hesapla
;           IF virgul1 THEN onda = onda + 125 END IF
;           IF virgul2 THEN onda = onda + 250 END IF
;           IF virgul3 THEN onda = onda + 500 END IF

         END IF
    END IF

END PROCEDURE
-- ------------------------------------------------------------------


-- ------------------------------------------------------------------
-- DS1820 YAZMA KODLARI
-- ------------------------------------------------------------------
PROCEDURE DS18B20_Yaz (BYTE IN MSB , BYTE IN LSB ) IS

    IF TekTel_Reset == 0 THEN
       Tektel_Yaz(DS_Rom_Atla)
       Tektel_Yaz(DS18B20_Sicaklik_Cevir)

       IF TekTel_Reset == 0 THEN
          Tektel_Yaz(DS_Rom_Atla)
          Tektel_Yaz(DS18B20_Scratchpad_Yaz)
          Tektel_Yaz(LSB)
          Tektel_Yaz(MSB)
       END IF

    END IF
END PROCEDURE
-- ------------------------------------------------------------------

Mucit23

#18
Arkadaşlar Wire kakkında bir sorunum kalmadı. Mantığını anladım. Bu yönden herhangi bir sorunum yok şükür. Ama şöyle bir sorunum var. Kou kirliliği açısından yeni bir başık açmak istemedim buraya yazayım dedim. Bu daha çok DS18b20 okumayla ilgili . İlk okumada ds18b20 herzaman sıcaklık olarak 85 değerini veriyor.Üstelik çok geç okuma yapıyor. Sıcaklık okuma kodları ETE hocamızın kodları. ETE hocamız bunu bir zamanlar açıklamıştı. Çok araştırdım. Bir konu altında yine bu sorun dile gelmişti. Fakat bununla ilgili öylesine çok konu varki bulamadım malesef. Bu konuda bilgisi olan arkadaşlar yardımcı olursa sevinirim.

Mucit23

Arkadaşlar bu konuda fikri olan yokmu. Ds18b20 den en pürüzsüz şekilde ölçüm almak için hangi nelr yapılması gerekir. İlk okumada neden sıcaklığı 850(85.0) gibi bir değerlerde gösteriyor. Bunu önlemenin yolları varmıdır.

X-Fi

sensör yanılmıyorsam 1 sn de bir okuma yapıyor son okuma değerini size gönderdiği için bekleme oluşuyor ilk okuduğu değer ise daha ölçüm yapmadığı için yanlış değer oluyor bence bir 1 sn beklemeden sonra sensörü okuyun ilk değeri atlayın.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

JKramer

İlk iki byte'da (sıcaklık değerlerinin tutulduğu) başlangıç değeri varsayılan olarak 85 derecedir. Bu yüzden hesaplamalarınızda ilk okuduğunuz değeri dikkate almayacaksınız. Geç okuma derken bunu mu kastettiniz bilmiyorum ama okuma süresi 12 bit'de bir saniyeye yakındı yanlış hatırlamıyorsam. Normal yani :).

Mucit23

Şöyle bişey deniyeyim. İlk başta bekleme yerine ard arda 2-3 defa okuma işlemi yapayım. Zaten okuma işlemi oldukça uzun sürüyor. Bir iki defa daha okuma yaptıktan sonra son aldığım değeri ekranda gösteririm. Bu bekleme yerine geçer. Devre multiplex çalışıyor 3 adet display ile ekranda gösteriyoru. Display sayısı az olmasına rağmen okuma yapıldığı zaman ekanda titremeler olabiliyor. Gerçi simülasyon okadar gerçekçi değil. PCB sini çizip gerçekte çalıştırdığım zaman ozamanki gözlemlerimi önemli benim için.

ete

Bu sorun ilk okuma belleğinin boş olmasından kaynaklanıyor. Bunu önlemenin bir çaresi var. Sırası ile açıklıyorum.

Öncelikle bir alt program yazın aşağıdaki şekilde;

SENSORYAZ:          
'          OWOUT   Comm_Pin, 1, [$CC,$4E, $FF, $FF, $1F]
'          OWOUT   Comm_Pin, 1, [$CC,$48]
          OWOUT   Comm_Pin, 1, [$CC,$B8]
'          OWOUT   Comm_Pin, 1, [$CC,$BE]
          return


Sonra programın başına ve BASLA satırından evvelki kısıma aşağıdaki kodları ilave edin;
GOSUB SENSORYAZ   
GOSUB SENSOROKU


Hepsi bu kadar. Bir şeyi daha ifade edeyim. Sensoryaz alt programında birden fazla komut satırı mevcut. Komut numaralarından ne işe yaradıklarını data sheete bakarak anlayabilirsiniz. Ancak yalnızca açık bıraktığım komut bile 85 derece sorununu çözmektedir.
İsteyenler tamamını açıkta bırakabilir.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Mucit23

Hocam sonuç gerçekten etkileyici. Dediğiniz eklemeleri yaptım. Başta hiç bekleme yapmadan bile direk sıcaklığı göseriyor. Şimdi epeyi düzelme oldu.
Sorunum çözümüştür arkadaşlar. Bana yardımcı olan herkese teşekkürler.

Bu arada tüm İslam aleminin Mevlit kandilini kutlarım.. :)

RcALTIN

#25
Ben kendi oluşturduğum bir zamanlama metodunu kullanarak bu tür işleri delay kullanmadan düzene koyuyorum öneririm:
//Every 50ms works this method
void Zamanlama()
{
   //make delay for trigging, default: 10 for 500ms
   if(z_tetik && (++z_tetik_say > 10))
   {
      output_low(TETIK_PIN);
      z_tetik = z_tetik_say = 0;
   }
   //---
   //make delay for pressing new ibutton device, default: 60 for 3sec
   if(z_ibutton && (++z_ibutton_say > 60))
   {
      z_ibutton = z_ibutton_say = 0;
   }
   //---
   //make delay for shown announce string, default: 100 for 5sec
   if(z_duyuru && (++z_duyuru_say > 200))
   {
      z_duyuru = z_duyuru_say = 0;  
   }
   //---
   //make delay for shown last entered person data, default: 200 for 10sec
   if(z_son_giris && (++z_son_giris_say > 100))
   {
      z_son_giris = z_son_giris_say = 0;  
   }
   //---
   //make delay for auto version controls, default: 1200 for 1min
   if(z_skontrol && (++z_skontrol_say > 600))
   {
      z_skontrol = z_skontrol_say = 0; 
   }
   
}

açıklamak gerekirse:
yukarıdaki metod timer kesmesiyle her 50ms de bir kez çağırılıyor, mesela z_tetik = 1 yapılmışsa, (500ms lik bir değer belirtmişim) bir süre sonra otomatik olarak 0 lanıyor, ben bunu ana döngümde kontrol ediyorum ve delay kullanıp programı kilitlemektense o sürede programın işleyişini sağlayabiliyorum.

Şimdi konumuza nasıl uyarlarız derseniz, şöyle olur: int1 z_sicaklik ve int8 z_sicaklik_say değişkenlerimizi tanımladıktan sonra...
.
.
.
//TODO: User Code
while(TRUE)
{
   if(!z_sicaklik) //zamanlama değişkeni 0'sa işle:
   {
       //yeni okuma başlat
       z_sicaklik = 1; // değişkeni 1 yap
   }
}
}

void Zamanlama()
{
   //make delay for ds18b20 read, default: 20 for 1sec
   if(z_sicaklik && (++z_sicaklik_say > 20))
   {
      //burada, sıcaklık sonucunu al  ve ekrana yaz
      z_sicaklik = z_sicaklik_say = 0; // değişkenleri sıfırla
   }
}


KİMSEYİ ENGELLEDİĞİM YOK, ÖZEL İLETİ DEVRE DIŞI !

Mucit23

@Rc_ALTIN
Hocam öneriniz için teşekkürler.
Kendi devremde 3 adet display ile multiplex olarak sıcaklık bilgisini ekranda gösteriyorum. Display tarama işini kesme ile yapıyorum. Bu haliyle simülasyonda gayet iyi çalışıyor. Titreme yok yani simülasyonda olmuyor. Gerçektede olacağını sanmıyorum açıkçası. Kesme içerisinde yukarıda örnek olarak verdiğiniz işlemleri koysam diğer işlemlerde aksaklıklar çıkmazmı. Özellikle display tarama işinde.

RcALTIN

Alıntı yapılan: mucit23 - 14 Şubat 2011, 17:53:16
@Rc_ALTIN
Hocam öneriniz için teşekkürler.
Kendi devremde 3 adet display ile multiplex olarak sıcaklık bilgisini ekranda gösteriyorum. Display tarama işini kesme ile yapıyorum. Bu haliyle simülasyonda gayet iyi çalışıyor. Titreme yok yani simülasyonda olmuyor. Gerçektede olacağını sanmıyorum açıkçası. Kesme içerisinde yukarıda örnek olarak verdiğiniz işlemleri koysam diğer işlemlerde aksaklıklar çıkmazmı. Özellikle display tarama işinde.

Benim projemde bir çok işlemin aynı anda beklemesi v.s söz konusu olunca çözümü bu şekilde bulmuştum; burada da fikir vermesi açısından ekledim, işlem için timer ayırabiliyorsanız ve bu şekilde çalıştığını belirtiyorsanız değiştirmeye gerek yok bence... Söz konusu display tarama olunca bir aksaklık olur mu kestiremiyorum, mesajı yazarken de lcd kullanıldığını düşünerek yazmıştım.
KİMSEYİ ENGELLEDİĞİM YOK, ÖZEL İLETİ DEVRE DIŞI !

Mucit23

evet hocam tarama olunca süreler biraz kritik olabiliyor bazen. Yinede ilginiz için çok teşekkür ederim.

Mucit23

Arkadaşlar devremi yaptım bitirdim. Şu haliyle çok iyi çalışıyor. Ekranda titremede yok belki sadece çok dikkatli birisi bakarsa ekranda titreme olduğunu farkedebilir. Herşey iyi güzelde sensör hassasiyetiyle ilgili ufak bir sorunum var. Programda Set değerini 0.1 derece hassasiyetinde ayarlanacak şekilde yaptım. Fakat sensör 0,5 derece hassasiyetinde çalışıyor. Değerler hep 25, 25.5, 30, 30.5 gibi değerlerde değişiyor. 5 ve 5 in katları halinde. Böyleolunca haliyle set değerinin 0.1 erece hassasiyetinde olması mantıksız kalıyor.
Ds18B20 ölçüm süresini arttırılarak okumanın hassasiyetin 0.0625 (0.1) derece gibi hassasiyete yükseltilebileceğini duymuştum. Fakat bunun için okuma kısmına ne gibi eklemeler yapmam gerektğini bilmiyorum. Bu konuda yardımlarınızı bekliyorum