がれすたさんのDIY日記

電子回路、Python、組み込みシステム開発、自作エフェクターを語るblog

PyLTSpiceを使用した自動シミュレーション

PyLTspiceについて

nunobrum氏が開発されているLTspiceが出力するファイルを解釈しPython上で扱えるようにするライブラリです。
ネットリスト(.net)の編集、結果ファイル(.raw)の取得、シミュレーションの自動実行なんかができます。


内包されているモジュールを以下に示します。

使用準備

PyLTspiceを使用するにあたってシミュレーションする回路が必要になります。
簡単なオペアンプの回路を用意して実行できることを確認しておきます。
f:id:gsmcustomeffects:20210626215308p:plain

Python環境に関しては以下の通りです。

  • python3.8.10
    • matplotlib
    • numpy
    • PyLTspice

PyLTspiceはpip install PyLTSpiceで導入可能です。

RawRead

まずはLTSpiceが出力する.rawファイルを読み込むのをやってみようと思います。
先ほど用意したオペアンプ回路のin,outを拾ってきてmatplotlibで出力するというものです。

import matplotlib.pyplot as plt
from PyLTSpice.LTSpice_RawRead import LTSpiceRawRead

#.rawファイルを読み込む。
LTR = LTSpiceRawRead(r'D:\LTspice\opamp\opamp.raw')

#LTspiceで使っているラベル類を抜きだす。
print(LTR.get_trace_names())

#.rawファイルの上のほうの情報を抜き出す。
print(LTR.get_raw_property())

#ラベル値を指定してrawファイルからデータを抜き出す。
V001    = LTR.get_trace("V(n001)")
V002    = LTR.get_trace("V(n002)")
x       = LTR.get_trace('time')

#step実行命令がある場合step番号を取得する。
steps   = LTR.get_steps()

fig = plt.figure()

#グラフのプロット
for step in range(len(steps)):
    plt.plot(x.get_time_axis(step), V001.get_wave(step), label="Vin",color="blue")
    plt.plot(x.get_time_axis(step), V002.get_wave(step), label="Vout",color="red")

plt.legend(fontsize=9)
plt.xlabel("time[s]")
plt.ylabel("voltage[V]")
plt.show()

コードを実行すると以下のような波形がプロットされると思います。
f:id:gsmcustomeffects:20210626223353p:plain:w500

LTSpiceBatch使用例

先ほどのシミュレーションでは.rawファイルを読みだすことができたので少し応用的なことをやってみます。
LTSpiceBatchというモジュールを使用してnetlistファイルを編集しバッチコマンドを実行します。

具体的には、R1を10k,20k,30kと変えたときのVoutの値をプロットするというものです。*1

import matplotlib.pyplot as plt
from PyLTSpice.LTSpiceBatch import LTCommander
from PyLTSpice.LTSpice_RawRead import LTSpiceRawRead

# LTspiceの回路ファイルを読み込む
LTC = LTCommander(r'D:\LTspice\opamp\opamp.asc')
fig = plt.figure()
R1list = ['10k','20k','30k']

for i in R1list:
    #netlistの中身を編集する
    LTC.set_component_value('R1', i) 
    LTC.set_component_value('V1','SINE(0 0.1 1000 0)')
    
    #現在のnetlistの情報でバッチ処理を実行する
    raw, log = LTC.run()
    LTR = LTSpiceRawRead(r'D:\LTspice\opamp\opamp.raw')

    #rawファイルよりプロットに必要な情報を取得する
    V001    = LTR.get_trace("V(n001)")
    V002    = LTR.get_trace("V(n002)")
    x       = LTR.get_trace('time')

    #step実行がある場合回数を取得する
    steps   = LTR.get_steps()
    plt.plot(x.get_time_axis(0), V002.get_wave(0), label="Vout , R2 = "+i,color="red")

#netlistを元に戻す
LTC.reset_netlist() 
plt.plot(x.get_time_axis(0), V001.get_wave(0), label="Vin",color="blue")   
plt.legend(fontsize=9)
plt.xlabel("time[s]")
plt.ylabel("voltage[V]")
plt.show()     

f:id:gsmcustomeffects:20210628003139p:plain:w500
このコードではV(n001)のようにデフォルトネットを参照していますが
ltspice上でネットにラベルを付けておくとプログラム上で参照する際にわかりやすいです。

まとめ

PyLTspiceを触ってみましたが使い方によってはかなり便利なのではないかと思いました。
今回はあまり込み入ったことをしていませんが、その他の科学計算ライブラリと組み合わせてバッチ実行を繰り返すといったこともできそうなので機会があればやってみようと思います。

*1:この操作自体は、LTspiceの.stepコマンドで実行できますがモジュールの使い方を学ぶ例題としてはよいと思います。