18 Ağustos 2013 Pazar

DS18B20 SICAKLIK SENSÖRÜ İLE FAN HIZ KONTROLÜ

  Merhaba arkadaşlar bu projede DS18B20 dijital sıcaklık sensörü ile fan kontrolünün nasıl sağlanabileceğini anlatacağım.Bu projeyi arkadaşlarımla gerçekleştirdik.
  Anlatmaya sıcaklık sensörümüzden başlayayım.Sensörün üç tane ayağı var.Bunlardan 1 nolu uc toprak bağlantısı yaptığımız gnd ucu,2 nolu uc dijital sıcaklık değerini okuduğumuz data ucu,3 nolu uc ise  5 volt uyguladığımız vdd ucudur.



  16F877A pic'ini kullandık.L298 motor sürücü ile bir çift fanın kontrolünü birlikte sağladık.L298 motor sürücüsünün 15 ayağı bulunmaktadır. Motor sürücünün enable1 ve enable2 ucları picin CCP1 ve CCP2 uclarına bağlanır.CCP uclarından gelen belli oranda pwm duty'leri ile sürücünün output uclarındaki fanların(motorların) hız kontrolleri sağlanır.l298 motor sürücü ve pin konfigürasyonu aşagıdaki gibidir.


















  L298 motor sürücünün ve DS18B20  sıcaklık sensörünün datasheetine de bakarak daha fazla  bilgi bulabilirsiniz.
  İsis devremizde aşağıdaki gibidir.



       Devremizde 20MHz'lik kristal kullandık fanları temsilen isisde dc motor kullandık.                            Sıcaklık sensörünün ortadaki data pininden gelen sıcaklık değerini program içerisinde okutup bir değişkene atadık.Daha sonra değişkene atadığımız sıcaklık değerini if komutu içerisinde belirli sayı değerlerinden küçük veya büyük olup olmadığına göre belirli işlemler yaptık.Tabi ki bu işlemler dc motorun belirli yüzde veriminde çalışmasını sağlamak olacaktır.Bunuda yukarıda bahsettiğimiz pwm modülü ile sağlıyoruz.Fanların kontrolünü ccs c pic programlama dili ile yazdık.Şimdi ccs c kodlarını inceleyelim.
/////////
#include "C:\Documents and Settings\İlçin\Desktop\fanaa\fankontrol.h"
#include <ds18b20.c>
void fan_ileri( );
void kirmizi();
void sari();
void main()
{
   float sicaklik;
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,100,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_tris_a(0x00);
   set_tris_b(0xFF);
   setup_CCP1(CCP_PWM);
   setup_CCP2(CCP_PWM);
   set_pwm1_duty(0);
   set_pwm2_duty(0);

  output_low(pin_d2);
  output_low(pin_d3);
  
while(1){
sicaklik=ds1820_read();
if(sicaklik<30){
   fan_ileri( );
   set_pwm1_duty(0);
   set_pwm2_duty(0);}
if(sicaklik>=30&&sicaklik<35){
   fan_ileri( );
   set_pwm1_duty(35);
   set_pwm2_duty(35);}
if(sicaklik>=35&&sicaklik<40){
   fan_ileri( );
   set_pwm1_duty(50);
   set_pwm2_duty(50);}
if(sicaklik>=40&&sicaklik<45){
   fan_ileri( );
   set_pwm1_duty(75);
   set_pwm2_duty(75);}
if(sicaklik>=45&&sicaklik<50){
fan_ileri( );
   set_pwm1_duty(90);
   set_pwm2_duty(90);}
if(sicaklik>50){
fan_ileri( );
   set_pwm1_duty(100);
   set_pwm2_duty(100);
}
   

   if(sicaklik<60)  sari();
   if(sicaklik>=60)  kirmizi();
   
}
}
void fan_ileri( ){
   output_high(pin_a0);
   output_low(pin_a1);
   output_high(pin_a2);
   output_low(pin_a3);
   }
void kirmizi( ){
   output_high(pin_d3);
   output_low(pin_d2);
}
void sari( ){
   output_high(pin_d2);
   output_low(pin_d3);
}

////////
   Kodları incelerseniz algoritmayı kolayca kavrayacağınızı düşünüyorum.ds18b20.c dosyasını yazdığınız programda include etmeniz gerekmektedir.Bunun için aşağıdaki ds18b20 kodunu  PIC C Compiler de yeni bir proje açıp oraya kopyalayıp derleyin ve oluşan .c uzantılı dosyayı ana program içerisinde include ediniz.Takıldığınız yer olursa yardımcı olmaya çalışırım.
****
#define ONE_WIRE_PIN PIN_b3
void onewire_reset() 

{
output_low(ONE_WIRE_PIN);
delay_us( 500 ); //1-wire resetleme için sıfıra çekilir
output_float(ONE_WIRE_PIN); //1-wire bir yapılır
delay_us( 500 ); // sensörün hazırlanması için beklenir.
output_float(ONE_WIRE_PIN);


void onewire_write(int data)
{
int count;
for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 ); // Sensöre yazma işlemine başlamak için  1-wire sıfıra çekilir.
output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // yazılacak bilgi 1-wire'da
delay_us( 60 ); // Yazma işlemi zamanı doldurulur.
output_float(ONE_WIRE_PIN); // 1-wire bir yapılır,
delay_us( 2 ); // 1us'den fazla beklenir.
}


int onewire_read()
{
int count, data;
for (count=0; count<8; ++count)
{
output_low(ONE_WIRE_PIN);
delay_us( 2 ); //Sensördem okuma işlemi içinl 1-wire sıfıra çekilir.
output_float(ONE_WIRE_PIN); //1-wire bir yapılır,
delay_us( 8 ); // Sensörün kendine gelmesi beklenir,
shift_right(&data,1,input(ONE_WIRE_PIN)); // sonuc bilgisi alınır.
delay_us( 120 ); //Okuma işlemi zamanı doldurulur.
}
return( data );


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;//18b20 icin
//result = (float) temp3 / 2.0;//18s20 icin
delay_ms(200);
return(result);
}
****
 Projenin bitmiş hali aşağıdaki video ve resimlerdeki gibidir.








                                 


 
    Ds18b20 sensörünün bellek haritası:


     Configuration Register:

   
     Ölçüm değerinin saklandığı byte 0-1 registerları:
     
    Örnek sıcaklık değerleri:

 
    Haluk Yağcı,Emre Aladaş,Hasan Tunay ve Muhammed İçen arkadaşlarıma teşekkür ediyorum.
İlgilenen arkadaşlara kolay gelsin. Başarılar dilerim.

8 yorum:

  1. Eser bey merhaba

    devre ve programınızı denedim çok güzel olmuş bende yeni yeni ccs c öğrenmeye uğraşıyorum bu konuda aşamadığım noktalar oluyor çünkü yazılan kelimelerin satırlardaki tam anlamalarını çözemedim henüz



    yinede farklı mantıklar yürüterek sizin ısı okuma mantığınızla ds18b20 yi pic 16f628a ile okumayı başardım bilen için 5-10 satırlık basit olaydır kesinde hiç bilmeyip yeni başlayınca karanlıkda yol bulmak gibi oluyor



    mesela sizin kodlarınızı biraz değiştirip belli sıcaklıklara geldiğinde değişik portlarda led yaktım belli bir seviyenin üstüne çıkıncada farklı bir portta ledi yakıp söndürdüm bu bile bana güzel geldi en azından ne olmasını istemişsem onu yapmak bile başarı şimdilik,



    şimdi size sormak istediğim ise şöyle



    bir ısı aralığı belirleyip min ile max arasında , örneyin portb 0---portb7 den sırayla led yalkmak aslında if şartı ile yapptım fakat sıcaklık 10 derece artarak led yakalabildim , mesela 1 derece 1 derece artırarak led yakamadım , max değerine geldiğimde ise tüm ledlerim yanıyordu fakat sıcaklığı düşürerek geri geldiğimde ledler sönmüyor yine hepsi yanık kalıyor , bunula işlemi ter uygulayarak portları low çekme yolu ile söndürdüm , fakat bunu böyle olacağını sanmıyorum mutlaka bir yöntem vardır diye düşünüyorum







    ilgi ve alakanız için şimdiden

    Teşekürler



    Kamil KAYA

    YanıtlaSil
    Yanıtlar
    1. Merhaba Kamil Bey

      İlginiz için teşekkürler. Sorunuza geçmeden önce Ds18b20 sensörü hakkında konuşmak istiyorum çünkü bu bilgiler ışığında sorunuzu cevaplamanın daha faydalı olacağı düşüncesindeyim.
      Ds18b20 sensörü 9 ila 12 bit çözünürlükte ve -55 ile 125 derece arasında sıcaklık dönüşümü yapan ve one wire üzerinden iletişim sağlayan bir dijital sıcaklık sensörüdür. Ayrıca belirlenen sıcaklık değerinde alarm özelliği de vardır. Eğer sensör üzerinde herhangi bir ayar yapılmazsa 12 bit çözünürlükte dönüşüm yapılır ve bu dönüşüm 750ms süre içerisinde tamamlanır. 12 bit haricinde 9,10 ve 11 bit çözünürlük çalışmak içinse sensörün bellek haritasını incelememiz gerekecektir. Bellek haritasını yukarıya az önce koydum. Ds18b20 nin bellek haritasına baktığımızda görülüyor ki Byte 0-9 aralığında registerlar var. Bu registerların her birinin farklı görevleri vardır. Byte 4 olan Configuration Registeri sensörün hangi çözünürlükte çalışacağını ayarlar. Configuration Register ının 5 ve 6. bitlerine karşılık gelen R0 ve R1 e belirli değerler yüklenerek çözünürlük ayarlanır. Yine yukarıya koyduğum tabloyu incelediğinizde daha iyi anlayacaksınız.
      Sensörün okuduğu sıcaklık değeri ise dijital olarak Byte 0 (LS Byte) -Byte 1 (MS Byte) registerlarında saklanır. Byte 0 ve Byte 1 de sıcaklığın işareti, tam kısmı ve ondalıklı kısmı saklıdır. Bit0-3 aralığında sıcaklığın ondalık kısmı, bit4-10 aralığında tam kısmı ve bit10-15 arasındanda işareti belirlenir. Bu digital değerler hesaplanarak gerçek sıcaklık değeri bulunur. Yukarıdaki tabloda belirli sıcaklık değerlerine karşılık gelen 16 bitlik dijital değerler görülmektedir. Tabi siz CCS C kulandığınız için ds1820_read(); ile sıcaklık değerini doğrudan okuyacaksınız.
      TH ve TL registerları ise alarm için kullanılan registerlardır. Bu ragisterlara yüklenen değerler ile ölçüm sounucu ile karşılaştırılır.
      Ayrıca belirli Rom ve Fonksiyon komutları vardır bunlarıda ürün datasheetinden veya Selim Koç un micro C ile programlama kitabından inceleyebilirsiniz.
      Bu bilgiler bir assembly kullanıcısı için gereklidir. Eğer pic programlama mantığı tam olarak öğrenilmek isteniliyorsa assembly dilinin çalışılmasının çok gerekli olduğu düşüncesindeyim. Ben yaptığım projelerde assembly kullanmıyorum mikroC kullanıyorum. Fakat assembly dili hakkında bilgi sahibiyim. Ve assemly öğrenenen kişi C dilinde daha başarılı oluryor.
      Şimdi sizin sorunuca gelecek olusak 12 bitte sensör 0,0625 derece hassasiyetle çalışır. Bu hassasiyet artık önemsiz çünkü siz port0-7 de sıcaklık değerini göstermek istiyorsunuz. O zaman bazı sıcaklık değişimlerini görmezden gelmeniz gerekecek. Ds18b20 -55 ila 125 arasında ölçüm yapıyordu. O zaman maximum ölçeceği değer 125 derecedir.

      float sicaklik;
      int deger=0, izci=126;
      int say[9] ={0,1,3,7,15,31,63,127,255};
      while(1){
      sicaklik=ds1820_read();
      deger=sicaklik/15.625; // 125/8=15.625
      if(değer!=izci) output_B(say[değer]);
      izci=deger;
      // bir sonraki ölçümde sıcaklık değeri bir öncekiyle aynı olursa //aynı değeri tekrar porta yazmak ledlerde titreşim oluşturur //bunu engellemek için --> izci=deger; böyle bir işlem yapıldı.
      }

      Bu şekilde bir algoritma oluşturdum. Hatalar olabilir fakat en azından yapmak istediğimi anlatabilmişimdir umarım.
      Faydalı olması dileğiyle...

      Sil
  2. slm eser bey ben elk öğrencisiyim bir proje ödevim var yardımcı olurmusunuz.Benim ISI NEM BASINÇ kontrolü yapmam gerekiyor ve LCD ekranda görüntülemeliyim bunları ayarladığım set değerlerinde belli çıkışlar almam derekiyor bu konuda yardımcı olurmusunuz teşekkürler ....

    YanıtlaSil
  3. eser bey kırmızı ile yazılmış olan kodu ne için yazdık projede kullanacakmıyız ? kullanacaksak yine aynı pic e mi yazacağız? yardımcı olursanız sevinirim öğrenciyim.

    YanıtlaSil
    Yanıtlar
    1. One wire ile sıcaklık değerini okuyabilmek için ds18b20 nin registerlarının şartlanması gerekiyor. Kırmızı kod ds18b20 nin çalışması için kullanılıyor. Bunu programınıza include etmeniz gerekiyor.

      Sil
    2. http://www.teknikders.com/17-ders14-ds18b20-sensoru-ile-sicaklik-olcme.html ben de bu linkden dosyayı bulup kullandım

      Sil
  4. Maili mi versem ares şemasını bana atabilir misiniz bazı elemanları tanımlayamadım daha yeni öğreniyorum aresi de daha öğretmediler yardımcı olursanız sevinirim (brekgungor@gmail.com)

    YanıtlaSil
  5. Bunun ares çizimini ben yapmadım onun için elimde çizim yok.

    YanıtlaSil