« 高周波・RFニュース 2024年7月23日 Samsung Galaxy Z Flip6分解ビデオでミリ波AiP確認、SEMCOの車載MLCC (1210 inch X7R 22㎌ 35V)、Nordic semiconductorがスマート農業のIoT4gに参加、マッキンゼーが6Gの収益化に疑問、OPアンプのモデリング、Apple R1チップ解説 | トップページ | 「しかのこのこのここしたんたん」ゲームをカシオの高精度計算サイトkeisan.casio.jpにUP! キヨシゲーム(ズン・ズン・ズン・ズンドコを揃える)のように乱数で出てくる「しか」「のこ」「こし」「たん」を揃える。マルコフ連鎖版が難しすぎるので…ただ高精度関係ないな。 »

2024年7月23日 (火)

Pythonの高周波ライブラリscikit-rfを使ってマイクロ波LCフィルタ合成をする(1)プロトタイプLPF(チェビシェフ、バタワース)の素子の値を計算する関数をMatthai, Young & JonesのMicrowave Filters, Impedance-matching networks, and coupling structureを基に作る。

Pythonの高周波ライブラリscikit-rfは便利でたいていなんでもあるが、フィルタの合成ツールがない。回路を作ることはできるので素子の値さえ計算できればつくれるな、とやってみる。

プロトタイプLPFというのはカットオフ周波数1、信号源の特性インピーダンスを1にしたものでこれをスケーリングして任意のカットオフ周波数、特性インピーダンス(通常50Ω)のLPFが設計できる。そのL,Cの値のテーブル(gk)が大抵のマイクロ波の本には載っている。

大抵の本のネタ本になっているのはMatthai, Young & JonesのMicrowave Filters, Impedance-matching networks, and coupling structureで、大昔に買った。ここにはテーブルだけでなくButterworthとChebyshevの計算式もあるのでこれを参考にしよう。

アマゾンリンク:https://amzn.to/3LAkTPr

20240723-092059

Butterworthの係数は

\[
\begin{align}
g_{0} = 1 \\
g_{k} = 2 \sin\left(\frac{(2k-1)\pi}{2n}\right) \quad k=1,2,...,n \\
g_{n+1} = 1 \\
\end{align}\] 

 Chebyshevの係数は

\[
\begin{align}
\beta = \ln\left(\coth\left(\frac{L_{Ar}}{17.37}\right)\right) \\
\gamma = \sinh\left(\frac{\beta}{2n}\right) \\
a_{k} = \sin\left(\frac{(2k-1)\pi}{2n}\right) \quad k=1,2,...,n \\
b_{k} = \gamma^{2} + \sin^{2}\left(\frac{k\pi}{n}\right) \quad k=1,2,...,n \\
\end{align}
\]

として 

\[
\begin{align}
g_{1} = \frac{2a_{1}}{\gamma} \\
g_{k} = \frac{4a_{k-1}a_{k}}{b_{k-1}g_{k-1}}\\
g_{n+1}=1 \quad n:奇数 \\
\quad=\coth^{2}\left(\frac{\beta}{4}\right)\quad n:偶数\\
\end{align}
\]

となる。LArはリップルの大きさ(チェビシェフのみ)。MathJaxの左詰めがうまくいかない…

Pythonのコードはこんな感じで、


import numpy as np
import matplotlib.pyplot as plt
import skrf as rf
rf.stylely()

def prototype_LPF(n, type = "Chebyshev", ripple = 0.1):
    """
    信号源、負荷のインピーダンス1、カットオフ周波数1のプロトタイプLPFの素子の値をndarrayで返す関数
    n : フィルタの次数(チェビシェフの場合、偶数だと負荷のインピーダンスが50Ωになりません)
    type : チェビシェフの場合"Chebyshev", バタワースの場合 "Butterworth"
    ripple : チェビシェフの場合のリップルの大きさをdBで表したもの
    """
    gk = np.zeros(n + 2)
    gk[0] = 1.0
    if type == "Chebyshev":
        ak = np.zeros(n + 1)
        bk = np.zeros(n + 1)
        beta = np.log(1 / np.tanh(ripple / 17.37))
        gamma = np.sinh(beta/(2 * n))
        for k in range(1, n + 1):
            ak[k] = np.sin((2 * k - 1) * np.pi / (2 * n))
            bk[k] = gamma**2 + np.sin(k * np.pi / n)**2
        gk[1] = 2 * ak[1] / gamma
        for k in range(2, n + 1):
            gk[k] = 4 * ak[k-1] * ak[k] / (bk[k-1] * gk[k-1])
        if n % 2 == 0:
            gk[n+1] = 1 / (np.tanh(beta/4)**2)
        else:
            gk[n+1] = 1
    elif type == "Butterworth":
        gk[n+1] = 1
        for k in range(1, n + 1):
            gk[k] = 2 * np.sin((2 * k - 1) * np.pi / (2 * n))
    return gk

9次のチェビシェフフィルタ、リップル1dBの場合は以下のようになる。ちゃんとMatthaiさんらのテーブルの値と一致。

prototype_LPF(9, ripple=1)

array([1. , 2.17980201, 1.1191509 , 3.12151925, 1.18964317,
3.17471934, 1.18964317, 3.12151925, 1.1191509 , 2.17980201,
1. ])

5次のバタワースの場合は以下の通り。

prototype_LPF(5, "Butterworth")

array([1. , 0.61803399, 1.61803399, 2. , 1.61803399,
0.61803399, 1. ])

 

スケーリングする関数はこれ。最初にシャントCが来るかシリーズLが来るか選べるようになっている。


def LC_LPF(n, fc, z0 = 50.0, first_element = "series", type = "Chebyshev", ripple = 0.1):
    """
    信号源、負荷の特性インピーダンスZo、カットオフ周波数fcのLPFのL,C素子の値をndarrayで返す関数
    n : フィルタの次数(チェビシェフの場合、偶数だと負荷のインピーダンスが50Ωになりません)
    fc : カットオフ周波数[GHz]
    z0 : 信号源の特性インピーダンス
    first_element : 最初にシリーズのLが来る場合"series", 最初にシャントのCが来る場合"shunt"
    type : チェビシェフの場合"Chebyshev", バタワースの場合 "Butterworth"
    ripple : チェビシェフの場合のリップルの大きさをdBで表したもの
    """
    gk = prototype_LPF(n, type, ripple)
    LC_elements = np.zeros(n + 2)
    LC_elements[0] = z0
    LC_elements[n+1] = gk[n+1] * z0
    wc = 2 * np.pi * fc * 1.0E9
    if first_element == "series":
        for k in range(1, n + 1):
            if k % 2 != 0:
                LC_elements[k] = gk[k] * z0 / wc
            else:
                LC_elements[k] = gk[k] / (z0 * wc)
    elif first_element == "shunt":
        for k in range(1, n + 1):
            if k % 2 != 0:
                LC_elements[k] = gk[k] / (z0 * wc)
            else:

                LC_elements[k] = gk[k] * z0 / wc

    return LC_elements

では例題としてPozarのマイクロ波工学のものをやってみる。

5次のバタワースフィルタでカットオフ周波数が2GHzのもの。最初がシャントC。

LC_LPF(5, 2, first_element="shunt", type="Butterworth")
とすると
array([5.00000000e+01, 9.83631643e-13, 6.43795269e-09, 3.18309886e-12,
6.43795269e-09, 9.83631643e-13, 5.00000000e+01])
と本に載っているのと同じ結果が得られた。
では次はこれから回路合成(続く)。
続き:

Pythonの高周波ライブラリscikit-rfを使ってマイクロ波LCフィルタ合成をする(2) Circuit機能を使ってL,CをつなげていってLPF(ローパスフィルタ)を合成してSパラメータを得る。チェビシェフとバタワースを比較したり素子の繋がりを図示したり。

« 高周波・RFニュース 2024年7月23日 Samsung Galaxy Z Flip6分解ビデオでミリ波AiP確認、SEMCOの車載MLCC (1210 inch X7R 22㎌ 35V)、Nordic semiconductorがスマート農業のIoT4gに参加、マッキンゼーが6Gの収益化に疑問、OPアンプのモデリング、Apple R1チップ解説 | トップページ | 「しかのこのこのここしたんたん」ゲームをカシオの高精度計算サイトkeisan.casio.jpにUP! キヨシゲーム(ズン・ズン・ズン・ズンドコを揃える)のように乱数で出てくる「しか」「のこ」「こし」「たん」を揃える。マルコフ連鎖版が難しすぎるので…ただ高精度関係ないな。 »

パソコン・インターネット」カテゴリの記事

学問・資格」カテゴリの記事

日記・コラム・つぶやき」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« 高周波・RFニュース 2024年7月23日 Samsung Galaxy Z Flip6分解ビデオでミリ波AiP確認、SEMCOの車載MLCC (1210 inch X7R 22㎌ 35V)、Nordic semiconductorがスマート農業のIoT4gに参加、マッキンゼーが6Gの収益化に疑問、OPアンプのモデリング、Apple R1チップ解説 | トップページ | 「しかのこのこのここしたんたん」ゲームをカシオの高精度計算サイトkeisan.casio.jpにUP! キヨシゲーム(ズン・ズン・ズン・ズンドコを揃える)のように乱数で出てくる「しか」「のこ」「こし」「たん」を揃える。マルコフ連鎖版が難しすぎるので…ただ高精度関係ないな。 »

最近の記事

2025年2月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28  

最近のコメント

無料ブログはココログ
フォト