ds18b20 problemi

Başlatan jackal183, 11 Şubat 2012, 11:26:41

jackal183

arkadaşlar merhaba forumda birçok yerde geçmiş birçok kişi bu problemle karşılaşmış, ben de karşılaştım inceleme yaptım ama sorunumu çözemedim. ds18b20 ile sıcaklık okumaya çalışıyorum, ancak 1-2 derece yüksek okuyor sıcaklığı, pic18lf25k22 kullanıyorum,

ds18b20'nin devresi her yerde herkesin kullandığı devre, vdd ile d arasında 4.7k direnç var. kullandığım yazılım da şu:

#define ONE_WIRE_PIN PIN_c2


void onewire_reset()  // OK if just using a single permanently connected device 
{ 
   output_low(ONE_WIRE_PIN); 
   delay_us( 500 ); // pull 1-wire low for reset pulse 
   output_float(ONE_WIRE_PIN); // float 1-wire high
   delay_us( 500 ); // wait-out remaining initialisation window. 
   output_float(ONE_WIRE_PIN); 
} 

/*********************** onewire_write() ********************************/ 
/*This function writes a byte to the sensor.*/ 
/* */ 
/*Parameters: byte - the byte to be written to the 1-wire */ 
/*Returns: */ 
/*********************************************************************/ 

void onewire_write(int data) 
{ 
int count; 

   for (count=0; count<8; ++count) 
   { 
     output_low(ONE_WIRE_PIN); 
     delay_us( 2 ); // pull 1-wire low to initiate write time-slot. 
     output_bit(ONE_WIRE_PIN, shift_right(&data,1,0)); // set output bit on 1-wire 
     delay_us( 60 ); // wait until end of write slot. 
     output_float(ONE_WIRE_PIN); // set 1-wire high again, 
     delay_us( 2 ); // for more than 1us minimum. 
   } 
} 

/*********************** read1wire() *********************************/ 
/*This function reads the 8 -bit data via the 1-wire sensor. */ 
/* */ 
/*Parameters: */ 
/*Returns: 8-bit (1-byte) data from sensor */ 
/*********************************************************************/ 

int onewire_read() 
{ 
   int count, data; 
   
   for (count=0; count<8; ++count) 
   { 
     output_low(ONE_WIRE_PIN); 
     delay_us( 2 ); // pull 1-wire low to initiate read time-slot. 
     output_float(ONE_WIRE_PIN); // now let 1-wire float high, 
     delay_us( 8 ); // let device state stabilise, 
     shift_right(&data,1,input(ONE_WIRE_PIN)); // and load result. 
     delay_us( 120 ); // wait until end of read slot. 
   } 
   
   return( data ); 
}

float ds1820_read() 
{ 
   int8 busy=0, temp1, temp2; 
   signed int16 temp3; 
   int8 tH,tL,Conf; 
   float result; 
   
   onewire_reset(); 
   onewire_write(0xCC); 
   onewire_write(0x44); 
   delay_ms(200); 
   while (busy == 0) 
     busy = onewire_read(); 
   
   onewire_reset(); 
   onewire_write(0xCC); 
   onewire_write(0xBE); 
   temp1 = onewire_read(); 
   temp2 = onewire_read(); 
   tH=onewire_read(); 
   tL=onewire_read(); 
   Conf=onewire_read(); 
   temp3 = make16(temp2, temp1); 
   
   //result = (float) temp3 / 2.0;   // 0.5 deg C resolution 
   result = (float) temp3 / 16.0;  //0.1 deg C resolution 
   delay_ms(200); 
   return(result); 
}


void initds18b20()
{
   //for  10 bit resolution mod  
   onewire_write(0xCC); 
   onewire_write(0x4E); 

   onewire_write(125); 
   onewire_write(-55); //this should be done for proper working of DS18B20 
   onewire_write(127); 

   onewire_reset(); 
   onewire_write(0xCC); 
   onewire_write(0x48); 
   delay_ms(15); 
}


void main()
{
        initds18b20();
       
        while(1)
       {
         sicaklik_degeri=ds1820_read();

        }
}

camby

200ms beklemişsin , eğer çözünürlüğün 12 bit ise 750 ms beklemen gerekir. Çözünürlükte değişiklik yapmadan olduğu gibi kullanıyorsan sonuç ölçüm 12 bittir.


Not : 200ms bekleden sonra yazdığın komut , ölçümün bitmesini mi bekliyor ?

jackal183

#2
bu kodu kendim yazmadım kardeş hazır aldım, bu forumda ya da başka forumlarda herkes bu kodu kullanmış, yani bilmiyorum 200 ms beklemenin ne yaptığını,  zaten ben şimdiden ds18b20 nin datasheetini karıştırmaya başladım bile.

200 ms den sonraki komut büyük ihtimalle sizin de dediğiniz gibi ölçümün bitmesini bekliyor. ölçümden geriye 0 dan farklı bir değer dönerse kod yürür.

hazad

Alıntı yapılan: camby - 11 Şubat 2012, 12:37:06
200ms beklemişsin , eğer çözünürlüğün 12 bit ise 750 ms beklemen gerekir. Çözünürlükte değişiklik yapmadan olduğu gibi kullanıyorsan sonuç ölçüm 12 bittir.


Not : 200ms bekleden sonra yazdığın komut , ölçümün bitmesini mi bekliyor ?


Dostum bit çözünürlüğü ile olan ilişkisini anlamadım. Bu zaten Sayısal bir çevirici değilmi. 12bit derken kasteddiğin şeyi anlamadım.

Benimde suanda ds1820 ile problemim var.

EXPKITS var elimde onun datasheet'inde sensör için 10K bağlamışlar. Sensör ilk seferde çalıştı ama sonra bir daha çalışmadı. Daha sonra direnci değiştirdim EXPkits'de ki.
Suanda normal çalışıyor ama benım kendi devremde bir türlü çalışmıyor. hep 0.5 derece okuyor. Aslında okumuyor sensoru cıkarınca da 0.5 geliyor.

Her tarafı kontrol ettim. PIC PortA 3 ucuna bağlı. 4.9K pull up var. bunun dışında zaten bir şeye gerek yok. aynı devre ve Yazılım EXPkit'te çalışıyor ancak benım devrede çalışmıyor. Sadece PINler farklı nedenini bir türlü çözemedim..


Arada bir fark daha var. EXPkit beslemesi 4.40V benim ki 5.03V bu datasheet'inde 3V-5.5V istenilen aralığında. Sorunu bir türlü çözemedim.

MikroC kullanıyorum Teşekkürşler

tekosis

Şemanı paylaşırsan çözüm daha kolay olacaktır. Ayrıca 12 bit olayı okunan sıcaklığın ne kadar detaylı okunacağı ile ilgili. sensörün hassasiyetini belirliyor. hassasiyet düşükse (8 bit gibi) okuma hızı düşer ama 12 bit ise bu okumanın yapılabilmesi için 750msn beklemek gerekiyor.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

camby

Alıntı yapılan: hazad - 12 Şubat 2012, 23:20:20

Dostum bit çözünürlüğü ile olan ilişkisini anlamadım. Bu zaten Sayısal bir çevirici değilmi. 12bit derken kasteddiğin şeyi anlamadım.

Benimde suanda ds1820 ile problemim var.

EXPKITS var elimde onun datasheet'inde sensör için 10K bağlamışlar. Sensör ilk seferde çalıştı ama sonra bir daha çalışmadı. Daha sonra direnci değiştirdim EXPkits'de ki.
Suanda normal çalışıyor ama benım kendi devremde bir türlü çalışmıyor. hep 0.5 derece okuyor. Aslında okumuyor sensoru cıkarınca da 0.5 geliyor.

Her tarafı kontrol ettim. PIC PortA 3 ucuna bağlı. 4.9K pull up var. bunun dışında zaten bir şeye gerek yok. aynı devre ve Yazılım EXPkit'te çalışıyor ancak benım devrede çalışmıyor. Sadece PINler farklı nedenini bir türlü çözemedim..


Arada bir fark daha var. EXPkit beslemesi 4.40V benim ki 5.03V bu datasheet'inde 3V-5.5V istenilen aralığında. Sorunu bir türlü çözemedim.

MikroC kullanıyorum Teşekkürşler


evet dijital çıkışlı. Normalde 12 bit data alıyorsun. 10 bit çözünürlüğe getirmişsen , 10 bit data alıyorsun.. Dijital olarak..

jackal183

Alıntı yapılan: hazad - 12 Şubat 2012, 23:20:20

Dostum bit çözünürlüğü ile olan ilişkisini anlamadım. Bu zaten Sayısal bir çevirici değilmi. 12bit derken kasteddiğin şeyi anlamadım.

Benimde suanda ds1820 ile problemim var.

EXPKITS var elimde onun datasheet'inde sensör için 10K bağlamışlar. Sensör ilk seferde çalıştı ama sonra bir daha çalışmadı. Daha sonra direnci değiştirdim EXPkits'de ki.
Suanda normal çalışıyor ama benım kendi devremde bir türlü çalışmıyor. hep 0.5 derece okuyor. Aslında okumuyor sensoru cıkarınca da 0.5 geliyor.

Her tarafı kontrol ettim. PIC PortA 3 ucuna bağlı. 4.9K pull up var. bunun dışında zaten bir şeye gerek yok. aynı devre ve Yazılım EXPkit'te çalışıyor ancak benım devrede çalışmıyor. Sadece PINler farklı nedenini bir türlü çözemedim..


Arada bir fark daha var. EXPkit beslemesi 4.40V benim ki 5.03V bu datasheet'inde 3V-5.5V istenilen aralığında. Sorunu bir türlü çözemedim.

MikroC kullanıyorum Teşekkürşler

yazılımını paylaşır mısın kardeş?

hazad

unsigned  xs;


/////////////////////////////////////////////////////
const unsigned short TEMP_RESOLUTION = 9;

char *text = "000.0000";
unsigned temp;

void Display_Temperature(unsigned int temp2write) {
  const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
  char temp_whole;
  unsigned int temp_fraction;

  // check if temperature is negative
  if (temp2write & 0x8000) {
     text[0] = '-';
     temp2write = ~temp2write + 1;
     }

  // extract temp_whole
  temp_whole = temp2write >> RES_SHIFT ;

  // convert temp_whole to characters
  if (temp_whole/100)
     text[0] = temp_whole/100  + 48;
  else
     text[0] = '0';

  text[1] = (temp_whole/10)%10 + 48;             // Extract tens digit
  text[2] =  temp_whole%10     + 48;             // Extract ones digit

  // extract temp_fraction and convert it to unsigned int
  temp_fraction  = temp2write << (4-RES_SHIFT);
  temp_fraction &= 0x000F;
  temp_fraction *= 625;

  // convert temp_fraction to characters
  text[4] =  temp_fraction/1000    + 48;         // Extract thousands digit
  text[5] = (temp_fraction/100)%10 + 48;         // Extract hundreds digit
  text[6] = (temp_fraction/10)%10  + 48;         // Extract tens digit
  text[7] =  temp_fraction%10      + 48;         // Extract ones digit

  // print temperature on LCD
  Lcd_Out(2, 5, text);
}
////////////////////////////////////////////////////////////
void main() {
     
        //FA_InitMCU();

        //FOR LCD PIN DIRECTION
        TRISD3_bit = 0;
        TRISC4_bit = 0;
        TRISD1_bit = 0;
        TRISC5_bit = 0;
        TRISC6_bit = 0;
        TRISD2_bit = 0;
				Lcd_Init();
				Lcd_Cmd(_LCD_CURSOR_OFF);
        		Lcd_Cmd(_LCD_CLEAR);
				  CMCON  |= 7; 
				  ADCON1 |= 0x0F;                               
				 /* //CMCON  |= 7;                                   
				    				Lcd_Init();
                EN1=0;
                EN0=1;
                S0=1;
                S1=0;
                S2=0;*/
				                                     
				  Lcd_Cmd(_LCD_CLEAR);                          
				  Lcd_Cmd(_LCD_CURSOR_OFF);                      
				  Lcd_Out(1, 1, " Temperature:   ");

				  Lcd_Chr(2,13,223); 
				                      

				  Lcd_Chr(2,14,'C');

					temp = 0;
				  while (1) {

				    Ow_Reset(&PORTA, 3);                         
				    Ow_Write(&PORTA, 3, 0xCC);               
				    Ow_Write(&PORTA, 3, 0x44);                   
				    Delay_us(120);

				    Ow_Reset(&PORTA, 3);
				    Ow_Write(&PORTA, 3, 0xCC);           
				    Ow_Write(&PORTA, 53, 0xBE);            
				    Delay_ms(400);

				    xs =  Ow_Read(&PORTA, 3);
				    xs = (Ow_Read(&PORTA, 3) << 8) + xs;
					temp++;
					IntToStr(temp,str);
					Lcd_Out(1,11,str);
					//IntToStr(xs,str);
					//Lcd_Out(2,11,str);
					Display_Temperature(xs);

				    Delay_ms(500);
				  }


Bu Kodun Aynısı EXPKits'te çalışıyor.

Şemayıda Gönderiyorum hemen

jackal183

ow_write, ow_read ve ow_reset fonksiyonlarını da gönderir misin?

hazad

Fonksiyonlar MikroC nin Hazır fonksiyonları. içini göremiyorum. Baya bi uğraştım ama olmuyor.

Bir de sormak istediğim neden 5V pull up yapıyoruz. bu biraz mantıksız değil mi? Datasheet'inde de öle gösteriyor. Pull Down yapsak daha mantıklı değil mi?

jackal183

o bana da mantıksız geldi kardeş, yani 5 v pull-up yaptığımız zaman sensöre hep sabit değerler gider, e ne anlamı kaldı o zaman one_wire iletişim protokolünün. ama bakınca da o pullupı yapmadığın zaman sensör çalışmıyor

hazad

Tamam Hallettim Arkadaşlar. LM35 Bağlıydı önce onun için paralel kapasite koymuştum şimdi hallettim.

Teşekkürler Arkadaşlar.