##1. はじめに
休日に家で電子工作をするのにオシロスコープが欲しくなりRIGOLのDS1054Zを昨年購入しました。当初はPCと接続することは特に考えていなかったのですがこのモデルはUSBでPCと接続するとUSBTMC(USB Test & Measurement Class)機器として認識されSCPIコマンドで制御できることがわかりました。
また、手元にUARTでコマンド制御できるArduino Leonardoがあります(→Arduino Leonardoで多目的ツールの製作)。
そこでオシロスコープとArduino Leonardoの制御をExcelで試しました。以下にその測定システムの概要を示します。
##2. 計測器をPCで制御する
計測器によって制御方法はさまざまです。DS1054ZはUSBまたはLANでPCと接続しSCPIコマンドで制御します。
###2.1 ハードウェア(物理インターフェース)
代表的な物理インターフェースを以下に挙げます。
- GPIB(General Purpose Interface Bus)
- LAN
- RS-232C
- USB
参考:https://ja.wikipedia.org/wiki/IEEE_488
###2.2 ソフトウェア
キーサイトのテスト・システムでのIVIドライバの評価 : IVIが最適な場合では以下の4つが挙げられています。
- SCPI(プログラマブル計測器用標準コマンド)
- プログラムまたは言語固有のドライバ(LabVIEW ドライバなど)
- 専用ドライバ(さまざまなベンダの測定器に付属)
- IVI などのオープンなドライバ
これに加えて、
- 機器固有のコマンド(SCPI登場より前の古い計測器)
があります。
##3. VISAライブラリ
ExcelでSCPIコマンドを使用して計測器を制御するにはVISA-COMライブラリを参照設定します。
###3.1 VISAライブラリ
VISA(Virtual Instrument Software Architecture)はIVI Foundationによって策定された計測器制御の共通規格で、この規格に則って実装されたVISAライブラリがいくつかの計測器ベンダから提供されています。VISAライブラリの一例を以下に示します。日本語ドキュメントの豊富さ、動作環境、使用条件などベンダによりさまざまです。
-
Keysight IO Librarise Suite
- Keysight IO Libraries Suiteのインストールの際にVISAライブラリが一緒にインストールされます。
-
NI-VISA
- ナショナルインスツルメンツ社が実装したVISAライブラリ。
-
TekVISA
- テクトロニクス社が実装したVISAライブラリ。
-
KI-VISA
- 菊水電子工業が実装したVISAライブラリ。
VISA-COMライブラリはMicrosoft COM形式のVISAライブラリです。
###3.2 Keysight IO Libraries Suite
DS1000ZシリーズのUltraSigma Instrument Connectivity DriverにはNI-VISAが同梱されていますがナショナルインスツルメンツ社の計測器制御の基本にはExcelの例がありません。計測器制御のプログラミングに慣れていればVisual Basicのサンプルを見ながらExcel VBAに置き換えることができるかもしれませんがちょっと敷居が高いです。
一方キーサイトのIO Libraries Suiteは
- 自動計測の情報が計測技術情報ライブラリにまとまっている
- Excelのサンプルプログラムがある
- 無償、かつ、他社の測定器ユーザも使用できる
ということでこちらを使用させていただきます。
2018/6/13追記
RIGOLのMSO1000Z&DS1000Z Programming GuideにNI-VISAのExcelのサンプルプログラムが掲載されているのをコメント欄で@shikasamaさんに教えていただきました。処理自体はKeysightのVISAとNI-VISAとで変わりませんがメソッドの名前や引数の与え方が若干異なっています。
##4. 試作プログラム
###4.1 用意するもの
- Keysight IO Libraries Suite
-
IO Libraries Suite ソフトウェアダウンロードサイト
- IO Libraries SuiteとInstrument Control Bundle(IO Libraries Suite / Command Expert / BenchVue Platformの統合パッケージ)があります
- IO Libraries Suiteは2018 Update 0.2を使用しました
- IO Libraries Suite 簡易取扱説明書 最新版
-
IO Libraries Suite ソフトウェアダウンロードサイト
- Arduino Leonardo(あるいはUARTで文字列の送受信ができるマイコンボードなど)
- SCPIコマンドをサポートするオシロスコープ
- Microsoft Excel
###4.2 USB制御
初級プログラム作成アプリケーション・ノートのExcel 2010/VBA による測定器制御プログラム入門の6. 注意事項に従い、掲載されているサンプルプログラムを使用しました。
####4.2.1 補足
- Excel 2010/VBA による測定器制御プログラム入門に記載のAgilentはKeysightの旧社名です。
- VISA AddressはPCに計測器を接続しIO Libraries Suiteに同梱のKeysight Connection Expertで確認できます。
####4.2.2 プログラム
Sub gpib_test()
Dim dstSheet As Worksheet
Set dstSheet = Worksheets("test") 'Excelの"test"シートへ戻り値を出力
Dim RM As New VisaComLib.ResourceManager
Dim DSO As New VisaComLib.FormattedIO488 'DSO : Digital Storage Oscilloscope
Set DSO.IO = RM.Open("USB0::0xXXXX::0xXXXX::XXXXXXXXXXXXXX::0::INSTR") 'VISA Address
DSO.WriteString "*IDN?"
dstSheet.Cells(2, "C") = Replace(DSO.ReadString(), vbLf, "") '改行コードを取り除いてC2セルへ書込む
DSO.IO.Close
Set DSO = Nothing
Set RM = Nothing
End Sub
####4.2.3 実行結果
PCにオシロスコープを接続して実行したのがこちらです。"*IDN?"コマンドを送信し受信したデータをC2セルに出力できました。
###4.3 RS232C制御
4.2のUSB制御プログラムに以下の改修を行いました。
- VISA Addressは ASRL6::INSTR (Arduino Leonardoに接続しているFT-232RQがCOM6として認識されているため)
- RS232Cの通信設定を追加(参考:Communicating with Instruments using RS-232)
- 送信する文字列は"ver"
- "ver"を受信するとスケッチのファイル名とビルド日時を応答するプログラムをArduino Leonardoに焼いてあります
- WriteString → ReadStringのあいだにウェイトを追加
- Sleepを作成し50msのSleepを最大10回行う
- 受信したデータから制御文字を削除
####4.3.1 プログラム
Private Declare Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)
Sub asrl_test()
Dim i As Long
Dim j As Long
Dim dstSheet As Worksheet
Set dstSheet = Worksheets("test")
Dim strVal As String
Dim strArr() As String
Dim RM As New VisaComLib.ResourceManager
Dim TB As New VisaComLib.FormattedIO488 'TB : Target Board
Set TB.IO = RM.Open("ASRL6::INSTR")
Dim sfc As VisaComLib.ISerial 'RS232C通信設定
Set sfc = TB.IO
sfc.BaudRate = 9600
sfc.DataBits = 8
sfc.Parity = ASRL_PAR_NONE
sfc.StopBits = ASRL_STOP_ONE
sfc.FlowControl = ASRL_FLOW_NONE
TB.IO.TerminationCharacter = 10
TB.IO.TerminationCharacterEnabled = True
TB.WriteString "ver"
For i = 1 To 10 'Write→ReadのあいだにSleepを入れる
Sleep (50)
strVal = ""
strVal = TB.ReadString()
ReDim strArr(1 To Len(strVal))
For j = 1 To UBound(strArr) '制御文字を削除する
strArr(j) = Mid(strVal, j, 1)
If Asc(strArr(j)) <= 31 Or 127 <= Asc(strArr(j)) Then
strArr(j) = ""
End If
Next j
strVal = Join(strArr, "")
If strVal <> "" Then
dstSheet.Cells(3, "C").Value = strVal
Exit For
End If
'DoEvents
Next
TB.IO.Close
Set TB = Nothing
Set RM = Nothing
End Sub
####4.3.2 実行結果
PCにArduino Leonardoを接続して実行したのがこちらです。"ver"コマンドを送信し返ってきたデータをC3セルに出力できました。
##5. ArduinoとオシロスコープをExcelで制御して測定する
ExcelからオシロスコープとArduino Leonardoへコマンドを送信し応答を得られたのでいよいよ本題の測定を行います。
この写真は
- ExcelからArduino LeonardoへRS232Cで自作のコマンドを送信しtone()関数で矩形波パルスを生成
- 生成したパルスをオシロスコープのCH1へ入力
- ExcelからオシロスコープへSCPIコマンドを送信しCH1の信号の周波数を測定
しているところです。
###5.1 仕様(のような何か)
####5.1.1 Excel
#####5.1.1.1 書式
- DSO(Digital Storage Oscilloscope)のVISA ADDRESSをC6セルへ記述する
- TB(Target Board、ここではArduino Leonardo)のVISA ADDRESSをC7セルへ記述する
- 1行につき一つのコマンドを10行目以降に記述する
- A列:制御対象機器
- DSO
- TB
- SYS(SYStem、Excel VBAのウェイト調整やメッセージボックス表示)
- //(コメント)
- B列:送信データ
- C列:受信データ
- 受信データが数値の場合はExcelの書式設定で小数点以下の桁数を適宜設定のこと
- A列:制御対象機器
- DSOのコマンドはSCPIコマンドそのもの
- :TIM:SCAL 0.01 (時間軸スケールを0.01秒に設定)
- :MEAS:FREQ? CHAN1 (CH1の信号の周波数を測定)
- SCPIコマンドに"?"が含まれる場合はReadString()でデータを受信しC列へ出力する
- TBのコマンドは5.1.2参照
- SYSのコマンドは以下の2つ
- wait1000ms (1000msの待ち)
- msgbox (メッセージボックスをポップアップする)
#####5.1.1.2 動作
- テスト開始ボタンの押下をもってコマンド実行を開始する
- 実行中のコマンドのセルをSelectする
- A列が空白の行をもってコマンド実行を終了する
####5.1.2 Arduino Leonardo
Arduinoにtone()という任意の周波数でデューティ比50%の矩形波パルスを生成する関数が用意されていますのでこの関数を叩くコマンドをArduino Leonardoに実装しました。
- "toneon <frequency>"というコマンドを受信すると tone(10, frequency) を実行します。
- 指定された周波数の矩形波パルスをDigital Pin #10に出力します。
###5.2 テストベンチの構築
Arduino LeonardoのDigital Pin #10をプローブでつまんでオシロスコープのCH1へ接続します(写真ではPin #10に接続されている抵抗をプローブでつまんでいます)。
###5.3 プログラム
4.2.2および4.3.1のプログラムに以下の変更を加えています。
- ActiveSheetの表からデータを入出力するように変更
- RS232Cのデータ受信部分は実機に合わせてタイミングやループ回数、文字列操作を変更
- Excel VBAの処理を制御するプログラムを追加
Option Explicit
Private Declare Sub Sleep Lib "KERNEL32.dll" (ByVal dwMilliseconds As Long)
Const COLUMN_CMD = "A" 'パーサ用コマンド
Const COLUMN_TXD = "B" '送信データ
Const COLUMN_RXD = "C" '受信データ
Const LINE_CMD = 10 'パーサ用コマンド開始行
Const VISA_ADDR_DSO = "C6" 'DSO : Digital Storage Oscilloscope
Const VISA_ADDR_TB = "C7" 'TB : Target Board
'「テスト開始」ボタン押下で呼出すマクロ
Sub Parser()
Dim i As Long
Dim strCmd As String
Dim strTxd As String
i = LINE_CMD
Do While ActiveSheet.Cells(i, COLUMN_CMD) <> ""
strCmd = ActiveSheet.Cells(i, COLUMN_CMD)
strTxd = ActiveSheet.Cells(i, COLUMN_TXD)
ActiveSheet.Cells(i, COLUMN_CMD).Select
If InStr(strCmd, "//") > 0 Then
'何もしない
ElseIf strCmd = "DSO" Then
Call ControlDSO(i, strTxd)
ElseIf strCmd = "TB" Then
Call ControlTB(i, strTxd)
ElseIf strCmd = "SYS" Then
Call ControlSystem(i, strTxd)
Else
MsgBox ("unknown command")
End If
i = i + 1
Loop
End Sub
Function ControlDSO(line As Long, strTxd As String)
Dim visaAddr As String
visaAddr = ActiveSheet.Range(VISA_ADDR_DSO)
Dim RM As New VisaComLib.ResourceManager
Dim DSO As New VisaComLib.FormattedIO488
Set DSO.IO = RM.Open(visaAddr)
DSO.WriteString strTxd
If InStr(strTxd, "?") > 0 Then
ActiveSheet.Cells(line, COLUMN_RXD) = Replace(DSO.ReadString(), vbLf, "")
End If
DSO.IO.Close
Set DSO = Nothing
Set RM = Nothing
End Function
Function ControlTB(line As Long, strTxd As String)
Dim i As Long
Dim j As Long
Dim strVal As String
Dim strArray() As String
' Dim dbgStr As String
Dim visaAddr As String
visaAddr = ActiveSheet.Range(VISA_ADDR_TB)
Dim RM As New VisaComLib.ResourceManager
Dim TB As New VisaComLib.FormattedIO488 'TB : Target Board
Set TB.IO = RM.Open(visaAddr)
Dim sfc As VisaComLib.ISerial 'RS232C通信設定
Set sfc = TB.IO
sfc.BaudRate = 9600
sfc.DataBits = 8
sfc.Parity = ASRL_PAR_NONE
sfc.StopBits = ASRL_STOP_ONE
sfc.FlowControl = ASRL_FLOW_NONE
TB.IO.TerminationCharacter = 10
TB.IO.TerminationCharacterEnabled = True
TB.WriteString strTxd
strVal = ""
For i = 1 To 3 'Write→ReadのあいだにSleepを入れる
Sleep (10)
DoEvents
strVal = strVal + TB.ReadString()
ReDim strArray(1 To Len(strVal))
For j = 1 To UBound(strArray) '制御文字を削除する
strArray(j) = Mid(strVal, j, 1)
If Asc(strArray(j)) <= 31 Or 127 <= Asc(strArray(j)) Then
' dbgStr = CStr(i) + "," + CStr(j) + "," + CStr(Asc(strArray(j)))
' MsgBox (dbgStr)
strArray(j) = ""
End If
Next j
strVal = Join(strArray, "")
If i <= 2 Then
strVal = strVal + "/"
End If
If strVal <> "" Then
ActiveSheet.Cells(line, COLUMN_RXD).Value = strVal
'Exit For
End If
Next
TB.IO.Close
Set TB = Nothing
Set RM = Nothing
End Function
Function ControlSystem(line As Long, strTxd As String)
Dim i As Long
If strTxd = "wait1000ms" Then
For i = 1 To 10
Sleep (100)
DoEvents
Next
ElseIf strTxd = "msgbox" Then
MsgBox ("wait...")
End If
End Function
##6. おわりに
-
測定器とマイコンボードをExcelで一元的に制御して測定するのは思っていたより難しくないと思いました。
- Keysight IO Librarise Suiteと計測技術情報ライブラリのおかげで百数十行のExcelのマクロでシンプルながらも自動計測システムを組めました。
-
Excelで測定器を制御して測定を行いその結果がそのままExcelに保存されるのは便利と思いました。
- 筆者が学生だった頃はPC-9801の拡張スロットにGPIBボードを挿してGPIBケーブルでオシロスコープをつないでフロッピーディスクに測定結果を保存したのをPC-9801とは別のWindows PCに移してExcelで開いて、、、などとやっていたので隔世の感があります。
-
VISA/VISA-COM、共通コマンド、SCPIコマンドが計測器業界で共通なのはありがたいと思いました。
- 今回たまたま手持ちのオシロスコープで制御プログラム(Excelマクロ)を作成しましたがSCPIコマンドをサポートするオシロスコープであればメーカーを問わずプログラムを再利用できてノウハウも無駄にならずに済むのはメリットと思いました。