DS18B20'de beklemeden ölçüm alma

Başlatan Mucit23, 22 Temmuz 2014, 17:43:24

Mucit23

kuru bir döngü içerisinde DS18B20'den sıcaklık okuduğumuzu varsayalım. Normalde mcu DS18B20'ye sıcaklık dönüşümü için start emrini verir ve dönüşümün bitmesini bekler. Bu süre 750ms civarı biliyoruz.
Aşağıdaki okuma rutininde bekleme yapılıyor.

float ds1820_read() 
{ 
 int8 busy=0, temp1, temp2; 
 signed int16 temp3; 
 float result; 

 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0x44); 

 while (busy == 0) 
  busy = onewire_read(); 

 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0xBE); 
 temp1 = onewire_read(); 
 temp2 = onewire_read(); 
 temp3 = make16(temp2, temp1); 
  
 result = (float) temp3 / 16.0;   //Calculation for DS18S20 with 0.1 deg C resolution 

 return(result); 
}

Ben bekemeden sistemin çalışması için yukarıdaki kodları aşağıdaki şekilde düzenledim.
float ds1820_read() 
{ 
 static int1 ds_flag=0;
 int8 busy=0, temp1, temp2; 
 signed int16 temp3; 
 static float result; 

 if(ds_flag==0)
 {
   onewire_reset(); 
   onewire_write(0xCC); 
   onewire_write(0x44); 
   ds_flag=1;
 }
 else
 {
   busy = onewire_read(); 
   if(busy==0)return result;
 }
 ds_flag=0;
 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0xBE); 
 temp1 = onewire_read(); 
 temp2 = onewire_read(); 
 temp3 = make16(temp2, temp1); 
  
 result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution 

 return(result); 
}


Tam istediğim gibi oldu aslında. Sıcaklık dönüşümü yapılmamışsa eğer Bir önceki sıcaklık değeriyle program geri dönüyor. Eğer dönüşüm işlemi tamamlanmışsa sıcaklık değişkeni güncellenip fonksiyon güncel değer ile geri dönüyor.

Fakat sıcaklık değeri stabil olmuyor. Normalde okunan değer 27-28 lerdeyken bir bakıyorsun 70-80'lara çıkıp hemen düzeliyor. Bunun için başka nasıl önlem alabilirim?

RaMu

#1
Ds18b20ye sıcaklığı oku de,
timer ile 750 ms den fazla bekleyip 800-900
sonra artık kesinlikle hazır olan sıcaklık bilgisii oku.

Veya
temp1, temp2, temp3 ve result değişkenlerini global olarak tanımla
ve programın hiçbiryerinde bu değişkenlerin değerini değiştirme,
aslında sadece result değişkenini global olarak tanımlaman yetecektir bence.

Böyle düşünmemin sebebi şu
result değişkeni 1wire için kullanılan fonksiyon içi bir değişken,
1 wire a fonksiyonu yazanın istediği gibi girip çıkılınca doğru değeri alır
ama fonksiyonun yarısındayken çıkar gidersen
o sıradaki result içinde anlamlı birşey olmak zorunda değildir,
result 1wire başka biryerde bozup kullanabilir,
veya sıfırlayabilir bence.

Yine aynı mantıkla işlemi yukarıda şekilde değilde şöylede yapabilirsin,
static float son_okuma; diye global bir değişken tanımla,
1wire fonksiyonunda
static float result; satırının altına
result=son_okuma; de.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

serdararikan

Olcumlerinizin dogrulugu hakkinda problem yasiyormusunuz?

Mucit23

@Ramu Timer ile felan uğraşmayalım şimdi. Çünkü iki adet timerim var ikiside kullanılıyor.

Bence kullandığım mantık iyi.  Belki dediğin gibi değişkenlerin fonksiyon içerisinde tanımlanmış olmasından kaynaklanıyordur. Aslında statik olarak tanımlanması fonksiyon içeriisndeki değişkenin değerinin silinmemesi anlamına gelmiyormu? Değişkenleri global yapsam ne gibi artıları olacak?

@serdararikan hocam ben hiç güvenmiyorum bu sensörlere. Doğruluğun hep şüphe duydum. Oda termometreleri ile yan yana koyduğumda hep arada 1-2 derece fark görüyorum.

Gerçi çinden aldığım su geçirmez ds18b20 probları var. Onları kullanıp buzlu su testi yapayım ozaman belli olur.

RaMu

Bence sonuçta ds1820_read() fonksiyonunu her çağırdığında
fonksiyon static float result; ile değişkeni tekrar tanımlayabilir
static olması buna engel olurmu bilemiyorum,
program yakınlarındaysa dediğim son iki yöntemi denemen 2 dk sürmez
deneyip sonucu yaz, bende  merak ettim.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23


Okan AKÇA

çözünürlügü degiştirerek  bekleme zamanını azaltabilirsiniz

serdararikan

bende artık hiç güvenmiyorum bu sensörlere.hem hatalı ölçüyor hemde lineer değil.

kantirici


Murat Mert

S.A.
Sn. Ferhat ntc kullansanız olmazmı?
mert07

skara1214

okuduğun değeri bir öncekiyle karşılaştır +-5 dereceden fazla değer varsa ciddiye alma 
Herkes ölür ama herkes gerçekten yaşamaz

F493

Selam,

  Sorun şu; Ds18B20'nin alt fonksiyonları var. Örnegin read bit gibi,  ör. pini 1 yapip 30us sonra 0 yapması gerekiyor siz orada beklemeyip başka işlemler yaptığınızda bu 30us sureyi belki 500us'ye çıkarmış oluyorsunuz. Fakat datasheet min 25us max 40us olsun diyor örnek verdim sadece.  Umarım sorunu anlatabilmişimdir.

Bir nokta daha, farz edelim siz 750ms bekleme yapıp öyle okudunuz hala başka sıkıntılar var. Örneğin, siz readBit ile ds18b20 den bir bit okuyacaksınız pini low yaptınız ve 30us bekleyip pini high yapacaksınız eğer siz pini low yaptıgınız anda bir interrupt gelirse ve bu interrupt içinde geçen süre 100us ise yine hatalı bilgi alma durumu var. Burada interruptları kapatıp orayı işleyip sonra tekrar açmak gerekiyor.

Bunu bekleme olmadan yapmanın bir yolu olabilir belki , düşünmek lazım.

Esen kalın.

Burak B

#12
@mucit23 sensör ölçümünü critical section yap. Fonksiyona girerken interruptların durumlarını sakla ve disable et. Çıkarken tekrar interrupt durumunu iade et. Böylece ISR olarak engellemeye maruz kalmazsın. Ayrıca beklemek istemiyorsan bir tick timer kurmalısın bu RTC de olabilir. Bir okuma işlemin bittikten sonra tick değerini al ve bu değer 750ms aşmışmı diye kontrol et. Eğer aşmamışsa sensör okuma fonksiyonuna girme ve boş zamanı diğer fonksiyonlarına harca. Aslında bu işin mantığı için round-robin v.s. bakabilirsin. Yada FSM ile de olabilir.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

RaMu

Mucit23 sorunu çözdünmü bilmiyorum ama
ben meraktan denedim,
fonksiyonu şu şekilde değiştirince istediğin gibi çalışıyor,
ds18b20yi asm ile çalıştırmıştım,
F493 ün belirttiği gibi durumlar var,
notlarıma bakmadan hatırladığım kadarıyla fonksiyonu değiştirdim
yinede sıkıntı çıkacağını sanmıyorum,
ds18b20deki esas bekleme yapan yer
çözünürlüğe bağlı olarak
ds18b20ye sıcaklığı söyle dediğimizde
bu işlemi içinde yapıp bize sonucu söylemesi 750ms kadar sürüyor
bu 750ms boyunca ccsc fonksiyonu cevabın gelmesini boş boş bekliyor,
ben bu kısmı baypas ettim fonksiyonda;
değiştirilmiş hali şöyle;
zaten değişiklik hemen görülüyor ama gerekirse anlatırım,

float ds1820_read() 
{ 
 int8 busy=0, temp1, temp2; 
 signed int16 temp3; 
 float result;
 
 static int one_read,busy_2;


if(one_read==0)      //b
{

 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0x44); 
one_read=1;         //b
}

// while (busy == 0) 
//  busy = onewire_read();


   while (busy_2 == 0) 
   {
  busy_2 = onewire_read();
   return(result);         //b
   }
one_read=0;      //b




 onewire_reset(); 
 onewire_write(0xCC); 
 onewire_write(0xBE); 
 temp1 = onewire_read(); 
 temp2 = onewire_read(); 
 temp3 = make16(temp2, temp1); 
  
// result = (float) temp3 / 2.0;   //Calculation for DS18S20 with 0.5 deg C resolution 
 result = (float) temp3 / 16.0;  //Calculation for DS18B20 with 0.1 deg C resolution 
  
 delay_ms(200); 
 return(result); 
}



Bu şekilde kullanan örnek,
2*16 lcd ve rs232 üzerinde sıcaklığı gösteriyor,
isis simulasyonu ve proje dosyası
(expkits in hazırladığı örnekten devşirdim)
https://www.dropbox.com/s/lnwzohlnpbb0zch/Ramu_CCSC_DS18B20_beklemesiz.rar
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Hocam benim yaptığımda aynı zaten.  Şuanda böyle iyi gibi.  Galiba hizla ilgili bir sıkıntı var.  One_wire.c dosyasına bakmam lazım.