acs712 hakkında

Başlatan ~ENES~, 14 Şubat 2015, 17:28:40

~ENES~

arkadaşlar uzun zamandır aklımı kurcalayan bir konu ac akımın pic ile ölçülmesi konusu... 220 vac yi pic ile rahatlıkla okuyabiliyorum fakat ac akım ölçümüne sıra gelince orda bocalıyorum bu konuyla alakalı allegro firmasının ACS712 isimli sensörünü aldım fakat ac aakımda cok dalgalanma yapıyor analog çıkışı kullandığım dil pıc basıc ac akım ölçmenin başka yöntemleri varmı veya bu sensörü nasıl kullanabilirim ? kullanan varsa kısaca kullanım mantığını anlatırsa sevinirim.. yardımlarınız için şimdiden teşekkürler...
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

ete

AC de akım ölçmek belalı bir iştir. Belası sinüs işaretinin şeklinden kaynaklanır.
Sıfır geçiş noktasında 0V olan AC kaynağı, gittikçe yükselerek tepe değerine ulaşır ve sonra yine yavaş yavaş alçalarak tekrar sıfır noktasına gelir. Bu aralıkta yaptığın ölçümlerde voltajın seyrine bağlı olarak iner çıkar. Aslında Voltaj ölçümünde de aynı sorun yaşanır. Bu nedenle RSM (Root Mean Square) denilen sistem ile ölçümler yapılarak voltajın gerçek değeri hesaplanmış olur.
Bu hesap da Ölçülen voltajların ortalamasının karekök 2 ye bölünmesi ile yapılıyor. Bunun akım versiyonunu uygularsan belki sonuca ulaşırsın ama nasıl onuda ben bilemiyorum.
Bu işle ilgili bazı özel entegreler olduğunu biliyorum. Bana kalırsa özel entegre araştır.

Ete

~ENES~

bildiğiniz entegre önerebilir misiniz hocam ? peki siz başka bir yöntemle akım ölçümü yaptıysanız onun mantığınıda anlatırsanız sevinirim benim için teknik farketmez stabil çalışması önemli..
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

Mucit23

ACS712 Bu işte iyidir. Hemde nispeten ucuzdur. RMS ölçüm yapmadanda defalarca AC ve DC ölçüm yaptım. Fakat  hatasız ölçümler isteniyorsa TRUE RMS şart.

AC akım ölçerken benim kullandığım yöntem ise şöyle.

50Hz için biliyorsunuzki frekansın peryodu 20ms dir. 20ms içerisinde sabit aralıklarla örnekler alıp(1ms aralıklarla 20 örnek veya 100us aralıklarla 200 örnek) bu örnekler içerisinden en küçük değeri ve en yüksek değeri bulmaya çalışıyorum. Bu bulduğum değerler benim AC sinyalimin negatif ve pozitif tepe noktaları oluyor. Sonrasında bu değerlerin mutlağını alıp topladıktan sonra ortalamasını alıyorum. Bu şekilde ortalama bir tepe değer buluyorum. Tepe değeri bulduktan sonra 0.707 ile çarparak efektif değeri buluyorum.

Bu yöntemle 100ma'in altında hata payı ile ölçüm yapabiliyorum.

Tabi TRUE RMS olsa çok hassas olur sistem.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

#4
Aşağıdaki linkte verilen devre güzel çalışıyor. Çıkışı pic ölçerek sonucu ekranda görebilirsin.

Ete

http://danyk.cz/wmetr_en.html

~ENES~

Ete hocam tesekkur ederim bu devre işimi görür sanirim .. Mucit rms olarak sinusün tepe değerinden mi bahsediyorsun ? Bunlari dizi değişkeni ile mi ortalama yi aliyosun ? Bildiğim kadarıyla basicde mutlak değer yok .. Nasil bir mantik kurdun merak ettim doğrusu ?
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

Mucit23

Sinüsün tepe değerini buluyorum. 1 perot için pozitif ve negatif alternans tan oluşan iki adet tepe değeri var. Bunları bulup bir değişkene yerleştiriyorum. Elimde iki adet tepe değeri var fakat bir tanesi negatif. Doğrudan toplarsam birbirini sıfırlarlar. Bu yüzden Negatif alternansın mutlak değerini alıp pozitif alternansla topluyorum. Sonra bu değeri 2 ye bölüp ortalama bir tepe değer buluyorum. Bundan sonra geriye oran kurmak kalıyor.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

~ENES~

mutlak değer nasıl alıyosun pıc basıcde anlamadığım nokta burası gerisini anladım..
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

Mucit23

Benim kendi yaptığım AC DC ampermetrenin kodlarını vereyim.

#include <16F877.h>

#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(clock=10000000)

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

#include <lcd_driver.c>
#include <stdlib.h>

float akim=0,toplam=0,ort=0;
signed int16 data1=0,data2=0,data3;
int i=0;
int1 mode=0;

signed int16 calc_ort_adc(void);

void main()
{
   set_tris_a(0x01);
   set_tris_b(0x00);
   set_tris_c(0x00);
   set_tris_d(0x00);
   set_tris_e(0x07);
   
   output_a(0x00);
   output_b(0x00);
   output_c(0x00);
   output_d(0x00);
   output_e(0x00);
   
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);   
   setup_spi(SPI_DISABLED);
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0); 
   
   lcd_init();
   printf(lcd_putc,"\f");
   lcd_gotoxy(1,1);
   printf(lcd_putc,"AC-DC AKIM OLCER");
   while(TRUE)
   {
      if(!input(pin_e2))
      {
       mode=1-mode;
       while(!input(pin_e2)){}
      }
     
      if(mode) //AC ölçüm yapılıyor.
      {
          data2=0;data1=0,data3=0;
          for(i=0;i<20;i++)
          {
             data2=calc_ort_adc(); //Örnek Al
             if(data1<data2)data1=data2; //Max Değeri bul. data1, pozitif alternansın teğe değeri
             if(data3>data2)data3=data2; //Min Değeri bul. data3, negatif alternansın teğe değeri
             delay_ms(1); 
          }
         
          ort=(data1+abs(data3))/2;  //Ortalama tepe değer bulunuyor

          akim =(float)(ort*20)/395;   //Akım hesaplanıyor
         
          lcd_gotoxy(1,2);
          printf(lcd_putc,"AC AKIM :%fA  ",akim*0.707);//Tepe değer 0.707 ile çarpılıp ekrana efektif değer olarak yazılıyor.
      }
      else
      {
          toplam=0;data1=0;
          for(i=0;i<20;i++)
          {
         
            data1=calc_ort_adc();
            if(data1>=-5 && data1<=5)
            {
              toplam=0;
            }
            else
            {
              toplam+=data1;
            }
            delay_ms(1);
          }
          toplam=(float)toplam/20;
          if(toplam<0)
          {
            akim=(float)((toplam*20)/405.3);
          }
          else
          {
            akim=(float)((toplam*20)/405.2);
          } 
          lcd_gotoxy(1,2);
          printf(lcd_putc,"DC AKIM :%fA  ",akim);
      }
      delay_ms(100);
   }

}

signed int16 calc_ort_adc(void)
{
  int i=0;
  signed int16 total=0;
 
  for(i=0;i<20;i++)
  {
    set_adc_channel(0);
    delay_us(20);
    total+=read_adc()-511;
  }
  total=total/20;

  return total;
}


ACS712'de  2.5V luk ofset gerilimi var. Normalde ACS üzerinden akım akmıyorken sensör 2.5V gerilim üretir. Yani ACS denakım akmıyorken adc bize yaklaşık 511 civarı bir değer verir.
Ben tepe değer hesabına vs girmeden önce ADC den okuduğum değerden 511 çıkarıyorum. Dolayısıyla ADC 0-5V arasını 0-1023 arasına oranlarken artık 0-5V arasını -511 ile +511 arasına oranlıyor.

Akım akmıyorken ADC den 0 değerini okuyorum. Gelen değerin işareti akımın yönünü gelen değerin büyüklüğü ise akımın şiddetini gösteriyor.

Bundan sonra alternatif akım için daha önce anlattığım olaylar geçekleşiyor. Tepe değer bulma ortalama alma vs vs.

ABS fonksiyonu PicBasicde de var fakat negatif sayı tanımlama bildiğim kadarıyla doğrudan yok. Ama Negatif sayının mantığı basittir.

Örneğin 8 bitlik bir işaretli tam sayı -127 ile +127 arasında değişir. Sayının negatif olduğunu tanımlanan değişkenin en yüksek değerlikli biti belirtir. Yani 8 bitlik bir değişkende 8 bit 1 ise sayı negatiftir diyebiliriz. Geriye kalan 7 bit ise -127 ile +127 bir kullanım sunar.

Aynısı 16bit içinde geçerli. 16.bit işaret bitidir.  Geri kalan 15 bit ile -32767 ile +32767 arası bir kullanım söz konusudur.

PicBasicde ABS fonksiyonu için şöyle bir açıklama mevcut.
Alıntı Yap4.17.4. ABS

ABS returns the absolute value of a number. If a byte is greater than 127 (high bit set), ABS will return 256 - value. If a word is greater than 32767 (high bit set), ABS will return 65536 - value.

   B1 = ABS B0

Diyorki gelen değişkenin değeri 127'den büyükse yani 8. bit 1 ise ABS fonksiyonu fonksiyon içerisine gelen değeri 256 dan çıkartıp geri gönderir.
16 Bit içinde aynı durum var. Eğerki fonksiyon içerisine gelen değer 32767'den büyükse Gelen değeri 65536 çıkartıp geri gönderir.

Negatif sayıların mantığı bundan ibaret. Bunu anlarsan benim C de verdiğim kodu çok rahat bir şekilde Basic'de yazarsın.
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

ete

ACS712 çıkışı ABS kullanımı için iyi bir örnektir.
Normalde hiç akım çekilmiyor iken sensör çıkışı 2,5V dur. Bunun ADC karşılığı (HAM=) 511 dir.
Şayet pozitif yönde bir akım çekerseniz sensör çıkışı 2,5V-5V arasında bir çıkış verir (HAM=511-1023)
Şayet ters yönde akım okursanız sensör çıkışı 0-2,5V arasında bir çıkış verir (HAM=0-511)
AKımın ne yönde çekileceği belli değil ise (Mesela bir H-Koprü ile motor sürüyorsanız ve motorun bir kolunda sensör bağlı ise motor bir yöne dönerken pozitif yöne akım çekilir, diğer yöne dönerkende negatif yönde akım çekilmiş olacaktır) ya bir kaç if satırı ile önce okunan HAM değerin 511 den büyükmü yoksa küçükmü olduğunu bulacak sonrada duruma göre formülü değiştireceksiniz. Halbuki bu işi ABS kullanarak hiç if kullanmadan yapmak mümkün. HAM=ABS(HAM-511) şeklinde bir komut size her konumda HAM değerini pozitif olarak verecektir. HAM değeri 511 den küçük se 511-HAM, büyük ise HAM-511 uygulayarak size sonucu hep doğru verir.

Ete

~ENES~

Hocam çok güzel anlatmişsiniz mantigi kavradim gerisi programa dökmek kaliyor tesekkur ederim .. Ferhat kardeşim sanada ilgin için çok tesekkur ederim ..şu c diline bi isinabilsem ona geçmeyi düşünüyorum ama ete hocam basic dilini öyle bir aşilamiski bırakmak kolay olmuyor sende hatirlarsin o dönemleri :)
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

~ENES~

ete hocam

denemeleri yaptım fakat algoritma yanlış veya ortalama alma olayını çözemiyorum sensör saçma bir deger gösteriyor.. nerede hata yapıyorum yardımcı olabilir misiniz...program ektedir
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

ete

Çok güzel anlatmıştım ama hiç birisini uygulamamışsın.
Bir defa deneme devrende sensör yok. İsis de bu sensör yer almaktadır koyup da deneme yapmak daha güzel değilmi?

Her neyse, Ne söyledik bu sensörden hiç akım çekilmediği zaman (yani boşta) sensör OUT pinind 2,5V okursun.
Bu sana HAM ADC değeri olarak 511 verir.
Sen buna 1 eklersen ki bu 1 senin toleransın olacak. 512 değerini bulursun. Akımın hangi yönde aktığını bilmediğimiz için ABS komutunu kullanmamız gerektiğini belirtmiştim.
Bu durumda şayet 5A lik sensör kullanıyor isen 0-511 arası yada 512-1023 arası değer sana 0-5A lik akımı verecektir.
Bu durumda 5/512*256=2,5 gibi bir sabit çarpan verir. Bunu 25 kabul ederiz ve sonucu /10 böleriz yada bölmeyiz bize ondalık değeride vermiş olur.
O halde SONUC=(ABS(512-HAM))*/25 şeklinde hesaplarız. Bu hesaın sonucu 5 A için 50 olarak hesaplanacaktır.
Dolayısyla 10 a bölersen tam sayı kısmını Mod 10 alırsan ondalıkkısmını bulmuş olursun.

Ete

~ENES~

Hocam bu kismi anladim yani ABS komutunun kullanimini ... Anlamadigim nokta birkaç ornek alip ortalama alma mevzusu .. Kafamda kurabilsem algoritmayı gerisi gelecek ama ortalamayi nasil alip yapacagiz ? Dizi değişkeni kullanmak gerekiyor galiba ? Ne şekilde kullanmam gerekiyor ortalama yi nasil alirim hocam burayi anlatirsaniz sevinirim çok tesekkur ederim ilginiz için ...
ALLAH'a teslim olmuş bir insan ! Ne sultan tanir , ne sadrazam !

ete

Toplam=0  (Toplam Word değişkeni)
For I=0 to 19
  ADCIN 0,HAM
  TOPLAM=TOPLAM+HAM
  Pauseus 50
Next
HAM=TOPLAM/20

Ete

Powered by EzPortal