acs712-20 ile ilgili sorun ?

Başlatan bulut_01, 01 Temmuz 2018, 15:18:22

bulut_01

iyi günler picproje ailesi elimde acs712-20 sensor ile AC akım ölçmeye calısıyorum stabıl ölçüm yapamıyorum kod asagıdakı gıbı hatam nerde sizce? akım degeri cok geziniyor

#int_TIMER1
void  TIMER1_isr(void)
{
set_timer1(0);                                                //100 ms kurulu 
ADCBuf[i]=read_adc();
delay_us(10);
if(++i==20){
adc_flag=1;        //akım hesabı yapılıyor
}}
///////////////////////////
if(adc_flag==1){
                                                              //akım hesabı***
i=0;
  do
  {
    i++;
  }while(i<20);
  adc_toplam=0;
 for(i=0;i<20;i++)
  {
    if(ADCBuf[i]>512) adc_val = ADCBuf[i] -512 ;
    else adc_val = ADCBuf[i];
    adc_toplam += adc_val*adc_val;
  }
  rsm_voltage = sqrt ((float) adc_toplam/20.0 )*4.88;
  amper=rsm_voltage;                                    //ekrana akım degerı basılıyor
adc_flag=0;
YENİLMEZ..

devrecii

Daha önce tartışmıştık  https://www.picproje.org/index.php?topic=71464.75

Orada  stm32f103 kullanılıyordu  (adc 1Msps!),   pic mi kullanıyorsun ? Eğer pic kullanıyorsan (yeni pic serileri hariç) o hızlara ulaşman imkansız, bence direnç ve opamp filter ile işi bitir. 

bulut_01

mesele  hız değilde algorıtmada hata var gıbı
YENİLMEZ..

devrecii

100ms demişsin o nedenle, her adc ölçümü kaç ms sürüyor ?  50hz ac her peryot  20ms dir . Peryota göre senkronize edemezssen kafaya göre farklı farklı değerler okursun .


"if(++i==20)"  20 tane toplam almışsın bunu artırmalısın  tabi hafıza lazım var mı ?  Artırabilirsen   "adc_toplam" bu 32bit integer olsun

Bu gereksiz

i=0;
  do
  {
    i++;
  }while(i<20);

bulut_01

bu algorıtmaya göre 1 ms ölcum suresı sekronıze edemedıgımden farklı degerler okuyorum sanırım
YENİLMEZ..

devrecii

#5
1ms fena değil, senkronze etmesen bile  iyi olmasa da ölçüm alabilmen gerekir. Bunun için çok sayıda ölçüm al (tabi hafıza varsa)

20 tane ölçüm almışsın bunu artırmalısın 200 hatta 2000.

if(++i==200){
adc_flag=1;        //akım hesabı yapılıyor
}}
///////////////////////////
if(adc_flag==1){

  adc_toplam=0;
 for(i=0;i<200;i++)
  {
    if(ADCBuf>512) adc_val = ADCBuf -512 ;
    else adc_val = ADCBuf;
    adc_toplam += adc_val*adc_val;
  }
  rsm_voltage = sqrt ((float) adc_toplam/200.0 )*4.88;
  amper=rsm_voltage;
 adc_flag=0;
 }


bulut_01

iboibo üstad bu sekılde senın yazdıgın kod calısmıyor.


#int_TIMER1
void  TIMER1_isr(void)
{
set_timer1(64120);                                        //1 ms kurulu  adc***
ADCBuf[i]=read_adc();
delay_us(10);
if(++i==200){
adc_flag=1;}}

/////////////////////////////////
if(adc_flag==1){
i=0;
  adc_toplam=0;
 for(i=0;i<200;i++)
  {
    if(ADCBuf>512) adc_val = ADCBuf -512 ;
    else adc_val = ADCBuf;
    adc_toplam += adc_val*adc_val;
  }
  rsm_voltage = sqrt ((float) adc_toplam/200.0 )*4.88;
  amper=rsm_voltage; 
 adc_flag=0;
 }
YENİLMEZ..

devrecii

Dostum sende calışan kodda değişiklikler yap , ilk önce 20 olan yerleri  40  .. 50  .. 200 .. artır (kaç tane adc okunduğu)

Daha sonra ms zamanını değiştir denemeler yap.


bulut_01

mesele timer alakalı 1ms delay adc flag döngüsünün içine koyunca calışıyor kod ama timer 1ms kuru olması rahmen timer içine adc okudugumda koddaki gibi çalışmıyor mesele 20 örnek 200 örnek meselesi değil.
YENİLMEZ..

devrecii

#9
2ms, 3ms,  4 ms  yine çalışmıyor mu  min çalışma hızı nedir bulsana.


timer1_isr fonksiyonunu bu şekilde değiştirmisin,  timer in hızını main.c de ayarlamıyormusun

Picleri bilmiyorum benim yorumlamam bu kadar ;D  ;D

void  TIMER1_isr(void)
 {
 disable_interrupts(INT_TIMER1);                                     
 ADCBuf=read_adc();
 delay_us(10);
 if(++i>=200){ adc_flag=1; } ///
 enable_interrupts(INT_TIMER1);
 }






OptimusPrime

 ::)
Kafayi duvara vuran bir emoji olsa onu kullanacaktim. Bana calistirdim demistin. :o

//==================================================================================
// Sample voltage
//==================================================================================
		i=0;
		do
		{
			TMR2=9;
			TMR2IF=0;
			
			GO_DONE=1;
			while(GO_DONE==1);
			wVoltageSample=ADRESH;
			wVoltageSample<<=8;
			wVoltageSample|=ADRESL;			

			wVoltage[i]=wVoltageSample;

			while(TMR2IF==0);
			TMR2IF=0;	
		
			//RB1^=1;
			i++;
		}while(i<SAMPLES_IN_A_PERIOD); 

//==================================================================================
// Calculate Vrms
//==================================================================================
		fVrms=0;
		for(i=0; i<SAMPLES_IN_A_PERIOD; i++) fVrms=fVrms+((float)wVoltage[i]-512.0)*((float)wVoltage[i]-512.0);
		fVrms=fVrms/(float)SAMPLES_IN_A_PERIOD;
		fVrms=sqrt(fVrms);
		fVrms=(fVrms/1024.0)*5.0;
		fVrms=fVrms*VOLTAGE_SCALE_FACTOR;

timer2 yi oyle bir ayarlaki 1ms yede bir tassin. RB1^=1; gibi bir pini toggle ederek surelerini scope ile olc.

timer2 kesmesini acip kafani iyece karistirma. Yukaridaki ornek senin isini gorur.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

bulut_01

yücel abi bende kafamı duvara vuruyum azıcık 😂
YENİLMEZ..