IoTで使うPython入門Step3-計測 (1) DMM 34461A-①

 ラボ・オートメーションという言葉が昔ありました。HP(Hewlett Packard)はAgilentからKeysightに名称が変わりました。HP-IBはGP-IBに変わったのちIEEE-488として標準化され、さまざまな研究・開発部門、製造ラインでたくさん使われていました。SCPI(Standard Commands for Programmable Instruments)言語として存続しています。
 いろいろな物理レイヤであるLANやUSB、RS-232C、各社の計測器用バスに対応したVXIドライバ、その後にできたIVIやVISAと、測定器関係ならなんでもつなげられるように進化してきました。
 一般の技術者がすぐに覚えられるということで、初期のころはBASIC言語がサンプル例としてメーカの資料に掲載されていました。それがVisual Basicになりしました。その後、どのメーカも経営的な原因なのか、サンプル類は増えていません。

 ここでは、Pythonで何とかしようと思います。

DMM 34461A

 Keysightのディジタル・マルチ・メータ34461Aは、その前の34401Aの後継機種です。相当年月が経っていますが、たくさん売れたのでしょう、いまでもヤフオクで出品されています。
 LANがデフォルトで用意されているので、ラズパイからはTCP/IPでアクセスします。

 最初に、PCにKeysightの無償ツールKeysight IO Libraries suiteをダウンロードします。必要なのはKeysight IO Libraries suiteだけですが、Command ExpertやBenchVueも必要ならインストールしておきます。BenchVueは現在、有償ソフトですが、デモは30日間無償で動きます。

 34461Aの電源を入れて2分ほどでreadyになります(ACをつないでいると発振器は常にON状態だが)。立ち上がりの途中にIPアドレスが表示されますが、読み損ねたとき本体にDHCPサーバからふられたIPアドレスは、

  • Shiftキー-Utilityキー
  • メニューI/O config
  • メニューLAN settings

で調べられます。

 もしくは先ほどインストールしたKeysight Connection Expert 2018を動かし、LANをクリック、+Addで34461Aを見つけ、表示された画面でIPアドレスがわかります。

 もしくは、National InstrumentsのNI MAXを立ち上げます。このソフトは、LabView2014をインストールしたときに入ったツールです。ここでも34461Aを見つけ、IPアドレスがわかりました(※)。

socketライブラリでプログラミング

 ラズパイの環境でプログラムを作ります。ターミナルで動くときは「python」とするとPython2が、「python3」でソース・プログラムを起動するときはPython3が動きます。ライブラリの管理ツールpipはPython2の環境にインストールするようです。

 Windows 10でもたぶん同じプログラムが動きます。Python2は「python」、Python3は「py」で起動するようです。pipはインストールした環境、pathの通し方で2か3のどちらが有効になるか不明です。

 node-RED Tips -- Input (1)の記事で、socketを使ったアクセスを行いました。

 socketは標準ライブラリなので、importして利用します。アクセス先は、IPV4のIPアドレスもしくはインターネット・ドメイン・ネームですが、mDNSの<ホスト名.local>も使えます。ポートは整数5025で、どこで決まっているのかは不明です。
 ホスト名は、機種名とシリアル番号の下5桁の組み合わせのようです。Keysight Connection Expert 2018のWeb UIをクリックして表示されるWeb画面や、34461A本体のIPアドレスを表示している画面に掲載されていました。

import socket 

ipAddr = "K-34461A-16054.local"
ports = 5025

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ipAddr, ports))

s.send('*IDN?\n')
print 'ID: ' + s.recv(256)

s.send('CONF:VOLT:AC 100,0.001\n')
s.send('VOLT:AC:BAND 20\n')
s.send('READ?\n')
print 'AC: ' + s.recv(64)

s.send('CONF:VOLT:DC 10,0.001\n')
s.send('READ?\n')
print 'DC: ' + s.recv(64)
s.close()

 AF_INETはIPv4 によるソケット、SOCK_STREAMはTCPの指定です。s.recv(xx)のxxはバッファ・サイズです。「*IDN?」はたぶんSCPI言語をサポートしている全機種に共通のコマンドで、型名などを返してきます。
 多くのDMMのデフォルトは、直流モード、レンジはautoです。なので、READ?コマンドを送ると、その設定でデータを返してきます。上記のプログラムでは、交流電圧モードに変更しています。その後、直流電圧モードに変更しています。書き込みと読み出しの確認ができました。

SCPIの仕様

 アスキー文字を使います。機種によってコマンドは異なるので、マニュアルを入手します。

 Truevoldシリーズ・デジタル・マルチメータ 操作/サービスガイド

 電圧の測定では、下記のフォーマットを使います。

CONFigure[:VOLTage]:{AC|DC}[{|AUTO|MIN|MAX|DEF}[, {|MIN|MAX|DEF}]]

】交流電圧 100Vレンジ 1mV分解能の設定
   CONF:VOLT:AC 100,0.001
   中速フィルタ(20Hz)
   s.send('VOLT:AC:BAND 20\n') 

】直流電圧 10Vレンジ 1mV分解能の設定
   CONF:VOLT:DC 100,0.001

 上記の設定後の読み取りは、READ? です。

MQTTの発行

 トピックはK-34461A/DC/voltにしました。Step2で作ったプログラムから多くを流用しています。

import paho.mqtt.publish as publish
from time import sleep
import socket

ipAddr = "K-34461A-16054.local"
ports = 5025
topic = "K-34461A/DC/volt"
host = 'raspberrypi.local'

s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ipAddr, ports))
s.send('CONF:VOLT:DC 10,0.001\n')

while 1:
s.send('READ?\n')
readDcVoltage = s.recv(64)
print "DC :" ,float(readDcVoltage), "V"
publish.single(topic, readDcVoltage, hostname=host)
sleep(1)
s.close()

 この例では、一度Brokerつながった後は、連続してデータを送れています。ソケットの機能というかTCP/IPの接続のルールをほとんど知らないので、これでうまく動いているとしか言えません。接続が維持される時間、接続が切れたら次に接続に行くまでの時間など、考慮しなくてはならない項目があるようです。
 上記のプログラムでは最後のclose()は実行されませんが、接続したのち通信しない時間がある程度経過すると自動で閉じられるようです。
 この連載では、おんどとりとの通信でソケットを使いますが、上記のプログラムではうまく動きませんでした。

 次回はUSBでつなぎます。

(※)2社のツールをインストールすると、数十のランタイム・プログラムが常駐します。2015年ごろからずっと利用していますが、これらのプログラムが原因でトラブルが起きた経験はありません。ウイルス・チェック関係はディフェンダを利用しています。