2 tane DC analog bilgiyi PİC te okuma

Başlatan okay57, 12 Aralık 2014, 20:17:53

okay57

İki tane doğru akım değerim var.Bu değerleri pic le ölçmek istiyorum.Bir kaç denemem oldu ama An0 ve AN1 E aynı anda dc gerilim uyguladığımda AN0 doğru değerinde ölçerken ama AN1 i 4,97VOLT olarak ölçüyorum. bir de şunu denedim AN0 A ac gerilim değeri uyguladığımda ise AN1 doğru değeri ölçüyorum sanki iki tane dc değer olduğunda ikinci analog giriş 5V a çekiliyor NEDEN?

ismailhtc

 Kodlarda problem vardır büyük ihtimal. Eklersen daha yardımcı olunabilir.

okay57

program kodlarını nasıl göndedirim

mesaj birleştirme:: 12 Aralık 2014, 20:49:19

kopyala yapıştırla satır atlıyor

ismailhtc

kod ekle işareti var onu kullandın mı ? "#"  olan işaret

okay57

#include <18F4550.h>
#device ADC=10  // 10 bitlik ADC kullanılacağı belirtiliyor.

#fuses HSPLL,USBDIV,PLL5,PUT,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP,NODEBUG,NOMCLR // 20MHZ CPUDIV1 çalışma frekansı içindir.96/2=48MHz dir.CPUDIV2 olsaydı 96/3=32MHz olurdu

#use delay(clock=48000000)

#define USB_HID_DEVICE     TRUE             
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT 
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT    
#define USB_EP1_TX_SIZE    64                 
#define USB_EP1_RX_SIZE    64 

#define use_portb_lcd TRUE //LCD B portuna bağlı
#include <lcd_drver.c>
#include <math.h>
#include <stdio.h>
#include <pic18_usb.h>     
#include <Usb_Driver.h>                //USB konfigurasyon bilgileri bu dosyadadır.
#include <usb.c>

#use fast_io(a)
//#use fast_io(b)
//#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#define UcNokta1       1 
#define gelen       gelen_paket[0]

   
int8 gelen_paket[64];
unsigned int8 giden_paket[64];         

//===ADC değişkenleri
unsigned long int bilgi; 
float Gerilim,Akim,Guc,maxU,maxI=0;           
const long ornekI = 10;
const long ornekU = 10;
 long n=0;
 int8 m=0; 
unsigned int UTam,UOnda,ITam,IOnda=0;

unsigned int16 U,I=0;



 //========Gerilim bilgisi============//
void germax()
 {
  while(1)
       {
       if(input(pin_a2)==0)  //ac gerilim sinyalin sıfırdan geçtiği an
          {
          maxU=0;
                  for(n=0; n<ornekU; ++n)     
                  {
                  set_adc_channel(0);  
                  delay_us(20);         
                  bilgi=read_adc();     
                  if(bilgi>maxU) maxU=bilgi;            
                  }
 
           maxU*=(70.993311*0.00508);           

           return;
            }
       }
 } 
void akimmax()
 {
  while(1)
       {
      if(input(pin_a4)==0)  
          {
           maxI=0;
                  for(n=0; n<ornekI; ++n)     
                  {
                  set_adc_channel(1);   
                  delay_us(20);         
                  bilgi=read_adc();     
                  if(bilgi>maxI) maxI=bilgi;            
                  }
           maxI*=(0.00508);

           return;
            }
       }
 } 



void main ()
{
setup_psp(PSP_DISABLED) ;        
setup_spi(SPI_SS_DISABLED) ;     
setup_timer_1(T1_DISABLED) ;     
setup_CCP1(CCP_OFF) ;         
setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);                 
/////////======ADC========//

setup_adc(adc_clock_div_32);  
setup_adc_ports(AN0_TO_AN1|VSS_VREF);   



///////////////==============PWM======//
   setup_ccp2(CCP_PWM); 
 

   setup_timer_2(T2_DIV_BY_16,240,1);

    set_pwm2_duty(m); 




set_tris_a(0x1F);
set_tris_e(0xFF);

set_tris_d(0x00);
output_a(0x00);
output_e(0x00);

output_d(0x00);

usb_init();                         //USB donanımını hazırlar.  
usb_task();                         //PIC PC'ye USB ile bağlandığında, USB aygıt hazır duruma getirilir                   
usb_wait_for_enumeration();         //Cihaz, hazır olana kadar bekle

lcd_init();
while(1)
   { 
 
   while(usb_enumerated())
      {

      



      
      if (usb_kbhit(1))             //Eğer pc'den yeni bir paket geldiyse
         {         
            usb_get_packet(UcNokta1, gelen_paket, 64); //paketi oku  
          
            if(gelen==1) //
             {
               output_d(gelen_paket[1]);
             }
             
             
           }  
          
           
           U=maxU*100;
           UTam=U/100;
           UOnda=U%100;    //virgülden sonraki iki hane almak için kullanıldı.
           giden_paket[1]=UTam;
           giden_paket[2]=UOnda;
           
           I=maxI*100;
           ITam=I/100;
           IOnda=I%100;    //virgülden sonraki iki hane almak için kullanıldı.
           giden_paket[3]=ITam;
           giden_paket[4]=IOnda;
           
           
           
           usb_put_packet(UcNokta1, giden_paket,64, USB_DTS_TOGGLE); // Datayı Gönder..
           //output_low(pin_a2);

           delay_ms(2000);
          
    
       }     //usb_enumerated
   }      //while(1)
   
}

ismailhtc

bi hata göremedim ya. bunu donanımsal olarak mı denenidiniz yoksa isiste simülasyon mu yaptınız.

okay57

#6
donanımsal olarak denedim.devremi anlatayım şebeke gerilim ve akım sinyallerini akım ve gerilim sensörlerinden geçirdim. akım sinyal çıkışını opampla yükseltip rc devreyle doğrulttum ve picin AN1 girişine verdim.GErilim sinyal çıkışını yükseltmedim çünkü 2,5 volt değerindeydi gerek görmedim.Gerilimi de rc devreyle doğrulttum ve picin AN0 ucuna uyguladım.Bu durumda AN0 normalken AN1 girişi 5 volt olarak ölçüyorum.Şu şekilde yaptığımda ise hata yok. GErilimi doğrultmadan sinüs olarak AN0 a uyguladım ve 400 tane örnek alarak maksimum bulma yöntemiyle doğru değeri ölçtüm.Acaba ikisi DC iken neden AN1 5 Volta çekiyor.birde şunu denedim akımı AN0 a gerilime AN1 e uyguladığımda ise AN0 5VOLt  gözüküyor AN1 normal değerinde gözüküyor.
void germax()
 {
  while(1)
       {
       if(input(pin_a2)==0)  //ac gerilim sinyalin sıfırdan geçtiği an
          {
          maxU=0;
                  for(n=0; n<ornekU; ++n)     
                  {
                  set_adc_channel(0);  
                  delay_us(20);         
                  bilgi=read_adc();     
                  if(bilgi>maxU) maxU=bilgi;            
                  }
 
           maxU*=(70.993311*0.00508);           

           return;
            }
       }
 } 
void akimmax()
 {
  while(1)
       {
      if(input(pin_a4)==0)  
          {
           maxI=0;
                  for(n=0; n<ornekI; ++n)     
                  {
                  set_adc_channel(1);   
                  delay_us(20);         
                  bilgi=read_adc();     
                  if(bilgi>maxI) maxI=bilgi;            
                  }
           maxI*=(0.00508);

           return;
            }
       }
 }

Sanki hangi Analog giriş önce kullanıldığında o normal gözüküyor sonra kullanılan ise 5 volt olarak gözüyor. ama sinüste niye normal oluyor herşey.Bu da acaba sinüs sinyali 1saniyede 50 kere 0volt olduğundan dolayım mı herşey normal gözüküyor.

mesaj birleştirme:: 12 Aralık 2014, 22:09:25

isiste denediğimde hiç bir sıkıntı yok.

mesaj birleştirme:: 12 Aralık 2014, 22:24:04

adc kesmesinde kaynaklı olabilir mi 
kesmeyi kapatmam gerekiyormuydu
;
disable_interrupts(GLOBAL): // bunu kullanmadım

ismailhtc

#7
Hocam ikiside dc iken akım hangi analog pindeyse o pin 5 volta çekiyor anladığım. akım tarafında bi problem olabilir mi?  çünkü kodlarda bana sıkıntı yokmuş gibi geldi. voltaj ac iken okuduğunuzda ise bir problem yok. sebebini çözemedim. ama  bende bi watmetre yapmaya çalışıyorum. hafta sonu basacam devremi. ben ac olarak ölçecem akım ve gerilim ikisinide. sizin yaptığınız gibi dc ye çevirip de deneyebilirim. sağlıklı çalışırsa paylaşırım zaten.


kesme aktif değil zaten. yinede bi deneyin.

okay57

#8
önce ac sinyali ölçtüm çalıştı ama akım ölçü aletinden okunan değerden çok farklıydı 400 tane örnek alarak maksimmum değğeri bulup değeri okuyordum.Siz nasıl yapacaksınız

mesaj birleştirme:: 13 Aralık 2014, 00:04:02

ac sinyalle.Hatalı ölçüm yaptığımdan dolayı da dc ye çevirmeyi denedim.sadece akım ölçümünde sıkıntı yok ama işin içine gerilim girince böyle oluyor

okay57

 akım için opamp yükselteç ve paralel rc zener diyot doğrultucu devre ile gerilim için  paralel rc zener diyot doğrultucu devresi aynı kart üzerinde  yaptım çıkıştaki doğru gerilimleri picteki AN0 VE AN1 pinlerine uyguladım.Acaba bu neden olabilir mi?

okay57

arkadaşlar sorunu buldum ama çözemiyorum. sorun şu hangi analog girişle(AN0) ilk önce işlem yapılıyorsa doğru ölçüm yapılıyor ikinci yer alan analog giriş(AN1) kendini otomatik olarak 5volta çekiyor.Sorun yazılımsal görünüyor ama ne yapmam gerekiyor

Kabil ATICI

Sanırım olay başka bir kanala anahtarlandığı zaman belli bir zaman geçmesi gerekiyor. İç örnekle tut kondansatörünün şarjı ile ilgili birşey.
Ya bu zamanı beklemeyeceksin,ya da kanalı değiştirdiğin zaman 2 kez o kanalı okutacasın ve 2. sonucu kullanacaksın. (burada bekleme süresine yeteceği konusunda kuşkularım var)
ambar7

okay57

adc ile okuma yaparken 20usn gecikme kullanarak adc modülündeki kondansatörün şarjını bekledim acaba bu süre yeterli değil mi? şunu da belirteyim sürekli AN2 DE 5 volt sabit gözüküyor gerilim akım okuma arasına bir gecikme koysam...

Kabil ATICI

Alıntı yapılan: okay57 - 15 Aralık 2014, 18:19:11
arkadaşlar sorunu buldum ama çözemiyorum. sorun şu hangi analog girişle(AN0) ilk önce işlem yapılıyorsa doğru ölçüm yapılıyor ikinci yer alan analog giriş(AN1) kendini otomatik olarak 5volta çekiyor.Sorun yazılımsal görünüyor ama ne yapmam gerekiyor
Yukarıda belirttiğin gibi.
Bu nedenle  AN2'i 2.5V veya başka bir gerilim okuyacak şekilde düzenleyip o şekilde deneme şansın var mı? Emin olmak açısından...
ambar7

okay57

AN2 Yİ KULLANIYORUM AMA ANALOG GİRİŞ OLARAK DEĞİL 1 Mİ DEĞİL Mİ DİYE BİR SİNYALİ SORGULATIYORUM.AMA BUNU İPTAL EDİP ANALOG BİR SİNYAL ÖLÇMEYİ DENEYECEĞİM. DEVREMDE ŞUNU DA DENEDİM ACABA SİNYALİMDE Mİ SIKINTI VAR DİYE AN1 DE BAŞKA BİR SİNYAL OKUTMAYA ÇALIŞTIM( HARİCİ BİR AYARLI GÜÇ KAYNAĞI) ONDA DA 5 VOLTA ÇEKTİ