Picproje Elektronik Sitesi

DERLEYİCİLER => Microchip XC Serisi => Microchip XC8 => Konuyu başlatan: PICaso - 23 Kasım 2020, 18:33:29

Başlık: AC 220V Okuma
Gönderen: PICaso - 23 Kasım 2020, 18:33:29
Arkadaşlar merhaba,

Pic18f45K22 ile şebeke gerilimini okuyup lcd ye yazmak istiyorum. Fakat lcd ye yazdığım değer 200v-240V arasında

sürekli değişiyor. Kodda ne gibi değişiklikler yapabilirim? Herkese kolay gelsin.

#include "config.h"
#include "lcd_16x2.h"

uint32_t led_timestamp 0;
static 
uint8_t led_state FALSE;

uint32_t adcUpdate_timestamp 0;

char lcd_msg[LCD_BUFFER_LEN] = { };
#define ADC_BUFFER_LENGTH   40u
uint16_t adc_data[ADC_BUFFER_LENGTH] = {0};
uint8_t adc_data_index 0;

void main()
{
  
// Select 16MHz Internal Oscillator
  
OSCCONbits.IRCF 0x07;             // From 1MHz to 16MHz
  
InitTimer0 ();
  
LCD_Init ();
  
// Configure ADC
  
ANSELAbits.ANSA0 1;     // Disable the Digital Input Buffer on AN0
  
TRISAbits.RA0 1;        // AN0 as Input Pin
  
  
ADCON1bits.PVCFG 0x00;  // +Vref = AVDD
  
ADCON1bits.NVCFG 0x00;  // -Vref = AVSS
  
  
ADCON2bits.ADFM 0x01;   // Right Justified
  
ADCON2bits.ACQT 0x01;   // 2TAD
  
ADCON2bits.ADCS 0x05;   // FOSC/16
  
  
ADCON0bits.CHS 0x00;    // AN0 Selected
  
ADCON0bits.ADON 1;      // Enable ADC
  
  
sprintf (lcd_msg"    Embedded");
  
LCD_Print_Line (0lcd_msg);
  
sprintf lcd_msg"AC RMS = %dV"0u);
  
LCD_Print_Line (1lcd_msg);
  
LCD_Update ();
  while(
1)
  {    
     
sprintf lcd_msg" VOLTAJ  OLCUMU ");
     
LCD_Print_Line (0lcd_msg); 
     
LCD_Update ();
     
    
    
// ADC Update Task
    
if( millis() - adcUpdate_timestamp >= 1u )
    {
      
uint32_t ac_value 0;
      
adcUpdate_timestamp millis ();
      
      
ADCON0bits.CHS 0x00;    // AN0 Selected
      
ADCON0bits.GODONE 1;  // Start Conversion
      
while(ADCON0bits.GO == 1);
      
uint8_t adc_lo ADRESL;
      
uint8_t adc_hi ADRESH;
      
adc_data[adc_data_index] =  (uint16_t)(adc_hi << 8) | (uint16_t)adc_lo;
      
adc_data_index++;
      if( 
adc_data_index >= ADC_BUFFER_LENGTH )
      {
        
adc_data_index 0u;
        
// Time to Process and Display Data
        
uint32_t adc_filter_val 0;
        
uint16_t adc_buf_local 0;
        for( 
uint8_t i=0i<ADC_BUFFER_LENGTHi++ )
        {
          
adc_buf_local adc_data[i];
          
adc_filter_val += ((uint32_t)(adc_buf_local*(uint32_t)adc_buf_local ));
        }
        
// 625*625 = 390625
        // 128*128 = 16384
        // 625^2 / 128^2 = 23.8414
        
adc_filter_val = (uint32_t)((float)adc_filter_val 23.84);
        
adc_filter_val /= ADC_BUFFER_LENGTH;      // mean squared sum
        
adc_filter_val *= 2;   
        
ac_value = (uint16_t)sqrt(adc_filter_val);// root mean square
        
ac_value *= 68u;
        
ac_value /= 1000u;
        
       
sprintf lcd_msg"AC RMS = %luV"ac_value);  
        
LCD_Print_Line (1lcd_msg);
        
LCD_Update();
        
       
      }
    }
  }
}
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 23 Kasım 2020, 18:41:36
(https://i.ibb.co/ckLpBL9/5-D1-B2392-1-F91-4833-9260-5-DA9-A3-CD790-E.png) (https://ibb.co/ckLpBL9)
Başlık: Ynt: AC 220V Okuma
Gönderen: M.Salim GÜLLÜCE - 23 Kasım 2020, 18:58:18
Kullandığın devrede sıkıntı war.
-Bir kere kapasitör kullanmazsan 0 +230 arası tüm değerleri görürsün
Kapasitör kullandığında da deşarj olabilmeli.
Kısacası kurgun yanlış.
-ikincisi kurduğun devre senin çarpılma riskinide getirir.
Zira şebekeden gelen faz ile nötr kazara yer değiştirse devrenin tamamı yüksek voltaja bağlanmış olur.

Mümkünse trafo kullan.
yada optik veya galvanik izolasyon kullan.
Yüksek empedans girişli (10-50 MOhm gibi) bir fark amplifikatörü ile bağlanmaya çalış.
Şurada paylaştığım devre sana fikir verebilir.
Benzer şeylerde paylaşmıştım forumda aramanı tavsiye ederim.
https://www.picproje.org/index.php/topic,78254.msg601150.html#msg601150 (https://www.picproje.org/index.php/topic,78254.msg601150.html#msg601150)
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 23 Kasım 2020, 19:53:10
Alıntı yapılan: Mehmet Salim GÜLLÜCE - 23 Kasım 2020, 18:58:18Kullandığın devrede sıkıntı war.
-Bir kere kapasitör kullanmazsan 0 +230 arası tüm değerleri görürsün
Kapasitör kullandığında da deşarj olabilmeli.
Kısacası kurgun yanlış.
-ikincisi kurduğun devre senin çarpılma riskinide getirir.
Zira şebekeden gelen faz ile nötr kazara yer değiştirse devrenin tamamı yüksek voltaja bağlanmış olur.

Mümkünse trafo kullan.
yada optik veya galvanik izolasyon kullan.
Yüksek empedans girişli (10-50 MOhm gibi) bir fark amplifikatörü ile bağlanmaya çalış.
Şurada paylaştığım devre sana fikir verebilir.
Benzer şeylerde paylaşmıştım forumda aramanı tavsiye ederim.
https://www.picproje.org/index.php/topic,78254.msg601150.html#msg601150 (https://www.picproje.org/index.php/topic,78254.msg601150.html#msg601150)

hocam trafo kullanmayı düşünmüyorum. proteusda program gayet güzel çalışıyor. Dediğiniz fişin takılma yönü önemli. AC

 nin 1 alternansını kullanarak, gerilim bölücüyle bu işi yapmak imkansız mıdır?
Başlık: Ynt: AC 220V Okuma
Gönderen: elektro77 - 23 Kasım 2020, 20:07:06
bir multimetre de nasıl ölçülüyor ac voltaj? inceleyip uygulayabilirsiniz. Piyasa da endüstriyel bir sürü pano tipi ac ölçen cihazlar var çoğunda trafo kullanılmıyor. Onlara da bakabilirsiniz.
Başlık: Ynt: AC 220V Okuma
Gönderen: M.Salim GÜLLÜCE - 23 Kasım 2020, 22:13:45
Alıntı yapılan: PICaso - 23 Kasım 2020, 19:53:10hocam trafo kullanmayı düşünmüyorum. proteusda program gayet güzel çalışıyor. Dediğiniz fişin takılma yönü önemli. AC

 nin 1 alternansını kullanarak, gerilim bölücüyle bu işi yapmak imkansız mıdır?
Verdiğim linkteki devre alternans falan dinlemez iki giriş ucu arasındaki gerilim farkına bakar.
Çıkışındaki Opamp İntegral şeklinde revize edilip RMS DC ye dönüştürüldüğünde istediğini elde etmiş olursun.
İstersen 2000 volt ölç (Giriş dirençleri o voltaja dayanıklı olması şartı ile) farketmez ondan sonra.
(https://i.ibb.co/F3N5VhK/resim.png)
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 24 Kasım 2020, 13:08:45
Alıntı yapılan: Mehmet Salim GÜLLÜCE - 23 Kasım 2020, 22:13:45Verdiğim linkteki devre alternans falan dinlemez iki giriş ucu arasındaki gerilim farkına bakar.
Çıkışındaki Opamp İntegral şeklinde revize edilip RMS DC ye dönüştürüldüğünde istediğini elde etmiş olursun.
İstersen 2000 volt ölç (Giriş dirençleri o voltaja dayanıklı olması şartı ile) farketmez ondan sonra.
(https://i.ibb.co/F3N5VhK/resim.png)
Hocam AC voltaj rms değeri azaldığı ya da arttığı durumlarda opamp çıkışı da lineer olarak değişir mi?

TS954 yerine kullanabileceğim muadil entegre neler olabilir?
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 24 Kasım 2020, 14:51:25
LM358 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.

(https://i.ibb.co/25Bw1dH/Whats-App-Image-2020-11-24-at-11-47-46.jpg) (https://ibb.co/6N527FL)

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.
Başlık: Ynt: AC 220V Okuma
Gönderen: Proteus - 24 Kasım 2020, 15:27:18
Kolay gelsin,

https://tr.aliexpress.com/item/33004868114.html

Diğer opamplı devreler ile aynı , en büyük farkı trafo ile izolasyon olması,

Kolay gelsin
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 24 Kasım 2020, 16:36:48
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.

(https://i.ibb.co/25Bw1dH/Whats-App-Image-2020-11-24-at-11-47-46.jpg) (https://ibb.co/6N527FL)

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 True RMS ile ilgili bir tecrübem olmadı. Pic 18f45k22 ile yapılabilir mi?
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 24 Kasım 2020, 17:01:35
tabi ki çok basit...
Başlık: Ynt: AC 220V Okuma
Gönderen: mehmet - 24 Kasım 2020, 17:50:59
ZC dan sonraki 90° de adc okuma yapabilirsiniz.
Buna göre de istediğiniz işlem yapılabilir...
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 24 Kasım 2020, 18:29:47
Alıntı yapılan: mehmet - 24 Kasım 2020, 17:50:59ZC dan sonraki 90° de adc okuma yapabilirsiniz.
Buna göre de istediğiniz işlem yapılabilir...
True RMS konusu ile yapmaya çalışacağım. Dediğiniz gibi ZC yi algılayıp, 5ms timer başlatıp, timer sonunda ADC ile peak voltajı okumakta mantıklı.
Başlık: Ynt: AC 220V Okuma
Gönderen: ACM - 24 Kasım 2020, 19:46:46
Alıntı yapılan: mehmet - 24 Kasım 2020, 17:50:59ZC dan sonraki 90° de adc okuma yapabilirsiniz.
Buna göre de istediğiniz işlem yapılabilir...

Erol hocamın devresi  sıfır geçişide yakalıyor yani ? Hemde direkt 220V girişle. Süüüüper , kopyala hemen.
Başlık: Ynt: AC 220V Okuma
Gönderen: selimkoc - 25 Kasım 2020, 00:25:44
Zero Crossing Detector için dahili komparatörler kullanılabilir.

https://elektrokod.wordpress.com/2020/01/17/dahili-karsilastiricili-dijital-dimmer-dimmer-with-built-in-comparator/ (https://elektrokod.wordpress.com/2020/01/17/dahili-karsilastiricili-dijital-dimmer-dimmer-with-built-in-comparator/)

https://elektrokod.wordpress.com/2020/01/20/arduino-ile-dimmer-uygulamasi/ (https://elektrokod.wordpress.com/2020/01/20/arduino-ile-dimmer-uygulamasi/)
Başlık: Ynt: AC 220V Okuma
Gönderen: M.Salim GÜLLÜCE - 25 Kasım 2020, 03:00:39
MCU ile şebeke okumada negatif tarafları görmek için Offset uygulamanız gerekir.
aksi takdirde 360 Dercelik bir periyottaki negatif tarafın tamamını sıfır olarak okursunuz.
Aradaki boşluğu yazılımla tamamlamak ne kadar sağlıklı olur o da tartışılır.
Zira okuyacağınız her zaman şebeke olmak zorunda değil.
Çok özel rezonans devresi yada farklı frekanstaki inverter de olabilir.
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 25 Kasım 2020, 03:22:53
Aslında şebekenin frekansı belli ise (misal 50 Hz) sıfır geçişlerine pek ihtiyacımız yok.

1 periyot = 20mS, birkaç tam periyotluk zaman içerisinde ADC ile TRUE RMS için Sample dizisi toplayabiliriz.
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 25 Kasım 2020, 12:23:53
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.

(https://i.ibb.co/25Bw1dH/Whats-App-Image-2020-11-24-at-11-47-46.jpg) (https://ibb.co/6N527FL)

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.
(https://i.ibb.co/7jSvMsW/7-C74-D808-191-C-44-EB-B23-A-51-BA81-E6098-B.jpg) (https://ibb.co/7jSvMsW)
Hocam çıkış sinyalim bu şekilde. 3k yerine 3,3k direnç kullandım. Bu nedenle mi negatif alternans farklı olmuş?
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 25 Kasım 2020, 12:40:48
Çıkışında sinus dalga olması lazım,,, aynı 220V şebekenin küçültülmüş bir örneği.

Bağlantılarda bi yanlışlık yapmış olabilirsin.

(https://i.ibb.co/pQgGVPC/2020-11-25-10h17-27.png) (https://ibb.co/BGmdWP8)
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 25 Kasım 2020, 14:06:09
Alıntı yapılan: Erol YILMAZ - 25 Kasım 2020, 12:40:48Bağlantılarda bi yanlışlık yapmış olabilirsin.

(https://i.ibb.co/pQgGVPC/2020-11-25-10h17-27.png) (https://ibb.co/BGmdWP8)

Evet hocam tl431 in katot ile ref uçlarını kısa devre etmemişim.
(https://i.ibb.co/nrCZH0w/B5-A92-A66-0934-48-C3-AD1-E-60-E2-FDA6-DE0-B.jpg) (https://ibb.co/nrCZH0w)
Şimdi bu sinyali pic in Adc pinine girerek 500us de bir okuma yapıp bunu bir diziye atacağım. Gerekli hesaplamalar ile lcd ye 220V yazdıracağım doğru mudur?
Başlık: Ynt: AC 220V Okuma
Gönderen: tunayk - 25 Kasım 2020, 14:33:39
500uS bir peryotta 40 örnek yapar. Bu ölçüm biraz kaba kalabilir.
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 25 Kasım 2020, 14:43:51
Alıntı yapılan: PICaso - 25 Kasım 2020, 14:06:09Şimdi bu sinyali pic in Adc pinine girerek 500us de bir okuma yapıp bunu bir diziye atacağım. Gerekli hesaplamalar ile lcd ye 220V yazdıracağım doğru mudur?

Opamp çıkış sinyalin 0'a düşmemiş,
Çıkış ile şase arasına 1K5 direnç bağlar mısın?
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 25 Kasım 2020, 15:03:40
Alıntı yapılan: Erol YILMAZ - 25 Kasım 2020, 14:43:51Opamp çıkış sinyalin 0'a düşmemiş,
Çıkış ile şase arasına 1K5 direnç bağlar mısın?

(https://i.ibb.co/7NVwDzf/948328-CB-4550-4-E92-BA12-9-F224932365-B.jpg) (https://ibb.co/7NVwDzf)
İşlemcinin 5V eksisi ile 12V eksiyi ortaklayınca düzeldi.
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 25 Kasım 2020, 15:04:32
Alıntı yapılan: tunayk - 25 Kasım 2020, 14:33:39500uS bir peryotta 40 örnek yapar. Bu ölçüm biraz kaba kalabilir.
1 periyotta kaç örnek almalıyım sizce?
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 02 Aralık 2020, 12:59:25
Arkadaşlar programın algoritmasını şöyle düşünüyorum. 100us lik Timer0 kurup, sonsuz döngüde her timer0 bayrağı 1 olunca

ADC yapıp, 200 elemanlı bir dizi oluşturmak. Bu elemanların karelerini alıp ortalama değerini bulmak. Bulduğum değerin

karekönü almak. Bu yaklaşım doğru mudur?
Başlık: Ynt: AC 220V Okuma
Gönderen: fahri- - 02 Aralık 2020, 13:08:42
Konu şebeke voltajı ise,
Örnek sinüsün tepe değerini okuyup kök 2 ye bölmek daha kolay değil mi?
Sinüsün tepe değeri için basit 1 diyod 1 opamplı devreler var.
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 02 Aralık 2020, 13:10:49
Alıntı yapılan: fahri- - 02 Aralık 2020, 13:08:42Konu şebeke voltajı ise,
Örnek sinüsün tepe değerini okuyup kök 2 ye bölmek daha kolay değil mi?
Sinüsün tepe değeri için basit 1 diyod 1 opamplı devreler var.
Tecrübe edinmek için true rms metodunu kullanmak istiyorum.
Başlık: Ynt: AC 220V Okuma
Gönderen: Proteus - 02 Aralık 2020, 13:42:07
Kolay gelsin,

for(i=0i<=20i++)
                      {
vADC_Read(1);
=(v-511.0)*(10.0/1023.0);

/*t[i]= v;*/
                      
}

ADCON0.ADON=0;
max=t[0];
/*for(i=0; i<=20; i++)    {

      if(max<t[i])
          max=t[i];

                        }
max=max*0.707106781;
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 02 Aralık 2020, 13:49:17
Alıntı yapılan: Proteus - 02 Aralık 2020, 13:42:07Kolay gelsin,

for(i=0i<=20i++)
                      {
vADC_Read(1);
=(v-511.0)*(10.0/1023.0);

/*t[i]= v;*/
                      
}

ADCON0.ADON=0;
max=t[0];
/*for(i=0; i<=20; i++)    {

      if(max<t[i])
          max=t[i];

                        }
max=max*0.707106781;
Hocam bu true rms için mi?
Başlık: Ynt: AC 220V Okuma
Gönderen: Proteus - 02 Aralık 2020, 14:07:31
TrueRMS 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:
(https://i.ibb.co/GJMhm6F/rms.png) (https://ibb.co/GJMhm6F)

VTRMS:
(https://i.ibb.co/fkSt6z7/truerms.png) (https://ibb.co/fkSt6z7)

VTRMS Kod ornegi:
(https://i.ibb.co/VMQDy1j/vtrms.png) (https://ibb.co/VMQDy1j)

Eğer keskin bir ölçüm yapacaksan VTRMS yapacaksın harmonik bindi mi sisteme sapıtır.
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 02 Aralık 2020, 15:07:47
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:
(https://i.ibb.co/GJMhm6F/rms.png) (https://ibb.co/GJMhm6F)

VTRMS:
(https://i.ibb.co/fkSt6z7/truerms.png) (https://ibb.co/fkSt6z7)

VTRMS Kod ornegi:
(https://i.ibb.co/VMQDy1j/vtrms.png) (https://ibb.co/VMQDy1j)

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?
Başlık: Ynt: AC 220V Okuma
Gönderen: Proteus - 02 Aralık 2020, 18:28:22
Eşit olarak bölebilirsin kaç us ise okadar illa 1024 almana da gerek yok
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 02 Aralık 2020, 18:45:18
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?
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 07 Aralık 2020, 13:17:55
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.

(https://i.ibb.co/25Bw1dH/Whats-App-Image-2020-11-24-at-11-47-46.jpg) (https://ibb.co/6N527FL)

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?
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 07 Aralık 2020, 14:35:30
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.
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 23 Mart 2021, 14:47:26
(https://i.ibb.co/9Gm6HF5/52245-F03-38-B7-4-B78-BDAD-685-D2-FDB57-C0.jpg) (https://ibb.co/9Gm6HF5)

(https://i.ibb.co/YyFSC0p/FA316-FCC-5680-4-C31-ACD1-69-D90-B42-F779.jpg) (https://ibb.co/YyFSC0p)

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);
    }         
}
Başlık: Ynt: AC 220V Okuma
Gönderen: ipek - 23 Mart 2021, 15:45:46
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..
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 23 Mart 2021, 16:09:55
Şebeke voltajı ölçeceğim hocam. Yüksek frekanslar değil yani.
Başlık: Ynt: AC 220V Okuma
Gönderen: Erol YILMAZ - 23 Mart 2021, 16:12:35
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)
}
Başlık: Ynt: AC 220V Okuma
Gönderen: PICaso - 23 Mart 2021, 16:54:38
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.