با سلام من میخوام با avr یک ولتمتر true rms بسازم یعنی نمیخوام ولتاژ را به dc تبدیل کنم میخوام از موج نمونه گیری کنم واز رابطه مقدارش را بدست بیارم برای اینکار بعد از نمونه گیری باید نمونه ها با هم جمع بشه بعد باید چه کار کرد کسی تا حالا ساخته؟ممنون میشم راهنمایی کنید
اطلاعیه
Collapse
No announcement yet.
ولت متر true rms
Collapse
X
-
پاسخ : ولت متر true rms
من قبلا انجامش دادم دقت نسبتا بالا لازم بود، با مقدار 1000 نمونه در 50 هرتز انجام داده شد (فرکانس نمونه گیری 50 کیلوهرتز)
البته مهمترین نکته شکل موج جریان است اگر شکل موج کاملا سینوسی باشد که اصلا احتیاجی به روش RMS نیست و با ضریب ساده ای عمل تبدیل انجام می شود پیک شکل موج جریان تقسیم بر جذر عدد 2 .
در غیر اینصورت فرکانس نمونه گیری طبق قضیه نایکویست باید حداقل 2 برار بیشترین فرکانس موجود در طیف فرکانسی موج مورد نظر باشد تا دقت لازم بدست آید .
دیدگاه
-
پاسخ : ولت متر true rms
نوشته اصلی توسط dr_mnfسلام .
البته همه چیز بستگی داره که چه مقدار دقت مورد نیازتون هست .
یه آی سی هست به نام AD736 که کارکردش جالب هست و لیون هم قبلاً داشت .
کارش همینه و اگر کاتالوگ رو بخونین دقت بالائی هم داره .
نوشته اصلی توسط jalal gilaniمن قبلا انجامش دادم دقت نسبتا بالا لازم بود، با مقدار 1000 نمونه در 50 هرتز انجام داده شد (فرکانس نمونه گیری 50 کیلوهرتز)
البته مهمترین نکته شکل موج جریان است اگر شکل موج کاملا سینوسی باشد که اصلا احتیاجی به روش RMS نیست و با ضریب ساده ای عمل تبدیل انجام می شود پیک شکل موج جریان تقسیم بر جذر عدد 2 .
در غیر اینصورت فرکانس نمونه گیری طبق قضیه نایکویست باید حداقل 2 برار بیشترین فرکانس موجود در طیف فرکانسی موج مورد نظر باشد تا دقت لازم بدست آید .
در غیر اینصورت فرکانس نمونه گیری طبق قضیه نایکویست باید حداقل 2 برار بیشترین فرکانس موجود در طیف فرکانسی موج مورد نظر باشد تا دقت لازم بدست آید .
از پاسخ شما ممنونم
دیدگاه
-
پاسخ : ولت متر true rms
من با ARM انجامش داده بودم ولی خب با AVR هم نباید خیلی متفاوت باشه فقط سرعت پایین تره که بسته به کاربردتون داره
نکته دیگه اینه که اگر با ADC داخلی AVR کار می کنید حداکثر فرکانس نمونه گیری 15 کیلو هرتز میشه که برای بیشتر کاربرد ها خوبه
در مورد طیف فرکانسی هم باید از روی FFT (بسط فوریه شکل موج) حداکثر فرکانس موجود رو بدست آورد یا اندازه گیری کرد.
فرکانس 50 کیلو هرتز رو هم با وقفه تایمر ایجاد کرده بودم که تبدیل ADC رو START می کرد
دیدگاه
-
پاسخ : ولت متر true rms
نوشته اصلی توسط jalal gilaniمن با ARM انجامش داده بودم ولی خب با AVR هم نباید خیلی متفاوت باشه فقط سرعت پایین تره که بسته به کاربردتون داره
نکته دیگه اینه که اگر با ADC داخلی AVR کار می کنید حداکثر فرکانس نمونه گیری 15 کیلو هرتز میشه که برای بیشتر کاربرد ها خوبه
در مورد طیف فرکانسی هم باید از روی FFT (بسط فوریه شکل موج) حداکثر فرکانس موجود رو بدست آورد یا اندازه گیری کرد.
فرکانس 50 کیلو هرتز رو هم با وقفه تایمر ایجاد کرده بودم که تبدیل ADC رو START می کرد
کد:[left] /***************************************************** This program was produced by the CodeWizardAVR V2.04.4a Advanced Automatic Program Generator © Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : Version : Date : 2/26/2012 Author : NeVaDa Company : Comments: Chip type : ATmega8 Program type : Application AVR Core Clock frequency: 8.000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/ #include <mega8.h> #include <delay.h> #include <stdio.h> #include <math.h> #include <stdlib.h> // Alphanumeric LCD Module functions #asm .equ __lcd_port=0x12 ;PORTD #endasm #include <lcd.h> bit fine_adc=0; unsigned char lcd_buff[60]; static unsigned long int adc_temp=0; unsigned long int adc_valu; static unsigned int n=0; unsigned long int temp; #define ADC_VREF_TYPE 0xC0 // ADC interrupt service routine interrupt [ADC_INT] void adc_isr(void) { unsigned int adc_data; // Read the AD conversion result if(fine_adc==0) { adc_temp+=ADCW; if(++n==1000) { fine_adc=1; // Place your code here } } } interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Place your code here TCNT0=235; //TCCR0=0x02; ADCSRA|=0x40; } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 1000.000 kHz TCCR0=0x02; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // ADC initialization // ADC Clock frequency: 62.500 kHz // ADC Voltage Reference: Int., cap. on AREF ADMUX=ADC_VREF_TYPE & 0xff; ADCSRA=0x8F; // LCD module initialization lcd_init(16); // Global enable interrupts #asm("sei") ADCSRA|=0x40; // lcd_gotoxy(0,0); // sprintf(lcd_buff,"V:%d ",temp); // lcd_puts(lcd_buff); while (1) { // Place your code here if(fine_adc==1) { n=0; adc_valu=adc_temp*adc_temp; temp=(adc_valu/1000); temp=sqrt(temp); temp=temp/204.8; lcd_gotoxy(0,0); sprintf(lcd_buff,"V:%d ",temp); lcd_puts(lcd_buff); adc_temp=0; fine_adc=0; }; } } [/left]
دیدگاه
-
پاسخ : ولت متر true rms
جناب زوار
در وقفه ADC باید به جای(adc_temp+=ADCWاین کد رو بنویسید :
adc_temp+=ADCW*ADCW
در برنامه اصلی این عبارت حذف می شود ( adc_valu=adc_temp*adc_temp
زمان بندی ها رو چک نکردم ولی با اطمینان میشه گفت که با هزار نمونه شما از چندین سیکل شکل موج نمونه گیری می کنید چون حداقل زمان تبدیل ADC در میکرو AVR حدود 65 میکروثانیه است البته این عمل در اندازه گیری تاثیری نخواهد داشت و مقدار محاسبه شده صحیح است .
زمان بندی تایمر را بررسی کنید تا در زمان های بیشتر از زمان تبدیل ADC به علاوه زمان اجرای زیر برنامه وقفه ADC ، وقفه بدهد در غیر اینصورت برنامه درست عمل نخواهد کرد .
در ضمن در برنامه وقفه ADC وقتی شمارنده n به 1000 رسید باید تایمر را متوقف کرده و بعد از محاسبه RMS در برنامه اصلی دوباره آن را فعال کنید تا دیتا در زمان محاسبه تغییر نکند.
دیدگاه
-
پاسخ : ولت متر true rms
نوشته اصلی توسط jalal gilaniدر ضمن فراموش کردم بپرسم
ولتاژ AC رو چطور به میکرو اعمال کردید برای اینکه ADC میکرو قابلیت خواندن مقادیر منفی را ندارد.
دیدگاه
-
پاسخ : ولت متر true rms
65 میکرو ثانیه رو کاریش نمیشه کرد محدودیت سرعت AVR هست تازه در بالاترین سرعت این مقدار خواهد بود
اگر از نیم سیکل استفاده کنید که دیگه True RMS معنی پیدا نمیکنه
برای خواندن تمام موج ساده ترین راه اینه که موج AC را با یک ولتاژ دقیق و ثابت DC جمع کنید (مثلا با 2.5 ولت) ابته به شرط اینکه پیک ولتاژ از 2.5 ولت بیشتر نباشد.
در این حالت مقدار صفر شیفت پیدا کرده و به مقدار 2.5 تبدیل می شود.
دیدگاه
دیدگاه