Ynt: if olmuyor

Başlatan helloworld, 13 Aralık 2014, 01:21:21

helloworld



amacım böyle birşeyin simulasyonunu yapmak.

0-1v k=0,5  (1.5 volt giriyorsa 1.5*0,5=0,75v elde edebilmek.)   burada k bir sabit sayı.
1-2v k=0,67       
..
..
4-5v k=0,87

kodu göstericek olursam
#include <16f877.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli
#use fast_io(e) //Port yönlendirme komutları E portu için geçerli
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
#INT_AD
void ADC_kesmesi ()
{    
   output_high(pin_c5);
   delay_ms(500);
   output_low(pin_c5);
}


void main()
{
   set_tris_c(0x00);  // C portu komple çıkış
   set_tris_e(0x0F);  // E portu komple giriş
   set_tris_b(0x00);
   output_c(0x00);    // C portu çıkışını sıfırla
   output_b(0x00);
   setup_adc(adc_clock_div_32);   // ADC clock frekansı fosc/32
   setup_adc_ports(AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF);   // Tüm AN girişleri analog 
   enable_interrupts(INT_AD);     // AD çevrimi bitti kesmesi tanıtılıyor
   enable_interrupts(GLOBAL);     // Tüm kesmeler aktif
   
   while(true)
   { 
      float k1=0.5,k2=0.67,k3=0.7,k4=0.8,k5=0.87;
      unsigned int16 voltaj,cikis;
      set_adc_channel(5);
      delay_us(20);
      voltaj=read_adc();
      
      if(voltaj<1)
      {
         cikis=voltaj*k1;
         
      }
      else if(voltaj>=1 && voltaj<2)
      {
         cikis=voltaj*k2;
         
      }
      else if(voltaj>=2 && voltaj<3)
      {
         cikis=voltaj*k3;
        
      }
      else if(voltaj>=3 && voltaj<4)
      {
         cikis=voltaj*k4;
        
      }
      else if(voltaj>=4 && voltaj<5)
      {
         cikis=voltaj*k5;
         
      }
       else if(5<voltaj)
      {
         cikis=5*k5;
         
      }
      
    output_b(cikis);
      
   }   
}


if leri yerleştirdim fakat çıkışta değer bulamıyorum.proteusu da gösteriyim.




bunu yetiştirmem lazım.final notu vericek hoca.yapmış olursam öteki derslerime yogunlaşıcam.yardımlarınızı bekliyorum


mesaj birleştirme:: 13 Aralık 2014, 15:23:30


serdararikan

değişkeni float olarak tanımla

helloworld

az önce benimde o aklıma geldi.düzelttim tam mesajınız gelmeden serdararikan.ancak hiç hata vermiyor program.yine de olmuyor

Burak B

#3
Bu şekilde float değişkenleri if içerisinde kullanman yanlış bir yaklaşım. if bloğunda karşılaştırdığın float sayıların eşitliğini doğrulamaya çalışmak ne derece doğru? Mesela ya float yineleyen bir sayı ise ? Bu nedenle float değişkenin söz konusu olduğu karşılaştırma durumlarında;
1- Kesin hataya göre,
2- Bağıl hataya göre,
3- Integer dönüşümü methodu ile
karşılaştırma yapmak gerekir. Buna literatürde EPSILON değere göre karşılaştırma da denir.
Örnek vermek gerekirse;
if (fabs(sonuc - tahmini_sonuc) < 0.00001)
{
   /* Neredeyse eşit */
}


şeklinde kullanmak daha doğru olur. Burada 0.00001 absolute EPSILON değeridir. Kabul edilebilir hata payı da diyebiliriz.

Şunu da belirtmekte fayda görüyorum yukarıda verdiğim örnekte tam doğru yöntem olarak algılanmamalıdır. Eğer uygulamanız daha kritik bir uygulama ise izin verilen sabit hata payı ile karşılaştırma yerine bağıl hataya göre karşılaştırma yöntemi için bir fonksiyon kullanılması daha doğru olacaktır.

Ayrıca bakınız;
Machine Epsilon
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

Salih

if(voltaj>=1 && voltaj<2)


Şöyle yazarsan daha iyi olur

if((voltaj>=1) && (voltaj<2))


sadogan

Adc den okuduğun değer ,adc referansına ve adc çözünürlüğüne bağlı bir değer.
Direk voltmetre de okuduğun bir değer deyil.
Adc çözürünlüğü programda 8 bit ,referans ta 5 volt.
voltaj =read_adc()*(5000/256);(mili volt cinsinden);
Burdan yola çıkarak istediğin voltaj değerinin adc değerini hesaplayarak
karşılastırma yapman daha doğru.
1 volt için örnek hesaplama:
adc = 1*1000(5000/256) = 51.2 adc değeri ondalıklı olamayacağından ondalıklı kısmı atıyorsun.
1volt yerine 51 sayısını kullanıyorsun.

 

helloworld

@salih dediğinizi yaptım yine çalışmadı.@burak bayrak dediğinizi anlamadım.
@sadogan çarpıyorum o da olmuyor.işin içinden çıkamıyorum.olay çok basit ama niye olmuyor.

Burak B

Alıntı yapılan: helloworld - 13 Aralık 2014, 15:32:36
@salih dediğinizi yaptım yine çalışmadı.@burak bayrak dediğinizi anlamadım.
@sadogan çarpıyorum o da olmuyor.işin içinden çıkamıyorum.olay çok basit ama niye olmuyor.

Dediğimi anlamadığın ve anlamaya çaba göstermediğin için olmuyor.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

helloworld

#8
estağfirullah.öğlen 12 den beri bunla uğraşıyorum mesela.yazılanları 12 de gördüm.sonuç alamadım.ama dediğğin gibi olsun.yine de a.r.o.


mesaj birleştirme:: 13 Aralık 2014, 18:07:53

bu arada hallettim sorunu.mesele şurda bitiyor.

y=x*255/5;
         output_b(y);


yardımcı olmaya çalışan herkese eyw.

Recep METE

float k1=0.5,k2=0.67,k3=0.7,k4=0.8,k5=0.87;
      unsigned int16 voltaj,cikis;
      set_adc_channel(5);
      delay_us(20);
      voltaj=read_adc();


Simülasyonu incelediğimde "set_adc_channel(5); " komutu ile 5. kanal olan RE/AN5 pinindeki sinyalin A/D cevrimine tabi tutulacağı denetleyiciye bildirilmiştir.Simulasyonda 4.8v sabit bir değer bağlı olduğu görülüyor.Yani voltaj=4.8'dir.Bunun yerine ayarlanabilir bir potansiyometre koyarak deneyebilirsin. Denememiz için simülasyon dosyasını buraya yüklersen hatayı bulmamız daha kolay olacaktır.

Ayrıca;
else if(voltaj>=4 && voltaj<5)
      {
         cikis=voltaj*k5;
         
      }
       else if(5<voltaj)
      {
         cikis=5*k5;
         
      }
       burda iki if değeri de aynı sonucu verdiğinden(birincide 4-5 arası, ikincide 5 ten küçük) program doğru sonucu gösteremektedir.
printf(lcd_putc,"\f  Ne kadar okursan oku, bilgine, yakışır şekilde davranmıyorsan cahilsin demektir.  \n   semfero");d

helloworld

daha dikkatli bakarsanız voltaj 5 ten büyükken diyor.pot koydum sonradan.şuan gayet iyi.kodu paylaşıyım daha net görülür.böylece bilmeyen varsa ögrenebilir.

#include <16f877.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli
#use fast_io(e) //Port yönlendirme komutları E portu için geçerli
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
#INT_AD
void ADC_kesmesi ()
{    
   output_high(pin_c5);
   delay_ms(500);
   output_low(pin_c5);
}


void main()
{
   set_tris_c(0x00);  // C portu komple çıkış
   set_tris_e(0x0F);  // E portu komple giriş
   set_tris_b(0x00);
   output_c(0x00);    // C portu çıkışını sıfırla
   output_b(0x00);
   setup_adc(adc_clock_div_32);   // ADC clock frekansı fosc/32
   setup_adc_ports(ALL_ANALOG);   // Tüm AN girişleri analog 
   enable_interrupts(INT_AD);     // AD çevrimi bitti kesmesi tanıtılıyor
   enable_interrupts(GLOBAL);     // Tüm kesmeler aktif
  
   
  
   
   while(true)
   {  
       int16 adc_degeri,y;
       float voltaj,x;
       float k1=0.5,k2=0.67,k3=0.74,k4=0.83,k5=0.9;
      
      set_adc_channel(5);
      delay_us(20);
      adc_degeri=read_adc();
      voltaj=(float) (adc_degeri*5)/255;
      
     
  if((voltaj>=0) && (voltaj<1))
      {
         x=k1*voltaj;
         
         
      }
      else if((voltaj>=1) && (voltaj<2))
      {
         x=k2*voltaj;
         
      }
    
      else if((voltaj>=2) && (voltaj<3))
      {
         x=k3*voltaj;
         
      }
      else if((voltaj>=3) && (voltaj<4))
      {
         x=k4*voltaj;
         
      }
       else if((voltaj>=4) && (voltaj<5))
      {
         x=k5*voltaj;
         
      }
      else if(5<voltaj)
      {
         x=5*k5;
         
      }
         y=x*255/5;
         output_b(y);
}
}