sıcaklık sensörü arada 00 derece gösteriyor

Başlatan baran123, 01 Nisan 2014, 18:50:54

baran123

Merhaba ds18b20 ile 2 adet displayde sıcaklık gösteriyorum gayet iyi çalışıyor ama bazen 00,85 gibi değerler gösterip hemen normal sıcaklığı göstermeye devam ediyor bunu nasıl engelleyebilirim kodlar assağıda yardımcı olursanız sevinirim

#include <16F88.h>
#device adc=16
#fuses NOWDT,XT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOWRT,NOPROTECT,NODEBUG
#use delay(clock=4M)
#include "ds18b20.c"

#define digit_birler pin_a1
#define digit_onlar pin_a0  

int temp,sayac = 0;                                   
const int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6F};   

#int_timer0
void timer0_kesme () 
{
   disable_interrupts(INT_timer0);
   switch(sayac)
   {
      case 0:      
      output_low(digit_onlar);
      output_b(digit[temp % 10]);
      output_high(digit_birler);
      sayac = 1;
      break;
      
      case 1:
      output_low(digit_birler);
      output_b(digit[temp / 10]);
      output_high(digit_onlar);
      sayac = 0; 
      break;
   }
   enable_interrupts(INT_timer0);
}

void main()
{
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(T0_INTERNAL | T0_DIV_16 );
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   set_timer0(131);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
   
   set_tris_a(0x00);
   set_tris_b(0x00);
   output_a(0x00);
   output_b(0x00);
   
   while(TRUE)
   {temp = ds1820_read();}
}                             


ds18b20 kutuphanem
#define ONE_WIRE_PIN PIN_A2

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;
   delay_ms(200);
   return(result);
}

Kabil ATICI

ekran taramasını timer ile kontrol ediyorsun. Şimdi sıcaklık sensörünü okurken timer kesmesi gelirse ne olur? Kaldı ki 1 wire bağlantısı oldukça sıkı bir zamanlama kontrolu gerektirir. Hata oluşur.!!

Sıcaklık sensörünü okurken, timer kesmesini iptal etsen iyi olur. Daha sonra tekrar timer'ı devreye alırsın...
ambar7

baran123

#2
Dediğiniz doğru fakat bu seferde cok yavas tarama yapıyor 1 sanıye aralıklarla dısplayler yanıyor while ın içini soyle yaptım
While(TRUE)
{                   
      disable_interrupts(INT_timer0);
      temp = ds1820_read();
      enable_interrupts(INT_timer0);


ve - seger okutmak ıstıyorum 2 dısplay oldugu ıcın max.-9 okuturum soyle bır sey dusundum ama bır hata var "-" gostermıyor sadece degerı gosterıyor yanı proteusta ds18b20 yı -5 yaptıgım zaman dısplayde "05" yazıyor kodların son halı assagıda

#include <16F88.h>
#device adc=16
#fuses NOWDT,XT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOWRT,NOPROTECT,NODEBUG
#use delay(clock=4M)
#include "ds18b20.c"

#define onlar  pin_a0 
#define birler pin_a1                        

signed int onlar1 = 0,birler1 = 0,sonuc;
signed int temp,sayac = 0;                                   
const int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6F};   
            
#int_timer0
void timer0_kesme() 
{     
   disable_interrupts(INT_timer0);
   switch(sayac)
   {                           
      case 0:      
      output_low(onlar);        
      onlar1 = temp % 10;          
      output_b(digit[temp % 10]);
      output_high(birler);
      sayac = 1;
      break;
                
      case 1:
      output_low(birler); 
      birler1 = temp / 10;  
      output_b(digit[temp / 10]);
      output_high(onlar);
      sayac = 0;  
      break; 
      
      if(sonuc < 0)
      {          
         sayac = 0;
         switch(sayac)
         {                 
            case 0:      
            output_low(onlar);                 
            output_b(0x40);
            output_high(birler);    
            sayac = 1;     
            break;
                      
            case 1:     
            output_low(birler);  
            birler1 = temp / 10;   
            output_b(digit[temp / 10]);
            output_high(onlar);
            sayac = 0; 
            break;              
         }               
      }    
   }                           
   enable_interrupts(INT_timer0); 
}

void main()
{                        
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(T0_INTERNAL | T0_DIV_16 );
   setup_timer_1(T1_DISABLED);  
   setup_timer_2(T2_DISABLED,0,1);    
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   set_timer0(131);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
   
   set_tris_a(0x00);
   set_tris_b(0x00);       
   output_a(0x00);
   output_b(0x00);          
                      
   while(TRUE)   
   {                    
      //disable_interrupts(INT_timer0); 
      temp = ds1820_read(); 
      sonuc = onlar + birler;
      //enable_interrupts(INT_timer0);
   }                                      
}                             

baran123

Güncel arkadaşlar plakete geçireceğim dereyi ondan çözmeme yardımcı olur musunuz kusura bakmayın.

Salih

Şöyle bir denermisin.

#int_timer0
void timer0_kesme() 
{     
   disable_interrupts(INT_timer0);
   switch(sayac)
   {                           
      case 0:      
      output_low(onlar);   
      if (temp < 0.0)
      {
      output_b(0x40);
      }else
      {
      onlar1 = temp % 10;          
      output_b(digit[temp % 10]);
      }
      output_high(birler);
      sayac = 1;
      break;
                
      case 1:
      output_low(birler); 
      birler1 = temp / 10;  
      output_b(digit[temp / 10]);
      output_high(onlar);
      sayac = 0;  
      break;     
      default:;     
      }    
                              
   enable_interrupts(INT_timer0); 
}

baran123

maalesef çok saçma garip değerler gösteriyor 0 ın altına inince kod soyle son sekılde

#include <16F88.h>
#device adc=16
#fuses NOWDT,XT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOWRT,NOPROTECT,NODEBUG
#use delay(clock=4M)
#include "ds18b20.c"

#define onlar  pin_a3
#define birler pin_a4                        

signed int onlar1 = 0,birler1 = 0,sonuc;
signed int temp,sayac = 0;                                   
const int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6F};   
            
#int_timer0
void timer0_kesme() 
{     
   disable_interrupts(INT_timer0);
   switch(sayac)
   {                           
      case 0:      
      output_low(onlar);                  
      if (temp < 0.0)
      {
      output_b(0x40);
      }else
      {
      onlar1 = temp % 10;          
      output_b(digit[temp % 10]);
      }
      output_high(birler);
      sayac = 1;
      break;
                
      case 1:
      output_low(birler); 
      birler1 = temp / 10;  
      output_b(digit[temp / 10]);
      output_high(onlar);
      sayac = 0;  
      break;     
      default:;     
      }    
                              
   enable_interrupts(INT_timer0); 
}

void main()
{                        
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(T0_INTERNAL | T0_DIV_16 );
   setup_timer_1(T1_DISABLED);  
   setup_timer_2(T2_DISABLED,0,1);    
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_CCP1(CCP_OFF);
   set_timer0(131);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL);
   
   set_tris_a(0x00);
   set_tris_b(0x00);       
   output_a(0x00);
   output_b(0x00);          
                      
   while(TRUE)   
   {                    
      //disable_interrupts(INT_timer0); 
      temp = ds1820_read(); 
      sonuc = onlar + birler;
      //enable_interrupts(INT_timer0);
   }                                      
}                             

Salih

@ baranekrem9 
negatif değerlerde düzeltme yapman gerekir.
Aşağıda 4 dijitli ve negatif işaret gösteren çalışan program.
#include <16F877A.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal=20000000)
#include "ds18b20.c"

#define dbirler   pin_d7
#define donlar    pin_d6
#define kbirler   pin_d5
#define konlar    pin_d4

int8  birler = 0,onlar = 0,birler1,onlar1, j=0;
signed int16 temp=0,temp1=0;
float f;
const int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6F};

#INT_RTCC
void  RTCC_isr(void) 
{
   disable_interrupts(INT_TIMER0);   
   switch(j)  
   {   
   case 0:
      output_high(konlar);     
      output_b(digit[birler]);
      output_low(dbirler);   
      j=1;
      break;
  case 1:
      output_high(dbirler);
       if (temp1 < 0)
      output_b(0x40);else
      if (onlar == 0) // sıfır gözükmesin
      output_b(0);else
      output_b(digit[onlar]);
      output_low(donlar);   
      j=2;
      break;
   case 2:  
      output_high(donlar);
      output_b(digit[birler1]);
      output_low(kbirler);   
      j=3;
      break;
   case 3:
      output_high(kbirler);
      output_b(digit[onlar1]);
      output_low(konlar);   
      j=0;
      break;
   default:
   }
   enable_interrupts(INT_TIMER0);
   set_timer0(99);
}

void main()
{
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_32|RTCC_8_bit);      //1,0 ms overflow
   enable_interrupts(INT_RTCC);
   enable_interrupts(GLOBAL);

   set_tris_b(0x00);
   set_tris_d(0x00);
   output_b  (0x00);
   output_d  (0xFF);

   while(TRUE)
   {
      f         =  ds1820_read();     
      temp1     = (int16) (f * 100.0);
      if (temp1 < 0) temp = -1 * temp1 ; else temp = temp1; 
      birler   = make8(((temp/100) % 10),0);
      onlar    = make8((temp / 1000),0);
      birler1   = make8(((temp/10) % 10),0);
      onlar1    = make8((temp % 10),0);      
      delay_ms(400);
   }
}

sard.555

Ben de genel olarak ara ara çok saçma sapmalar yapıyor ds18b20 simülasyonda parazit olayı olmadan niye böyle sapmalar yapıyor ki?

selimkoc

Kesme altında sayaçla zamanı saydır(sayac*tarama için timer süresi) sayac 1sn olduğunda bayrak aç. Ana program içinde bayrak aktif ise (kesmeleri iptal ederek) okuma yap ve bayrağı sıfırla.


baran123

Alıntı yapılan: selimkoc - 07 Nisan 2014, 13:00:19
Kesme altında sayaçla zamanı saydır(sayac*tarama için timer süresi) sayac 1sn olduğunda bayrak aç. Ana program içinde bayrak aktif ise (kesmeleri iptal ederek) okuma yap ve bayrağı sıfırla.

yanı timer ıcınde bır sayıcı yapım bu sayıcı 1 sanıye oldugunda ana programdakı ıf ıle kontrol mu edeyım dogrumu anladım ?

selimkoc

Tarama için kullanılan timer içinde yapılabilir.