Picproje Elektronik Sitesi

SERBEST BÖLGE => Programlama ve Algoritma => Konuyu başlatan: Mucit23 - 22 Temmuz 2014, 17:43:24

Başlık: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 22 Temmuz 2014, 17:43:24
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?
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: RaMu - 22 Temmuz 2014, 18:34:11
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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: serdararikan - 22 Temmuz 2014, 20:05:42
Olcumlerinizin dogrulugu hakkinda problem yasiyormusunuz?
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 22 Temmuz 2014, 20:48:38
@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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: RaMu - 22 Temmuz 2014, 20:58:44
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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 22 Temmuz 2014, 21:16:39
Tamam deneyelim.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Okan AKÇA - 22 Temmuz 2014, 21:59:08
çözünürlügü degiştirerek  bekleme zamanını azaltabilirsiniz
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: serdararikan - 23 Temmuz 2014, 01:26:05
bende artık hiç güvenmiyorum bu sensörlere.hem hatalı ölçüyor hemde lineer değil.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: kantirici - 23 Temmuz 2014, 01:43:54
state machine iş görür bence.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Murat Mert - 23 Temmuz 2014, 10:19:31
S.A.
Sn. Ferhat ntc kullansanız olmazmı?
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: skara1214 - 23 Temmuz 2014, 10:23:46
okuduğun değeri bir öncekiyle karşılaştır +-5 dereceden fazla değer varsa ciddiye alma 
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: F493 - 23 Temmuz 2014, 11:13:36
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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Burak B - 23 Temmuz 2014, 13:26:11
@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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: RaMu - 24 Temmuz 2014, 22:27:04
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 (https://www.dropbox.com/s/lnwzohlnpbb0zch/Ramu_CCSC_DS18B20_beklemesiz.rar)
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 25 Temmuz 2014, 00:49:56
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.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Karamel - 25 Temmuz 2014, 00:55:09
hocam ben konu disinda birsey merak ediyorum. fonksiyonu neden void deilde float olarak tanimladiniz? ( float ds1820_read()  )
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: RaMu - 25 Temmuz 2014, 00:57:28
Aynı değil busy değişkeni herseferinde 0 yükleniyor sende
ben onu static int busy_2 olarak değiştirdim,
aslında int8 busy tanımlamasını kaldırsam daha net görülürmüş.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 25 Temmuz 2014, 01:14:18
Tekrardan bi inceleyeyim
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: RaMu - 25 Temmuz 2014, 01:19:33
Alıntı yapılan: Karamel - 25 Temmuz 2014, 00:55:09
hocam ben konu disinda birsey merak ediyorum. fonksiyonu neden void deilde float olarak tanimladiniz? ( float ds1820_read()  )
c de fonksiyonlar konusuna bakmalısın
geriye değer döndüren fonksiyonlar kısmında yazar,
bu fonksiyon çağrıldıktan sonra
result değişkeni içinde geriye float bir değer döndürüyor,
bu yüzden float olarak tanımlı,
misal integer bir değer döndürseydi
int olarak tanımlayabilirdik.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Karamel - 25 Temmuz 2014, 04:53:45
yanit icin tesekkur ederim ramu hocam. boyle olabilecegini tahmin etmistim ama emin deyildim.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: Mucit23 - 27 Temmuz 2014, 14:24:44
Sensör bayağı hassasmış.

Büyükçe bir bardak içerisine buzları doldurdum. Boşluk kalmayacak şekilde birazda içerisine su koydum. 10 Dakika kadar bekledim ve Su geçirmez ds18b20'yi daldırdım buzların içerisine.

Buzların tam arasındayken 0,8C hatta 0,6C felan görüyorum. Tam sıfır olması zaten beklemiyordum. Bu durumda hata yok gibi.

Şimdi buzların bir kısmı eridi. Buzlar bardağın üstünde yüzüyor. Sensörü bardağın dibine yani buz olmayan kısıma götürünce sıcaklık 1,5-2C oluyor. Sensörü yukarı buzların arasına alınca hemen yine 0,6 lara iniyor.

Buz testinin sonuçları böyle.
Başlık: Ynt: DS18B20'de beklemeden ölçüm alma
Gönderen: mehmet - 27 Temmuz 2014, 15:42:13
Buz içerisine bir miktar tuz koyup deneyiniz...