PIC16 tabanlı digital alçak geçiren fiitre

Başlatan PROTECH_, 15 Kasım 2009, 01:19:48

PROTECH_

Merhabalar arkadaşlar,
Bir kaç ay önce bir projemde ADC den alınınan verilerin işlenmesi ile alakalı bir projem olmuştu. Fakat veriler aşırı gürültülü olarak  alınıyordu bende, bunu gidermek için fazla yer ve süre almayan bir digital filitre geliştireyim dedim sonuçta böyle bir proje çıktı,

Yaklaşık  frekans zayıflaması ile alakalı formul, kod kısmında yer almaktadır. adc ile alakalı projelerinizde tavsiye ederim.
Özellikle sıcaklık ölçümü, pot, vb. ölçümler için ideal.
pic16 serisi için uygulanabilir olması bu seri ile çalışanlar için, iyi bir kolaylık olacağını düşünüyorum  :!:

kolay gelsin


kaynak kodları (HI-TECH C )

/************************************************** 	
	PROJECT NAME	: FAST DIGITAL LOW PASS FILTER 
   	AUTHOR 			: PROTECH
   	DATE			: 14/10/09  		
    COMPILER		:HI-TECH C LITE,(EASY TO IMPLEMENT WITH ASSEMBLER)   
    
    
	BASIC ATTENUATION CALCULATING FORMULA:
    
    >>AdB=20*Log[1/( t_sample*6 * F_input) X 1/n ]   

	>> - t_sample = ADC conversion time 
  	>> - n        = filterin coefficient
  	
  	 
****************************************************/

#include <pic.h>
__CONFIG(WDTDIS);

#define LED	RC1				// SİSTEM CALIŞIYOR LED'İ

void adf(void);        		// ADC KONFÜGRASYON FONK.      
void interrupt isr(void);	// KESME RUTİNİ

static unsigned char n[]={0,0,0,0,0,0,0,0}; // 8. DERECEDEN FILITRE DIZISI(8 ADET)

static unsigned char HIGH;
static unsigned int sum;					// TOPLAM DEĞİŞKENİ	

// ANA FONKSIYON
void main(void) 
{

	
	adf();									// ADC AYARLA

while(1)									// SONSUZ DÖNGÜ	
{	
	TRISC=0X00;								// LED'I YAK
    LED=1;										
	
} 
	 
}


//8bit-ADC konfügrasyon fonksiyonu    
void adf(void)       		
{
	ADCON0=0b10000001;		 
	//ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE — ADON
	// T-örnek=OSC/32  
	//(alcak geçiren filitre olduğu için örnekleme süresini uzun tutmak
	// program işleyişi açısından daha uygun)  
	
	
	ADCON1=0b00001110;		// PORT AYARLARI
	//ADFM — — — PCFG3 PCFG2 PCFG1 PCFG0
	
	ADIE=PEIE=1; 			//ADC INTERUPT ETKİN
	TRISB=0X00;				//PORTB CIKIŞ
	TRISA= TRISA||0b00000001;//RA0 GİRİŞ
		ei();				// İNTERRUPT AKTİF
		GODONE=1;           // ADC AKTİF
	

}
//KESME FONKSIYONU
void interrupt isr(void)
{
	if(ADIE&&ADIF)
	{ 
		// alçak geçiren digital filitre başlangıcı 
		 n[7]=n[6];   		//HER DEFASINDA ÖRNEKLERI BIR SONRAKI
		 n[6]=n[5];         // DEĞİŞKENE KAYDIR  YENİ ALINAN ÖRNEĞİ DİZİNİN  
	     n[5]=n[4];         // İLK ELEMANINA YÜKLE 
	     n[4]=n[3];          
	     n[3]=n[2];
	     n[2]=n[1];
	     n[1]=n[0];
	     n[0]=ADRESH;		//   N[7]<=....N[1]<=N[0]<=ADRESH 
	    
	    sum=n[7]+n[6]+n[5]+n[4]+n[3]+n[2]+n[1]+n[0];   
	    
	    
	 PORTB=(unsigned char)(sum>>3);
	     
	    //8. DERECEDEN FILITRELEME ISLEMI TAMAM
	    
	    ADIF=0;   
	    GODONE=1;
	  	}
}
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

teknikelektronikci

merhaba paylasim icin tesekürler

simdi ben projeyi anlamadim analog girise uygulanan gürültülü sinyali  formüle göre düzenleyip dijital analog dönüstürücü ile tekrar analog sinyale mi cevirioyor portb cikisi sanirim merdiven tipi dac oluyor birde o gürültülü sinyali isis de nasil yaptiniz yazabilirmisiniz rica etsem tesekürler
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

PROTECH_

@teknikelektronikci
  hocam sistemi kavramışsınız, dışarıdan gelen gürültülü veri sinyali adc den alınarak dijital'e çevriliyor. Ve dijitale çevrilen her yeni adc değeri  anlık olarak filitreden geçiriliyor. Daha sonra gürültüsü giderilmiş sinyal portb ile DAC den dışarı veriliyor.

Normalde filitrenin amacı sadece alıp filitreleyip dışarıya vermek değil,
sinyal filitrelendikten sonra istediğiniz gibi o sinyal üzerinde sağlıklı olarak işlemler yapabilmek, böylece kurmuş olduğunuz sistem daha verimli ve sağlıklı bir şekilde çalışır.

ISIS te gürültülü sinyal oluşturmak için sadece ana sinyal üzerine daha yüksek frekansta başka bir sinyal bindiriyorsunuz.

mesela yukarıdaki örnekte  ana sinüs sinyali 2V, 200Hz lik bir sinyaldi
Gürültü sinyali ise 0.5V, 1800Hz lik bir sinyal.

Kolay gelsin..
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

teknikelektronikci

Alıntı yapılan: "PROTECH_"@teknikelektronikci
  hocam sistemi kavramışsınız, dışarıdan gelen gürültülü veri sinyali adc den alınarak dijital'e çevriliyor. Ve dijitale çevrilen her yeni adc değeri  anlık olarak filitreden geçiriliyor. Daha sonra gürültüsü giderilmiş sinyal portb ile DAC den dışarı veriliyor.

Normalde filitrenin amacı sadece alıp filitreleyip dışarıya vermek değil,
sinyal filitrelendikten sonra istediğiniz gibi o sinyal üzerinde sağlıklı olarak işlemler yapabilmek, böylece kurmuş olduğunuz sistem daha verimli ve sağlıklı bir şekilde çalışır.

ISIS te gürültülü sinyal oluşturmak için sadece ana sinyal üzerine daha yüksek frekansta başka bir sinyal bindiriyorsunuz.

mesela yukarıdaki örnekte  ana sinüs sinyali 2V, 200Hz lik bir sinyaldi
Gürültü sinyali ise 0.5V, 1800Hz lik bir sinyal.

Kolay gelsin..


aciklama icin tesekürler güzel bir calisma olmuş
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

hasangurlek

Favorim : Donanımsal filtreler.

Sinyal 200 Hz, Gürültü 1 Volt / 10kHz

http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

94220039

Güzel bir paylaşım.

PROTECH_

Alıntı yapılan: "hasangurlek"Favorim : Donanımsal filtreler.

Sinyal 200 Hz, Gürültü 1 Volt / 10kHz

tabi hocam donanımsal filitreler bu işin temeli fakat dijital işlem yapacağım yerde neden giriş için extradan "opam+ kondansatör + direnc + pcbde yer kaplama "
parası verelimki?   8)

özelliklede seri üretim yapılan bir ürün ise mesela ekstradan  2$, 100 adet için 200$ yapıo nekadar az eleman o kadar kâr...
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

pro73

Teşekkürler Güzel paylaşım ama ben bu şemaları proteuse ta çalıştıramıyorum. Nasıl calıştıklarını anlatabilirmisiniz.

PROTECH_

Alıntı yapılan: "pro73"Teşekkürler Güzel paylaşım ama ben bu şemaları proteuse ta çalıştıramıyorum. Nasıl calıştıklarını anlatabilirmisiniz.

hangi kısmı ?
eğer bahsettiğin şey grafik simulasyonu ise, sadece ölçme noktalrına yerleştirdiğin ölçüm oklarını grafik alanına sürükleyip brakıyorsun, sonrada sağ tıklayıp simulate diyorsun, simulasyonunu yapıyor
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

pro73

teşekkür ederim grafik kısmını anladım,Sinyal kısmında
2v5 vermedeki amaç sinüs sinyalin -v den kurtulmakmıdır.

Maxim

protech hocam eline sağlık ,
yanlız hitech kullanmayan bizler için acaba bu kodu anlatırmısınız ,
daha doğrusu kodu değil formülü, basitçe .

örnek ,
adc girişini 6 kere örnek alıyoruz ,
bu 6 örneği birbiriyle çarpıyoruz ,
sonra bunların log unu alıyoruz içine biraz tuz katıyoruz vs vs

teşekkürler tekrardan .

hasangurlek

Alıntı yapılan: "PROTECH_"tabi hocam donanımsal filitreler bu işin temeli fakat dijital işlem yapacağım yerde neden giriş için extradan "opam+ kondansatör + direnc + pcbde yer kaplama "
parası verelimki?   8)

özelliklede seri üretim yapılan bir ürün ise mesela ekstradan  2$, 100 adet için 200$ yapıo nekadar az eleman o kadar kâr...

Emin olun sizin şemadan daha az maliyetli olur ve daha az yer kaplar. Bir adet direnç / bir adet kondansatör = Pasif alçak geçirgen filtre yerlerini değiştirseniz yüksek geçirgen. Filtrelemeden emin olmak için op-amp ilave edilebilir. Dahada emin olunmak isteniyorsa (tıbbi uygulamalar, görüntü işleme gibi) filtrenin büküm sayısı 32 ye kadar, hatta PC uygulamalarında daha fazla sayıda artırılabilir.

Sizin şemada op-amp (-) girişine bir prob atıp, analizin grafik çıktısını paylaşabilirmisiniz ?

Birde AdB=20*Log[1/( t_sample*6 * F_input) X 1/n ] bu işlemi yazılımda göremedim.

Görebildiğim kadarıyla yazılım 8 ölçüm yapıp (sum=n[7]+n[6]+n[5]+n[4]+n[3]+n[2]+n[1]+n[0] ; ) sekize bölerek (PORTB=(unsigned char)(sum>>3); ) ortalama alıyor yani formül AD=n[0]+.....+n[7] / 8 oluyor. Bu formülü "average out" olarak biliyorum.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

hasangurlek

Alıntı yapılan: "pro73"teşekkür ederim grafik kısmını anladım,Sinyal kısmında
2v5 vermedeki amaç sinüs sinyalin -v den kurtulmakmıdır.

Alternatör özelliklerinde belirtilen voltaj değeri sinyalin tek yönlü tepe noktasını belirler. Dalgalanma ise tepe noktası x 2 olur. Alternatör girişine dışardan uygulanan voltaj ise sinyalin merkezini yani ofsetini belirliyor. Boş bırakılırsa veya 0 verilirse sinyal merkezi 0 volt kabul edilir. Dışardan 2.5 volt verildiğinde alternatör değeride 2 volt ise dalgalanma 0,5 ile 4,5 volt arasında olur.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

PROTECH_

@hasan_gurlek
Hocam galiba gözleden kaçırdığınız bir nokta var,
Bu devrenin amacı: PIC için  adc den alınan sinyalin gürültülerinden arındırılarak, PIC'in bu sinyal üzerinde sağlıklı bir şekilde çalışmasını sağlamak,(sinyali filitreleyip olduğu gibi dışarıya vermek değil! ). Yukarıdaki devre sadece sinyalin filitrelenmiş halini göstermek için hazırlandı.

@maxiboost

hocam kısaca şöyle


filitrenin ayrık zamandaki  formülü:


Y=filitre cıkışı değeri
X=filitre girişi değeri
n=filitre derecesi
a=adc den alınan örnek sırası

Hocam teorik anlatım genelde biraz kafa karıştırıyor ama yinede yazayım dedim.
Uygulama anlatımı daha anlaşılır :) :

Program RC filitre   mantığı ile işliyor,
ADC alınan her örnek kendisinden önceki n-1 tane örnek ile toplanıp
ortalamsı alınıyor ve yeni değer elde edilmiş oluyor

örnek:
4. dereceden bir filitre

adc den alınan örnekler sırasıyla  x1,x2,x3,x4,x5,x6,x7...
filitreden geçirilmiş         hali      y1,y2,y3,y4,y5,y6,y7...

mesela filitrelenmiş sinyalin 5.(y5) değerini ve 6.(y6) değerini bulalım
*(filitre derecesi 4 olduğu için kendisinden önceki 3 değer ile birlikte toplam 4 değer alınıyor)





bu işlemler her değer için sıra sıra yapılıyor olay bundan ibaret :)
Not="Bölme işlemindeki süre kaybını önlemek için filitre derecesi 2 nin katları seçilip elde edilen toplam değeri sağa kaydırılarak bir-iki cycle da bölme işlemi yapılabilir"

_________________

Frekansa bağlı sinyal zayıflaması formülü
(istenmeyen frekansların bastırılma miktarı):

AdB=20*Log[1/( t_sample*6 * F_input) X 1/n ]

AdB          = Frekansa bağlı sinyalin zayıflama katsayısı (dB olarak)
t_sample   = ADC örnekleme süresi (sn olarak)
F_input     = zayıflama miktarı hesaplanacak frekans(Hz olarak)
n              = filitre derecesi

kolay gelsin
Multi-Core ,RTX,ThreadX, FreeRTOS, MODBUS  RTOS - Electronic-Hardware -- BERLIN

Erol YILMAZ

@PROTECH_

Birçok uygulamada ADC kullanıyoruz.
ve bahsettiğin türden bir filtre özellikle displaye yansıyan ADC sonuçları var ise gerçekten çok işe yarıyor.

Donanım filtresi sinyali filtre etse de,
ADC nin kendi dönüşüm kıpırdanmalarını engelleyemiyor.  

Bu yüzden özellikle ADC ile biraz tanışmış arkadaşların bahsettiğin türden
filtre uygulaması yapmaları daha sonraki projeleri için çok faydalı
olacaktır.  

Paylaşımın için teşekkürler.