|
|
View previous topic :: View next topic |
Author |
Message |
Urgent Guest
|
band-stop filter mathematical equation |
Posted: Thu Oct 22, 2009 9:34 am |
|
|
Hi, all.
My project requires me to program a Butterworth band-stop filter using PIC C compiler. The Butterworth band-stop filter is to be embedded into a 18LF14K50 PIC.
The filter is used to filter a bang-bang torque input to control/reduce the vibration of a flexible manipulator.
Is there any example of band-stop filter code c program for my PIC available for me to refer?
How can I find the mathematical equation for the Butterworth band-stop filter to enable me to program it using PIC C compiler?
Any help would be greatly appreciated. Thx. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
|
Eoin87
Joined: 20 Oct 2009 Posts: 18
|
|
Posted: Thu Oct 22, 2009 2:27 pm |
|
|
You'll need to build an FIR filter, do some research on FIR filter structures. You will need to sample your analog signal adequately fast enough to satisfy Nyquists sampling theorem , that means sampling at a rate 2 times faster than your highest wanted input frequency.
Have a look for Scope FIR filter software, even the student version is excellent for simulating FIR filters.
All you need on the output of your PIC is a DAC to convert your signal back to the Analog domain. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Oct 22, 2009 4:42 pm |
|
|
Butterworth and similar low order filters can be typically realized as IIR filters which less effort. |
|
|
Urgent Guest
|
|
Posted: Thu Oct 22, 2009 8:18 pm |
|
|
Hi all, thx for the reply.
I've looked into wikipedia's Butterworth filter equation but only the transfer function equation is provided in it. I need the mathematical equation for the filter so that I can program it in c code.
I've downloaded the ScopeFIR software but I need examples in code C since I'm using PIC C compiler. Is there any available?
I'd like to find the mathematical equation for band-stop filter that is similar like the following equation which is for low pass filter:
y[t] = (x[t - 1] + x[t - 2] + x[t - 3] + x[t - 4])/4
which is shown in the low pass filter titled discussion in the ccsinfo forum.
Thx for any help provided. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Oct 23, 2009 1:25 am |
|
|
I think, the problem is, that you know nearly nothing about digital filters, so you don't understand the clear hints for filter implementaion provided e.g. with ScopeFIR. Your example is a trivial moving average filter, a kind of low-pass indeed, but with a sin(x)/x frequency response.
I don't know, if you're motivated to learn about digital filters or are just looking for a quick solution for a specific problem. For the latter, you may want to tell your filter specification (sampling frequency, center frequency, bandwidth, data bitwidth), so we can discuss, which filter implementation IIR/FIR is suitable. You should however consider the fact, that a bandstop also involves an oscillating step response. It's a good idea to simulate the filter behaviour before starting to code it. |
|
|
Kai
Joined: 22 Oct 2009 Posts: 1
|
|
Posted: Fri Oct 23, 2009 6:13 pm |
|
|
Hi, FvM,
You were right to say that I know nearly nothing about digital filters but please do help me to understand it more because I spent too much time searching for example code c program for band-stop filter.
I developed my Butterworth band-stop filter using the analog filter design block in MATLAB. After reading your thread, I found out that a digital filter should be developed if I want to proceed to the next step.
I have used two Butterworth analog band-stop filter to filter out my bang-bang torque input to lower two of the peak frequencies of a flexible manipulator. The two peak frequencies are lowered because they cause vibration to the flexible manipulator.
I have done the following:
Code: |
1st, I find the transfer function of the analog form,
Wn=[90 110]
>> [b,a]=butter(3,Wn,'stop','s')
b =
1.0e+011 *
0.0000 0 0.0000 0 0.0029 0 9.7030
a =
1.0e+011 *
0.0000 0.0000 0.0000 0.0000 0.0030 0.0392 9.7030
1/0.001
ans =
1000
Then, I change it into digital form, which is:
[bz,az]=impinvar(b,a,1000)
bz =
-0.0390 0.1923 -0.3790 0.3723 -0.1808 0.0332 0.0010
az =
1.0000 -5.9305 14.6840 -19.4292 14.4895 -5.7745 0.9608
The second band-stop filter in analog form:
>> Wn=[340 360]
Wn =
340 360
>> [b,a]=butter(3,Wn,'stop','s')
b =
1.0e+015 *
0.0000 0 0.0000 0 0.0000 0 1.8338
a =
1.0e+015 *
0.0000 0.0000 0.0000 0.0000 0.0000 0.0006 1.8338
and its digital form:
>> [bz,az]=impinvar(b,a,1000)
bz =
-0.0390 0.1815 -0.3461 0.3363 -0.1651 0.0314 0.0010
az =
1.0000 -5.5990 13.4097 -17.5502 13.2321 -5.4516 0.9608 |
I'm not sure about the fs needed.
Is it related to my bang-bang torque input?
I assumed that it is related to the sampling time of my bang-bang torque input, which is 0.001s.
The following is my bang-bang torque input:
Code: | starting_time=0;
simulation_time=4;
sampling_time=0.001;
t=starting_time:sampling_time:simulation_time;
for i=1:(0.2/sampling_time)+1
u(i,1)=0;
end
for i=(0.2/sampling_time)+1:(0.5/sampling_time)+1
u(i,1)=0.3;
end
for i=(0.5/sampling_time)+1:(0.8/sampling_time)+1
u(i,1)=-0.3;
end
for i=(0.8/sampling_time)+1:(4/sampling_time)+1
u(i,1)=0;
end
|
Please do help me out despite the lack of knowledge I have in digital filters.
What should I do next? |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Oct 24, 2009 10:26 am |
|
|
The problem can be subdivided in four tasks, I think:
- define a filter specification
- calcule the filter parameters
- design a code that implements the filter algorithm
- handle the platform specific problems of numeric representation
You already did the two first steps. I simply have to assume, that the selected filter specification is suitable for
your application. You have options to either use an IIR or a FIR filter structure. I still believe, that a FIR filter
involves a higher arithmetic effort, but that not's completely clear. As an advantage, you could merge both filters
to a single FIR structure without doubling the tap count.
I'm not particularly familiar to uP filter designs, because I mostly use digital filters with FPGA designs, thus I can't give
detailed suggestion for step 3 and 4. I show below a sample C code generated by a commercial filter tool.
As you see, it's using float arithmetic, so it most likely won't run at a sample frequency of 1 kHz on a PIC18.
By using adapted fix point arithmetic, 1 kHz should come in reach.
Code: | float DigFil(float invar,float initval, int setic)
/******************************************************************************/
/* Filter Solutions Version 10.0 Nuhertz Technologies, L.L.C. */
/* www.nuhertz.com */
/* +1 602-206-7781 */
/* 3rd Order Band Stop Butterworth */
/* Step Invariant Transformation */
/* Sample Frequency = 1.000 KHz */
/* Standard Form */
/* Arithmetic Precision = 4 Digits */
/* */
/* Lower Corner Frequency = 90.00 Hz */
/* Upper Corner Frequency = 110.0 Hz */
/* Pass Band Attenuation = 3.010 dB */
/* */
/******************************************************************************/
/* */
/* Input Variable Definitions: */
/* Inputs: */
/* invar float The input to the filter */
/* initvar float The initial value of the filter */
/* setic int 1 to initialize the filter to the value of initvar */
/* */
/* There is no requirement to ever initialize the filter. */
/* The default initialization is zero when the filter is first called */
/* */
/******************************************************************************/
/* */
/* This software is automatically generated by Filter Solutions. There are */
/* no restrictions from Nuhertz Technologies, L.L.C. regarding the use and */
/* distributions of this software. */
/* */
/******************************************************************************/
{
float sumnum, sumden; int i;
static float delay[7] = {0.0,0.0,0.0,0.0,0.0,0.0,0.0};
static float znum[7] = {
.9725,
-4.788,
10.81,
-13.97,
10.91,
-4.882,
1.0
};
static float zden[6] = {
.7778,
-3.942,
9.195,
-12.32,
9.999,
-4.662
};
if (setic==1){
for (i=0;i<=6;i++) delay[i] = 20.95*initval;
return initval;
}
else{
sumden=0.0;
sumnum=0.0;
for (i=0;i<=5;i++){
delay[i] = delay[i+1];
sumden += delay[i]*zden[i];
sumnum += delay[i]*znum[i];
}
delay[6] = invar-sumden;
sumnum += delay[6]*znum[6];
return sumnum;
}
} |
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|