home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / sci / electron / 23208 < prev    next >
Encoding:
Text File  |  1993-01-22  |  9.8 KB  |  312 lines

  1. Newsgroups: sci.electronics
  2. Path: sparky!uunet!news.univie.ac.at!hp4at!siemens.co.at!fuer
  3. From: fuer@nessie.gud.siemens.co.at (Gerhard Fuernkranz)
  4. Subject: Re: Digital Filtering
  5. Sender: news@siemens.co.at (Newssoftware)
  6. Message-ID: <1993Jan22.152702.1778@siemens.co.at>
  7. Date: Fri, 22 Jan 1993 15:27:02 GMT
  8. References: <fitzpa.727655646@maxwell>
  9. Nntp-Posting-Host: nessie.gud.siemens-austria
  10. Organization: SIEMENS Austria Corp., A-1100 Wien, Gudrunstr. 11
  11. X-Newsreader: Tin 1.1 PL5
  12. Lines: 298
  13.  
  14. Gerry FitzPatrick (fitzpa@eeel.nist.gov) wrote:
  15. : I need to design a digital filter (either a notch filter or
  16. : a low-pass filter).  I will be analyzing data taken from a 
  17. : lecroy 7200 scope (in either ascii or binary).  I would like
  18. : I would like to look at the 60  Hz component of the waveform.
  19. : Any ideas on how to write a subroutine that would perform this
  20. : digital filtering on stored data?  Any good books on designing
  21. : digital filters?
  22.  
  23. Once I have written the following test program
  24. to simulate the behaviour of a digital filter.
  25. It must be linked with -lm.
  26.  
  27. I hope, this will help you.
  28.  
  29. --
  30. Gerhard Fuernkranz        SIEMENS Austria Corp.
  31. Email: fuer@siemens.co.at    Gudrunstr. 11
  32. Phone: +43-1-60171-5716        A-1100 Wien
  33.  
  34. ---------- output produced by this program ----------
  35.  
  36. The example shows the pulse response of
  37. a 10th order digital filter:
  38.  
  39. input signal:
  40. Samples:
  41.     0: 0.000000                      *                             
  42.     1: 0.000000                      *                             
  43.     2: 0.000000                      *                             
  44.     3: 0.000000                      *                             
  45.     4: 1.000000                      |                            *
  46.     5: 1.000000                      |                            *
  47.     6: 1.000000                      |                            *
  48.     7: 1.000000                      |                            *
  49.     8: 1.000000                      |                            *
  50.     9: 1.000000                      |                            *
  51.    10: 1.000000                      |                            *
  52.    11: 1.000000                      |                            *
  53.    12: 1.000000                      |                            *
  54.    13: 1.000000                      |                            *
  55.    14: 1.000000                      |                            *
  56.    15: 1.000000                      |                            *
  57.    16: 1.000000                      |                            *
  58.    17: 1.000000                      |                            *
  59.    18: 1.000000                      |                            *
  60.    19: 1.000000                      |                            *
  61.    20: 1.000000                      |                            *
  62.    21: 1.000000                      |                            *
  63.    22: 1.000000                      |                            *
  64.    23: 1.000000                      |                            *
  65.    24: 1.000000                      |                            *
  66.    25: 1.000000                      |                            *
  67.    26: 1.000000                      |                            *
  68.    27: 1.000000                      |                            *
  69.    28: 1.000000                      |                            *
  70.    29: 1.000000                      |                            *
  71.    30: 1.000000                      |                            *
  72.    31: 1.000000                      |                            *
  73. output signal:
  74. Samples:
  75.     0: 0.000000                      *                             
  76.     1: 0.000000                      *                             
  77.     2: 0.000000                      *                             
  78.     3: 0.000000                      *                             
  79.     4: 0.000331                      *                             
  80.     5: 0.004683                      *                             
  81.     6: 0.030922                      *                             
  82.     7: 0.126287                      | *                           
  83.     8: 0.355361                      |       *                     
  84.     9: 0.725740                      |                *            
  85.    10: 1.103899                      |                         *   
  86.    11: 1.270497                      |                            *
  87.    12: 1.146250                      |                          *  
  88.    13: 0.929901                      |                    *        
  89.    14: 0.893190                      |                    *        
  90.    15: 1.043636                      |                       *     
  91.    16: 1.137073                      |                         *   
  92.    17: 1.047580                      |                       *     
  93.    18: 0.937792                      |                     *       
  94.    19: 0.973822                      |                     *       
  95.    20: 1.063945                      |                        *    
  96.    21: 1.041176                      |                       *     
  97.    22: 0.950166                      |                     *       
  98.    23: 0.948518                      |                     *       
  99.    24: 1.026586                      |                       *     
  100.    25: 1.043214                      |                       *     
  101.    26: 0.982888                      |                      *      
  102.    27: 0.963995                      |                     *       
  103.    28: 1.012875                      |                      *      
  104.    29: 1.030241                      |                       *     
  105.    30: 0.987176                      |                      *      
  106.    31: 0.970688                      |                     *       
  107.  
  108. ---------- cut here ----------
  109.  
  110. #include <math.h>
  111.  
  112. /*
  113.  * State information for 2nd order digital filter.
  114.  * L1 and L2 a re the currently stored values,
  115.  * C0..C2, D0..D2 are the (digital) filter coefficients.
  116.  */
  117.  
  118. struct filter {
  119.     double L1, L2;
  120.     double D0, D1, D2;
  121.     double C0, C1, C2;
  122. };
  123.  
  124. void setup_lp_filter (struct filter *f,
  125.     double OmegaA, double A0, double a1, double b1);
  126. void reset_filter (struct filter *f);
  127. void do_filter (struct filter *f, double *in, double *out, int n);
  128.  
  129. /*
  130.  * Setup a filter structure for a digital low pass filter
  131.  * of 2nd order.
  132.  * OmagaA is the normalized takeover frequency of the filter.
  133.  * OmegaA = sampling frequency (of the input samples) /
  134.  *        desired takeover frequency of the filter.
  135.  * A0 is the DC gain of the filter (normally 1.0).
  136.  * a1 and b1 are the coefficients of a corresponding
  137.  * 2nd order analog low-pass filter with complex
  138.  * transfer function
  139.  *
  140.  *        A0
  141.  *    ---------------------
  142.  *    1 + a1*P + b1*P^2
  143.  *
  144.  */
  145.  
  146. void
  147. setup_lp_filter (struct filter *f,
  148.     double OmegaA, double A0, double a1, double b1)
  149. {
  150.     /*
  151.      * Setup anlog filter coefficients.
  152.      * d1, d2, c0 are 0 for a low pass filter.
  153.      * Must be changed for other filter types,
  154.      * e.g. high-pass.
  155.      * The analog (complex) transfer function would be:
  156.      *
  157.      *    d0 + d1*P + d2*P^2
  158.      *    ------------------
  159.      *    c0 + c1*P + c2*P^2
  160.      *
  161.      * Depending on c0..d2, this can be a low-pass,
  162.      * high-pass, band-pass, notch-filter, ...
  163.      */
  164.  
  165.     double d0 = A0, d1 = 0,  d2 = 0,
  166.            c0 = 1,  c1 = a1, c2 = b1;
  167.     /*
  168.      * Convert analog filter coefficients to digital ones.
  169.      * This should work for all filter types.
  170.      * (Z transformation).
  171.      */
  172.  
  173.     double l = 1.0/tan(M_PI/OmegaA);
  174.     f->L1 = 0;
  175.     f->L2 = 0;
  176.     f->D0 = (d0 - d1 * l + d2 * l * l) / (c0 + c1 * l + c2 * l * l);
  177.     f->D1 = 2.0 * (d0 - d2 * l * l)    / (c0 + c1 * l + c2 * l * l);
  178.     f->D2 = (d0 + d1 * l + d2 * l * l) / (c0 + c1 * l + c2 * l * l);
  179.     f->C0 = (c0 - c1 * l + c2 * l * l) / (c0 + c1 * l + c2 * l * l);
  180.     f->C1 = 2.0 * (c0 - c2 * l * l)    / (c0 + c1 * l + c2 * l * l);
  181.     f->C2 = 1.0;
  182. }
  183.  
  184. /*
  185.  * Reset Filter to a defined initial condition.
  186.  */
  187.  
  188. void
  189. reset_filter (struct filter *f)
  190. {
  191.     f->L1 = 0;
  192.     f->L2 = 0;
  193. }
  194.  
  195. /*
  196.  * Run an array of input samples in[] thru the filter f
  197.  * and produce an array of output samples out[].
  198.  * N is the number of sampled values in the filter.
  199.  */
  200.  
  201. void
  202. do_filter (struct filter *f, double *in, double *out, int n)
  203. {
  204.     double L1 = f->L1, L2 = f->L2;
  205. #define IN (*in)
  206. #define OUT (*out)
  207.  
  208.     while (n-- > 0) {
  209.         OUT = f->D2 * IN + L2;
  210.         L2 = L1 + f->D1 * IN - f->C1 * OUT;
  211.         L1 = f->D0 * IN - f->C0 * OUT;
  212.         in++;
  213.         out++;
  214.     }
  215.     f->L1 = L1;
  216.     f->L2 = L2;
  217. #undef IN
  218. #undef OUT
  219. }
  220.  
  221. #define        N    32        /* Number of samples */
  222. #define        fsampl    4000.0        /* sampling frequency */
  223. #define        fg    1000.0        /* 3dB takeover frequency
  224.                        of the filter */
  225.  
  226. /*
  227.  * Filter coefficients for a 10th order butterwort (or is it
  228.  * a 10th order 0.5dB tschebyscheff - I can't remember).
  229.  */
  230.  
  231. double ai[] = { 6.3648, 1.3582, 0.4822, 0.1994, 0.0563 };
  232. double bi[] = { 18.3695, 4.3453, 1.9440, 1.2520, 1.0263 };
  233.  
  234. main()
  235. {
  236.     double in[N];
  237.     double in2[N];
  238.     double in3[N];
  239.     double in4[N];
  240.     double in5[N];
  241.     double out[N];
  242.     struct filter f[5];
  243.     int i;
  244.  
  245.     /*
  246.      * Setup the input signal.
  247.      * Example: step pulse to analyze the
  248.      * pulse response of the filter.
  249.      */
  250.  
  251.     in[0] = 0;
  252.     in[1] = 0;
  253.     in[2] = 0;
  254.     in[3] = 0;
  255.     for (i = 4; i < N; i++)
  256.         in[i] = 1.0;
  257.  
  258.     printf("input signal:\n");
  259.     printsamp(in,N);
  260.  
  261.     /*
  262.      * Set up 10th order low pass filter consisting
  263.      * of 5 2nd order stages.
  264.      */
  265.  
  266.     for (i = 0; i < 5; i++)
  267.         setup_lp_filter(&f[i],fsampl/fg,1.0,ai[i],bi[i]);
  268.  
  269.     /*
  270.      * Run the signal thru the 5 filter stages ...
  271.      */
  272.  
  273.     do_filter(&f[0],in ,in2,N);
  274.     do_filter(&f[1],in2,in3,N);
  275.     do_filter(&f[2],in3,in4,N);
  276.     do_filter(&f[3],in4,in5,N);
  277.     do_filter(&f[4],in5,out,N);
  278.  
  279.     printf("output signal:\n");
  280.     printsamp(out,N);
  281. }
  282.  
  283. printsamp (samp, n)
  284. double *samp;
  285. unsigned n;
  286. {
  287.     unsigned i;
  288.     char s[62];
  289.     char nn[32];
  290.     double maxi = 0.0;
  291.  
  292.     printf ("Samples:\n");
  293.  
  294.     for (i = 0; i < n; i++)
  295.         if (fabs(samp[i]) > maxi)
  296.             maxi = fabs(samp[i]);
  297.     for (i = 0; i < n; i++) {
  298.         int j;
  299.         memset(s,' ',60);
  300.         s[60] = 0;
  301.         s[30] = '|';
  302.         j = samp[i] / maxi * 30 + 30;
  303.         if (j < 0) j = 0;
  304.         if (j > 59) j = 59;
  305.         sprintf(nn,"%f",samp[i]);
  306.         memcpy(s,nn,strlen(nn));
  307.         s[j] = '*';
  308.         printf("%5d: %s\n",i,s);
  309.     }
  310. }
  311.