S Lazy-H
  • Home
  • About
  • Posts
  • Contact
  • Slide Rules
  • A Biker’s Tale

Filter Tables For Electronics

mathematics
electronics
Author

Sam Hutchins

Published

December 30, 2022

During the development of the two Microstrip Design posts, I came to realize that there was a section missing from one of my favorite reference books, (ARRL 2023). The latest version I acquired, the 100th edition, no longer contains a section that depicted filter normalization value tables for filter design. The rationale may have been size limitations, or the fact many folks nowadays use some sort of software program to generate the values as needed. I’m not exactly sure when those references were removed as I don’t have a handbook for every year, but they were removed sometime between the 2016 and 2021 editions. Admittedly, there are many other books available, mostly older volumes (read 20th Century) that contain pieces of those, or similar, tables. For example, Table 12-13 in (Fink and Christiansen 1982). However, the table layout seemed a bit easier to peruse in the ARRL Handbook than other references I’ve found.

So, the reason for this post is to preserve a portion of the data, and attempt to present the formulae to develop that data. As I like to experiment with the (R Core Team 2023) programming language, I thought I would take a stab at developing it that way. In fact, this whole blog is made using (Allaire et al. 2023) and (Xie, Dervieux, and Presmanes Hill 2023).

I already had developed a windowed Python program (using TKinter) to calculate Chebyshev filter values many years ago, so I used those formulae as a starting point. Creating tables in ‘R’ is simply a matter of using the ‘matrix()’ definition to store generated values. As most filter orders (N) are not useful below 3, and too cumbersome above 11, those are the orders to which I limited my tables. The two filter types I create here are for Butterworth and Chebyshev designs.

Butterworth Filters

As Butterworth filters have maximally flat responses in the passband, I didn’t have to deal with ripple values as I do in Chebyshev filter tables. The formula to generate a Butterworth normalized value is:

\[g_x = 2 \sin\left[(2 * N_x - 1) \frac{\pi}{2 * N_x}\right]\]

where Nx is the filter order, and gx is the normalized value based on a radian corner frequency of 1 rad/s and a 1\(\Omega\) system impedance. To produce the table, I used this:

Bo <- 3
butter <- matrix(data=, nrow=11,ncol=12, byrow=F)
while(Bo <= 11) {
  r <- 1
  while(r <= Bo) {
    butter[Bo,r] <- 2*sin((2*r-1)*(pi/(2*Bo)))
    butter[Bo,12] <- 1
    r <- r+1
  }
  Bo <- Bo+1
}

Then, to show only the desired rows, I skipped the first rows in the matrix by using print(butter[3:11,]). The table could be prettied up a bit with the ‘dimnames’ option easily enough.

Chebyshev Filters

The formulae are a bit more complicated for the Chebyshev design, but I will attempt to make them as clear as I can.

\[\gamma = \sinh\left(\frac{\beta}{2n}\right) \hspace{8pt} and \hspace{8pt} b_k = \gamma^2 + \sin^2\left(\frac{\beta \pi}{n}\right)\]

where k = 1,2,….,n.

\[\beta = ln\left[\frac{\cosh(R_{dB} / 2 * 20 \log(e))}{\sinh(R_{dB} / 2 * 20 \log(e))}\right] \hspace{8pt} = \hspace{8pt} ln\left[\coth\left(\frac{R_{dB}}{17.3717793}\right)\right]\]

where \(e\) is 2.718281828, RdB is ripple, n is filter order, \(\gamma\) is Gamma, \(\beta\) is Beta. For the normalized values \(g_k\), we use:

\[a_k = \sin\left[\frac{(2k - 1) \pi}{2n}\right] \hspace{8pt} for \hspace{8pt} g_1 = \frac{2a_1}{\gamma}\]

so then:

\[g_k = \frac{4a_{k-1} a_k}{b_{k-1} g_{k-1}}\]

Finally, the Rload value for odd orders is 1, for even orders:

\[g_{n+1} = \tanh^2\left(\frac{\beta}{4}\right)\]

Obviously, it is generally more desirable to have source and load impedances the same, so Chebyshev filters are usually restricted to odd orders.

The Chebyshev filters have ripple in the passband, so require a table for each desired value. I limited these tables to the same found in earlier editions of the ARRL handbook. To do that, I placed the ripple factors (0.01, 0.044 and 0.2) in a vector to use in a ‘for()’ loop. This code is shown here:

ripVal <- c(0.01,0.044,0.2) # values to use in tables (for loop)
for(ripple in ripVal) { # generate several tables at once
  order <- 3
  beta <- log1p(((cosh(ripple/17.37))/(sinh(ripple/17.37))))
  A <- matrix(data=,nrow=1,ncol=12)
  B <- matrix(data=,nrow=1,ncol=12)
  Gval <- matrix(data=, nrow=11,ncol=12, byrow=F)
  while(order <= 11) {
    y <- sinh(beta/(2*order))
    counter <- 1
    while(counter <= order) {
      A[1,counter] <- sin(((2*counter - 1)*pi)/(2*order))
      B[1,counter] <- y^2 + (sin((counter*pi)/order))^2
      counter <- counter+1
    }
    Gval[order,1] <- (2*A[,1])/y # first normalized value
    counter <- 2
    while(counter < order+1) { # Normalized values
      Gval[order,counter] <- (4*A[,counter-1]*A[,counter])/ 
        (B[,counter-1]*Gval[order,counter-1])
      counter <- counter+1
    }
    if(order%%2 == 1) { # Rload value
      Gval[order,12] <- 1
    } else {
      Gval[order,12] <- (((cosh(beta/4))/(sinh(beta/4)))^2)^-1
    }
    order <- order+1
  }
} # end of for loop

Again, to show only the desired rows, I used print(Gval[3:11,]). Also note the above ‘log1p()’ is natural log ‘ln()’ or log() in R.

So, there you have it, the tables reproduced once again, for those who don’t use a software program. And, as most filter programs only run on a Windows version, that leaves out those folks who prefer a Linux flavor1.

Have a great day, and I hope this may find some usefulness for someone. God Bless and stay safe!


References

Allaire, JJ, Yihui Xie, Christophe Dervieux, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, et al. 2023. Rmarkdown: Dynamic Documents for r. https://CRAN.R-project.org/package=rmarkdown.
ARRL. 2023. ARRL Handbook for Radio Communications, 100th Edition. Newington, CT: American Radio Relay League. https://www.arrl.org.
Fink, Donald G., and Donald Christiansen. 1982. Electronics Engineers’ Handbook, 2nd Edition. McGraw-Hill Book Company.
R Core Team. 2023. R: A Language and Environment for Statistical Computing. Vienna, Austria: R Foundation for Statistical Computing. https://www.R-project.org/.
Xie, Yihui, Christophe Dervieux, and Alison Presmanes Hill. 2023. Blogdown: Create Blogs and Websites with r Markdown. https://CRAN.R-project.org/package=blogdown.

Footnotes

  1. I prefer Fedora, and am currently using version 34↩︎

© S Lazy-H 2019 -