この記事ではオシロスコープを使用した自動測定の実現方法と活用アイデア④について解説しています。
プログラムの実行
オシロスコープにファンクションジェネレータを接続してプログラムを実行してみます。ファンクションジェネレータは10mHzのRamp信号を1Vppで出力しています。
プログラムを実行するとグラフウィンドウが表示され、Startをクリックするとグラフ描画が開始されます。Stopをクリックするとグラフ描画が停止します。
1秒毎に電圧が変化している様子が確認できます。このような長い時間をかけて変化する信号の測定はオシロスコープが苦手な分野の一つですが、プログラムを組み合わせることで簡単に測定できるようになります。また簡易的ではありますが、グラフ表示によって視覚的に信号の変化を捉えられることも、プログラミングによる自動測定のメリットと言えます。
周波数特性の測定
周波数特性の測定にはネットワークアナライザなどの計測器を使用することが一般的ですが、ファンクションジェネレータと組み合わせることでオシロスコープでも実現できます。(Siglent製のオシロスコープの場合、周波数特性を測定するためのSAG1021Iもあります)
ここではローパスフィルタの測定を例にして、周波数特性を測定するプログラムを紹介します。なお今回は簡易的な手段で測定を実現していますが、実務レベルで使用するにはプログラムのブラッシュアップが必要です。
プログラムの生成
Perplexityのプロンプトは以下のように入力しました。
-------------------------------------------------------------------------------------------------------
以下の要件を満たすプログラムを生成して
・オシロスコープ(SDS804X)とファンクションジェネレータ(SDG2042X)を使用して周波数特性を測定
・周波数範囲は10Hz~10kHz
・測定ポイント数は10points/decade
・ファンクションジェネレータで周波数を変化させるたびに、オシロスコープのピーク間電圧を測定する
・すべての測定が終了したら、周波数特性グラフ表示する
-------------------------------------------------------------------------------------------------------
このプロンプトをもとに生成されたプログラムは以下のとおりです。
**************************************************************************************
import pyvisa
import time
import numpy as np
import matplotlib.pyplot as plt
# 機器への接続
rm = pyvisa.ResourceManager()
scope = rm.open_resource('USB0::0xF4EC::0x1017::SDS08A0X802449::INSTR') # オシロスコープ
fgen = rm.open_resource('USB0::0xF4EC::0x1011::SDG2XDCD3R0001::INSTR') # ファンクションジェネレータ
# 測定パラメータの設定
start_freq = 10
stop_freq = 10000
points_per_decade = 10
# 周波数リストの生成
frequencies = np.logspace(np.log10(start_freq), np.log10(stop_freq),
num=int(points_per_decade * np.log10(stop_freq/start_freq)) + 1)
# 測定結果を格納するリスト
amplitudes = []
# オシロスコープの設定
scope.write(':CHANnel1:SWITch ON')
scope.write(':CHANnel1:SCALe 0.1')
scope.write(':TIMebase:SCALe 0.01')
scope.write(':TRIGger:MODE EDGE')
scope.write(':TRIGger:EDGE:SOURce CHANnel1')
scope.write(':TRIGger:EDGE:LEVel 0')
# ファンクションジェネレータの設定
fgen.write('C1:BSWV WVTP,SINE')
fgen.write('C1:BSWV AMP,1')
fgen.write('C1:OUTP ON')
# 測定ループ
for freq in frequencies:
# ファンクションジェネレータの周波数を設定
fgen.write(f'C1:BSWV FRQ,{freq}')
# オシロスコープの測定
scope.write(':MEASure:CLEar')
scope.write(':MEASure:ADVanced:P1:TYPE VPP')
scope.write(':MEASure:ADVanced:P1:SOURce1 CHANnel1')
time.sleep(0.5) # 測定が安定するまで待機
# ピーク間電圧の取得
vpp = float(scope.query(':MEASure:ADVanced:P1:VALue?'))
amplitudes.append(vpp)
# 測定終了
fgen.write('C1:OUTP OFF')
# 結果のプロット
plt.semilogx(frequencies, 20 * np.log10(amplitudes))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude (dB)')
plt.title('Frequency Response')
plt.grid(True)
plt.show()
# 接続を閉じる
scope.close()
fgen.close()
rm.close()
**************************************************************************************
プログラムの修正
ただしこのままだと上手く動作しなかったため、以下のように修正しました。
**************************************************************************************
import pyvisa
import time
import numpy as np
import matplotlib.pyplot as plt
# 機器への接続
rm = pyvisa.ResourceManager()
scope = rm.open_resource('USB0::0xF4EC::0x1017::SDS08A0X802449::INSTR') # オシロスコープ
fgen = rm.open_resource('USB0::0xF4EC::0x1102::SDG2XFBQ7R2350::INSTR') # ファンクションジェネレータ
# 測定パラメータの設定
start_freq = 10
stop_freq = 10000
points_per_decade = 10
# 周波数リストの生成
frequencies = np.logspace(np.log10(start_freq), np.log10(stop_freq),
num=int(points_per_decade * np.log10(stop_freq/start_freq)) + 1)
# 測定結果を格納するリスト
amplitudes = []
# オシロスコープの設定
scope.write(':CHANnel1:SWITch ON')
scope.write(':CHANnel1:SCALe 0.2') # 垂直スケールを適切に設定
scope.write(':TIMebase:SCALe 0.01') # 水平スケールを適切に設定
scope.write(':TRIGger:MODE EDGE')
scope.write(':TRIGger:EDGE:SOURce CHANnel1')
scope.write(':TRIGger:EDGE:LEVel 0')
# ファンクションジェネレータの設定
fgen.write('C1:BSWV WVTP,SINE')
fgen.write('C1:BSWV AMP,1') # 振幅を1Vppに設定
fgen.write('C1:OUTP ON')
# 測定ループ
for freq in frequencies:
# ファンクションジェネレータの周波数を設定
fgen.write(f'C1:BSWV FRQ,{freq}')
# オシロスコープの測定
scope.write(':MEASure:CLEar')
time.sleep(2) # 測定が安定するまで待機
# 実効値の取得
vrms = float(scope.query(':MEASure:SIMPle:VALue? PKPK'))
amplitudes.append(vrms)
# 測定終了
fgen.write('C1:OUTP OFF')
# 結果のプロット
plt.semilogx(frequencies, 20 * np.log10(amplitudes))
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude (dB)')
plt.title('Frequency Response')
plt.grid(True)
plt.show()
# 接続を閉じる
scope.close()
fgen.close()
rm.close()
**************************************************************************************
プログラムの実行
修正後のプログラムを実行してみるとローパスフィルタの特性通り、周波数が高くなるにつれて振幅が減衰する様子がグラフで確認できます。
ここでは振幅が-30dBで平坦になっていますが、これはオシロスコープの垂直分解能による影響です。本来であれば周波数ごとに垂直軸スケールを設定するのが適切ですが、今回は簡易的なプログラムであるため、-30dBで頭打ちになっています。同じプログラムを使ってハイパスフィルタとバンドパスフィルタの周波数特性も測定してみました。
いずれも垂直軸スケールの影響でダイナミックレンジは小さいですが、フィルタの通過域付近の特性は正しく測定できていると言えそうです。このようにプログラミングによる自動測定を活用することで、比較的容易に回路の周波数特性を評価できるようになります。
© 2024 T&Mコーポレーション株式会社