Pythonを使ってオシロスコープを遠隔操作したり、画面キャプチャをしてみよう
IT技術
python でオシロスコープを操作しよう!
オシロスコープなどの計測器は「NI-VISA」という通信規格に対応しています。
NI-VISA を使えば、PC から簡単にオシロスコープを制御したり、データ転送することができます。
今回は「PyVISA」モジュールを使い、オシロスコープを操作する Python プログラムを作ってみましょう!
準備
PyVISA とは?
「PyVISA」は、NI-VISA を通して、Python コード上で計測器を制御するモジュールです。
【PyVISA 公式サイト】
https://pyvisa.readthedocs.io/en/latest/index.html
おなじみの pip を使えば、簡単にインストールできます。
1pip install -U pyvisa
インストールが必要なもの
- Python の開発環境
- PyVISA モジュール
- NI-VISA
この中で、NI-VISA のインストールには注意が必要です。
公式サイトの最新バージョンでは Full 版しかダウンロードできませんが、バージョンを17.5まで落とせば Runtime 版をダウンロードできます。
最低限 NI-VISA のドライバが使えればいいので、他の機能はインストール不要ということです。
筆者の実行環境
- Python(3.6)
- Spyder(3.2.6)
- PyVISA(1.9.1)
- オシロスコープ(Tektronix 社 MSO58 シリーズ)
①PyVISA でオシロスコープのアドレスを取得する
それではさっそく、Python でコードを書いていきましょう!
PC とオシロスコープを接続
まずは、Python を通して PC とオシロスコープを接続する処理を行います。
1import pyvisa
2
3rm = pyvisa.ResourceManager()
4print(rm.list_resources())
ResourceManager が、PC と計測器をつなぐクラスです。
このスクリプトを実行する前に、オシロスコープと PC が USB ケーブルで接続されているか確認してください。
オシロスコープのアドレスを取得
実行すると…
1('USB0::0x___::____::INSTR', 'ASRL1::INSTR', 'ASRL2::INSTR')
このような表示がされます。
この 'USB0::~' がオシロスコープのアドレスで、この値を使うことで通信の確立を行います。
※接続した USB の端子の箇所によっては、USB1 や USB2 となったりもします。
②オシロスコープと接続し、遠隔操作する
オシロスコープのアドレスが分かったら、次は接続です。
さっき取得したアドレスを、括弧内に入力することを忘れずに!
1import pyvisa
2import time
3from datetime import datetime
4
5inst = rm.open_resource('USB0::0x___::____::INSTR')
6print(inst.query('*IDN?'))
実行し、下記のようなコードが表示されれば接続成功です。
1<'USBInstrument'('USB0::0x___::____::INSTR')>
2TEKTRONIX,MSO58,_____,______
接続されているオシロスコープの情報が表示されていますね(__はシリアル番号の略です)。
この.query は、オシロスコープに NI-VISA コマンドを送信し、戻り値を要求しています。
NI-VISA のコマンドに「?」が付いているのも、戻り値を要求するコマンドだからです。
接続に失敗した場合
1VI_ERROR_RSRC_NFOUND (-1073807343): Insufficient location information or the requested device or resource is not present in the system.
万が一接続に失敗すると、このような表示がされます。
こんな時には、下記の方法を試してみてください。
- rm.close()で ResourceManager のクローズ処理を実行
- USB ケーブルを再接続
- オシロスコープを再起動
オシロスコープを遠隔操作してみよう
接続に成功したら、下記のコマンドを実行してみましょう。
1inst.write('ACQuire:STATE STOP')
オシロスコープの測定が停止したことが分かります。
次は、下記のコマンドです。
1inst.write('ACQuire:STATE RUN')
今度は逆に、オシロスコープの測定が再開します。
これで、PC 上からオシロスコープの測定開始・停止ができるようになりました。
PyVISA は命令するだけ
PyVISA で行っていることは、.write のコマンドで()内の NI-VISA コマンドをオシロスコープに命令するだけです。
.query と異なり、戻り値を要求せず、命令を実行するだけなので、NI-VISA のコマンドにも「?」は付いていません。
③オシロスコープの画面をキャプチャして、PC に送信
次に、測定停止中のオシロスコープの画面をキャプチャして、PC に送信するコードを書いてみましょう。
1#オシロスコープの内蔵HDにテンポラリのキャプチャ画像を保存
2inst.write('SAVE:IMAGe \"C:/Temp.png\"')
3
4#画像のキャプチャ処理が終了するまで待つ
5while inst.query('*OPC?')[0]!="1":
6 print("Waiting")
7 time.sleep(1)
8
9#保存された画像ファイルをPC側へ読み出す
10inst.write('FILESystem:READFile \"C:/Temp.png\"')
11img_data = inst.read_raw()
12
13#PC側に保存する際にdatetimeモジュールを使い、日付+時間のファイル名で保存する
14dt=datetime.now()
15filename = dt.strftime("IMG_%Y%m%d_%H%M%S,png")
16file = open(filename,"wb")
17file.write(img_data)
18file.close()
19
20#測定終了後にオシロスコープとの通信を切断する
21inst.close()
22rm.close()
上記コードの原理を説明すると、こんな感じです。
- 画面キャプチャをしたら、オシロスコープの内蔵ハードディスクに「Temp.png」として保存するよう命令
- コマンドOPC?を.queryで送信し続け、1が返ってくるまで Wait
- オシロスコープの内蔵ハードディスクから、PC へ画像ファイルを転送
処理が全て終わったら、オシロスコープとの接続をクローズすることを忘れずに!
応用例:タイマー制御の自動キャプチャ
最後に、ひとつ応用例をご紹介します!
「Python のタイマー制御により、自動でオシロスコープの RUN/STOP と画面キャプチャを行う」というものです。
オシロスコープに一切触れることなく、数秒単位で波形画面を次々に取得できますよ。
1import pyvisa
2import time
3from datetime import datetime
4
5
6VISAAddr = "USB0::___::____::INSTR" #rm.list_resources()にて得られる接続先のアドレス
7GET_INT_SEC = 3 #画像をキャプチャするまでの待ち時間[sec]
8GET_COUNT = 3 #タイマーによる画像キャプチャを繰り返す回数
9
10#リソースマネージャを実体化し、オシロスコープと接続を行う
11rm = pyvisa.ResourceManager()
12inst = rm.open_resource(VISAAddr)
13
14#接続先のオシロスコープの情報を表示(表示できない場合はエラーで終了)
15print(inst.query('*IDN?'))
16
17#タイマーカウントによる画像キャプチャ処理の開始
18for i in range(GET_COUNT):
19
20 #timeモジュールを使い、待ち時間が0になるまでカウントを繰り返す
21 cnt_sec = GET_INT_SEC
22 while cnt_sec!=0:
23 print("Timer Count:" + str(cnt_sec))
24 time.sleep(1)
25 cnt_sec = cnt_sec-1
26
27 print("Image Capture Start")
28
29 #オシロスコープの画面を停止させる
30 inst.write('ACQuire:STATE STOP')
31 time.sleep(1)
32
33 #オシロスコープの内蔵HDにテンポラリのキャプチャ画像を保存
34 inst.write('SAVE:IMAGe \"C:/Temp.png\"')
35
36 #画像のキャプチャ処理が終了するまで待つ
37 while inst.query('*OPC?')[0]!="1":
38 print("Waiting")
39 time.sleep(1)
40
41 #保存された画像ファイルをPC側へ読み出す
42 inst.write('FILESystem:READFile \"C:/Temp.png\"')
43 img_data = inst.read_raw()
44
45 #PC側に保存する際にdatetimeモジュールを使い、日付+時間のファイル名で保存する
46 dt=datetime.now()
47 filename = dt.strftime("IMG_%Y%m%d_%H%M%S,png")
48 file = open(filename,"wb")
49 file.write(img_data)
50 file.close()
51
52 #オシロスコープ側のテンポラリ画像ファイルを削除
53 inst.write('FILESystem:DELEte \"C:/Temp.png\"')
54
55 #オシロスコープの画面の停止を解除する
56 inst.write('ACQuire:STATE RUN')
57
58#測定終了後にオシロスコープとの通信を切断する
59inst.close()
60rm.close()
繰り返しの回数や時間間隔は、使いやすいようにカスタマイズしてください。
さいごに
Python の良いところは、デバッガなしでも、コードの途中で処理が実行できるところだと思います。
特に NI-VISA コマンドは使ってみないとわからないものも多いので、Python との相性は良さそうですね。
次回は「オシロスコープの波形データを自動転送」する方法をご紹介します。
お楽しみに!
次回の記事はこちら!
こちらの記事もオススメ!
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit