help me Why my Digital filter doesn't operate

Status
Not open for further replies.

hbaocr

Full Member level 4
Joined
May 13, 2007
Messages
232
Helped
25
Reputation
48
Reaction score
4
Trophy points
1,298
Location
Hochiminh City university of technology (VietNam)
Activity points
2,765
here the LOW Pass filter code with NUM and DEN designed by matlab (sptool) that fsample=1KHZ;Fc=40Hz;ButterWorth IIR filter

#define pi acos(-1)
double Numerator[]={0.00018321602337,0.000732864093479,0.001099296140218,0.000732864093479,0.00018321602337};

double Denominator[]={1,-3.344067837711875,4.238863950884069,-2.409342856586321,0.517478199788041};

Code:
void CVedothiDlg::Low_pass_filter(double *NUM,double *DEN,double *sample,double data_update,double *output,unsigned int length_output_data)
{

	unsigned char i;

	sample[4] =sample[3];
	sample[3] =sample[2];
	sample[2] =sample[1];
	sample[1] =sample[0];
	sample[0]=data_update;
	//buffer output
	for(i=length_output_data;i>0;i--)
	{
		output[i]=output[i-1];
	}
	
	//update output data
	output[0]=NUM[0]*sample[0]+NUM[1]*sample[1]+NUM[2]*sample[2]+NUM[3]*sample[3]+NUM[4]*sample[4]-DEN[1]*output[1]-DEN[2]*output[2]-DEN[3]*output[3]-DEN[4]*output[4];

}
and then In the main program,the input data is

Code:
void CVedothiDlg::OnPlot() 
{
	// TODO: Add your control notification handler code here
	int i;
	DOUBLE y[1000];
	DOUBLE x[4];
	DOUBLE data;
	for(i=0;i<1000;i++)
	{
		data=sin(2*pi*i/1000)+sin(2*pi*500*i/1000);
		Low_pass_filter(Numerator,Denominator,x,data,y,1000);
		Scope.Channels[0].Data.SetYData(y,1000) ;//draw signal output
	}

	
}
why it doesn't work????
Do anyone help me to make the filter work
 

There are trivial C programming issues, I think. I would generally suggest to trace program execution with a debugger to check for plausible operation.

One point is that in an expression as 2*pi*500*i/1000 the compiler is free to define the order of execution to its needs, thus an integer expressions 500*i and 500*i/1000 may be executed first. One would possibly cause overflow, if integer is 16 (you didn't tell about the enviroement), the other truncation anyway. Writing (500.0f*i) or (float)i would guarantee correct execution.

The oher point is, that local variables in a function are generally uninitialized in C, so your filter storage elements contain arbitrary valuesa t the beginning.

Finally, I don't know how the Scope component works, if it's used correct with the y output vector.
 

There is obvious buffer overflow :
You use sample[4] but size of array x is four so allowed index is 0,1,2,3 but not 4.
Also I think Scope.Channels[0].Data.SetYData(y,1000) ;//draw signal output
should be after for loop to speed up execution.
 

FvM, the C expression 2*pi*500*i/1000 is equivalent to (((2*pi)*500)*i)/1000.
If 'pi' is a double, then everything gets promoted to double, so there's no risk of dividing two integers.
 

Kernighan/Ritchie says, that a compiler is free to reorder * or + operators in an expression. Also, * and / have equal priority. I don't see a rule that would forbid to evaluate i/1000 first. It could be, that VC6 has additional self-defined constraints to provide more clarity to programmers.
 

K&R2 section A.7.6 says, "The multiplicative operators *, /, and % group left-to-right."

You may be thinking of this statement from K&R2 section 2.12:
"C, like most languages, does not specify the order in which the operands of an operator are evaluated."
That's a different issue.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…