18 Eylül 2021, 20:25:49

Haberler:

Eposta uyarılarını yanıtlamayınız ( ! ) https://bit.ly/2J7yi0d


AC 220V Okuma

Başlatan PICaso, 23 Kasım 2020, 18:33:29

PICaso

Alıntı yapılan: Proteus - 02 Aralık 2020, 14:07:31TrueRMS farklı RMS Farklı aralarındaki en büyük fark birinin sadece sinüsün max. noktasını bulup 0,707 ile çarpması diğerinin ise örnekler alıp ortalamasını alıp daha keskin sonuç çıkarması.

VRMS:


VTRMS:


VTRMS Kod ornegi:


Eğer keskin bir ölçüm yapacaksan VTRMS yapacaksın harmonik bindi mi sisteme sapıtır.

Hocam kod örneğinde 1024 örnek alıyor ama bunu ne kadar sürede alıyor?

Proteus

Eşit olarak bölebilirsin kaç us ise okadar illa 1024 almana da gerek yok

PICaso

Hocam zaman kavramını kafamda tam olarak oturtamadım. 1000 örnek alıyorsam 20ms/1000 kadar bir timer mı kurmam

gerekiyor. Nasıl bir şart sağlandığın da adc yaptırmalıyım? kısaca açıklar mısınız?

PICaso

Alıntı yapılan: Erol YILMAZ - 24 Kasım 2020, 14:51:25LM358 veya LM324 kullanabilirsin.
Differantial amplifier yapısı endüstriyel elektronikte sıklıkla kullanılır.

Gerilim kazancı = 3K / (2x220K) olarak hesaplanır.
Çıkışın Ofset gerilimi 2.5v'tur.

Whats-App-Image-2020-11-24-at-11-47-46" border="0

Opampın Çıkışında 2.5V ofset gerilimine bindirilmiş 3/440 oranında zayıflatılmış girişteki AC sinyali göreceksin.
Bunu da ADC yardımıyla True RMS olarak okuyabilirsin.
Hocam bu devre ile voltaj okumayı başardım. Şimdi Frekansıda okumak istiyorum. Nasıl bir yol izlemeliyim?

Erol YILMAZ

Frekans için;
ADC'ye giden sinyal ile TL431'in 2.5v luk gerilimini COMPARATOR ile karşılaştırarak oluşturduğun kare dalganın  periyoduna bakabilirsin.

PICaso

23 Mart 2021, 14:47:26 #35 Son düzenlenme: 23 Mart 2021, 14:50:09 PICaso




Kare dalga sinyal ile picin capture fonksiyonu kullanarak şebeke frekansını ölçüyorum sorunsuz.
Sinüs ile de ADC voltajı ölçmeye çalışıyorum. Fakat lcd de ki değer 200-270 arasında geziyor. Yazılım kısmında hatalarım olduğunu düşünüyorum. Yardımlarınızı bekliyorum.

unsigned int sayici=0;
float frekans=0;
void __interrupt() kesme(void)
{
    if(
CCP1IF)
    {
        
CCP1IE=0;
        
TMR1H=0;
        
TMR1L=0;
        
sayici=(CCPR1H<<8)+CCPR1L;
    }
     
CCP1IE=1;
     
CCP1IF=0;      
}

void ADC_Init()
{    
    
TRISA 0xff;
	
	
/*Set as input port*/
    
ADCON1 0x07;  
	
	
/*Ref vtg is VDD & Configure pin as analog pin*/    
    
ADCON2 0x92;  
	
	
/*Right Justified, 4Tad and Fosc/32. */
    
ADRESH=0;  
	
	
	
/*Flush ADC output Register*/
    
ADRESL=0;   
}

int ADC_Read(int channel)
{
    
int digital;
    
ADCON0 =(ADCON0 0b11000011)|((channel<<2) & 0b00111100);
    
//*channel 0 is selected i.e.(CHS3CHS2CHS1CHS0=0000)& ADC is disabled
    
ADCON0 |= ((1<<ADON)|(1<<GO));//*Enable ADC and start conversion
    //*wait for End of conversion i.e. Go/done'=0 conversion completed
    
while(ADCON0bits.GO_nDONE == 1);
    
uint8_t adc_lo ADRESL;
    
uint8_t adc_hi ADRESH;
    
digital =  (uint16_t)(adc_hi << 8) | (uint16_t)adc_lo;
    return(
digital);
}

float RMS_value;
float RMS (){
    
int16_t i,t;
    
int32_t V1,V2;
    
V1=V2=0;
    for(
i=0;i<1000;i++)
    {
        
t=ADC_Read(0);
        
V1=V1+(int32_t)t*(int32_t)t;
        
V2=V2+(int32_t)t;
    }
    
RMS_value=sqrt(V1/1000.0-((V2/1000.0)*(V2/1000.0)));
    
RMS_value=((float)4.31)*((float)RMS_value);   //  220V icin 
    
return RMS_value;        
}

int deger1;
void main()
{    
    
char s[16];
    
    
TRISA 0xff;
    
TRISB 0x00//LCD BAGLANTILARI
    
TRISD 0x00
    
Lcd_Init(); /*Initialize 16x2 LCD*/
    
ADC_Init();
	
	
	
/*Initialize 10-bit ADC*/
    ///////FREKANS ICIN///////////////////////////////////////////////////////////// 
    
TRISC=0XFF;
    
GIE=1;
    
PEIE=1;
    
T1CON=0B11111001//bit4,5;1:8 Prescale value    
    
CCP1CON=0B00000101;    //Her yukselen kenarda okuma yapar   
    
PIE1bits.CCP1IE=1;
    
PIR1bits.CCP1IF=0;
    
TMR1H=0;
    
TMR1L=0;
    
CCPR1H=0;
    
CCPR1L=0;
//////////////////////////////////////////////////////////////////////////////// 

    
while(1)    
    {      
    if(
CCP1IF){
        
CCP1IE=0;
        
TMR1H=0;
        
TMR1L=0;
        
sayici=(CCPR1H<<8)+CCPR1L;     
    }
    
CCP1IE=1;
    
CCP1IF=0;    
    
frekans=625000/(float)sayici// 625000=20MHz/4*8 ,,,frekans floata çevrilir.           
    
    
RMS();
    
int toplam 0;
        for(
int j 0100j++) //100 farkli ADC de?erini okuruz.
    
{   toplam=toplam+RMS_value; }
        
deger1 toplam 100 ;   
        
    
sprintf(s"VOLTAJ FRQ OKUMA  " );
    
Lcd_Set_Cursor(1,1);
    
Lcd_Write_String(s);    
    
sprintf(s"V=%d   F=%.3f  ",deger1,frekans); 
    
Lcd_Set_Cursor(2,1);
    
Lcd_Write_String(s);
    }         
}

ipek

en baba counter'ler bile Sinus ölçmekte zorlanır.bir komparatör ile frekansı kare dalga formuna yaklaştırmalısınız. bu konuda terimler Comparator Slicer , Clock Shaper gibi frekans 10KHz'yi geçmiyorsa LM311 open Collector Comparator hatta LM555 bile olabilir.yinede frekans aralığınızı bilmek gerekir.

düşük frekanslar responce süresini uzatır,en kolay yöntemi Periyot ölçümüdür.

örnek ticari counterlerin çoğu düşük frekanslardaki iyileşme için Reciprocal Period dönüşümü yapar. bir mini örnek 64uS = 15625 Hz gibi.
muhakkak MCU ölçsün istiyorsanız bazı işlemcilerde Schmitt Trigger pin'i bulunmaktadır,bu pin'de bir çeşit wave shaping yapma kabiliyetine sahiptir..

PICaso

Şebeke voltajı ölçeceğim hocam. Yüksek frekanslar değil yani.

Erol YILMAZ

True RMS gerilim örneklerini 1 periyota yaymak gerekiyor...

for(i=0;i<1000;i++){
  
t=ADC_Read(0);
  
V1=V1+(int32_t)t*(int32_t)t;
  
V2=V2+(int32_t)t;
}

kodunu tahminen güncelleyelim...

50 Hz = 20mS
64 örnek alıcaksan 20ms / 64 = 312.5uS de 1 örnek alman gerekiyor.

for(i=0;i<64;i++){
  
t=ADC_Read(0);
  
V1=V1+(int32_t)t*(int32_t)t;
  
V2=V2+(int32_t)t;
  
delay_us(280)
}

PICaso

Alıntı yapılan: Erol YILMAZ - 23 Mart 2021, 16:12:35True RMS gerilim örneklerini 1 periyota yaymak gerekiyor...

for(i=0;i<1000;i++){
  
t=ADC_Read(0);
  
V1=V1+(int32_t)t*(int32_t)t;
  
V2=V2+(int32_t)t;
}

kodunu tahminen güncelleyelim...

50 Hz = 20mS
64 örnek alıcaksan 20ms / 64 = 312.5uS de 1 örnek alman gerekiyor.

for(i=0;i<64;i++){
  
t=ADC_Read(0);
  
V1=V1+(int32_t)t*(int32_t)t;
  
V2=V2+(int32_t)t;
  
delay_us(280)
}

Hocam bu şekilde düzenledim ama yine çalışmadı.
float RMS_value;
float RMS (){
    
int16_t i,t;
    
int32_t V1,V2;
    
V1=V2=0;
    
    for(
i=0;i<64;i++){
    
t=ADC_Read(0);
    
V1=V1+(int32_t)t*(int32_t)t;
    
V2=V2+(int32_t)t;
    
__delay_us(280);
    }
    
    
RMS_value=sqrt(V1/1000.0-((V2/1000.0)*(V2/1000.0)));
    
RMS_value=((float)4.31)*((float)RMS_value);   //  220V icin 
    
return RMS_value;        
}

280 us nereden geldi onu da anlamadım.

Yasal Uyarı: Picproje.org sitemizde 5651 sayılı kanunun 8. maddesine ve T.C.Knın 125. maddesine göre tüm üyelerimiz yaptıkları paylaşımlardan kendileri sorumludur. Picproje.org hakkında yapılacak tüm hukuksal şikayetleri İletişim sayfamızdan bize bildirdikten en geç 3 (üç) iş günü içerisinde ilgili kanunlar ve yönetmelikler çerçevesinde tarafımızca incelenerek gereken işlemler yapılacak ve site yöneticilerimiz tarafından bilgi verilecektir.