IoTで使うPython入門 Step4-Python3ソケット③DMM 34461Aデータ連続読み出し
前回、決まった測定数を読み出しました。ここでは、連続測定の指定をしてDMMのメモリに残っている測定データをつぎつぎと読み出すことで、連続して測定&読み出しをするプログラムを作ります。
●SCPIコマンド
34410A/11A プログラミング-こんなとき、どんなコマンドを使う?- の「定期的に PC にデータを転送しながら高速連続データロギングを実施するには?」のサンプルをベースに直流電圧を測定します。
| *RST;*CLS リセット、クリア CONF:VOLT:DC 10, MAX; DCV測定, 10Vレンジ、分解能最大 VOLT:DC:NPLC MIN; 積分時間を最小に VOLT:DC:ZERO:AUTO OFF; オートゼロOFF VOLT:DC:NULL:STAT OFF; TRIG:SOURce IMMediate; 内部トリガ TRIG:COUNt INFinity; トリガ・カウント無限大 TRIG:DEL 0; トリガ遅延 0 FORMat ASCii; データ・フォーマットをASCIIに設定 *OPC? 動作完了確認 Readyだと'1'が返る ループ 数バイト読み込んで1であれば、 INIT 数字nが返ってくる R? n 読み取った n データ分を問い合わせ データ受信 ループ・エンド |
●1回だけ読み取る
ASCIIデータは有効桁9文字固定です(34461Aではバイナリの設定はできない)。DATA:POIN? を送った後に、ヘッダ部分を含む10バイトを読み込みます。
b'#3558+2.
のようなバイト列が得られます。#の後ろの1文字は、そのあとに続くデータ数の桁数を表しています。この例だと3なので、558がデータ数の数値です。+2.は、1番目のデータの先頭部分が見えています。
データ数がわかったので、それらを読み込めば、1回分のループが終わります。ループの先頭に戻ると、DMMのメモリには、数百個の測定データが保存されているので、R?で読み出すことを繰り返します。
import socket
#'DISP OFF\n'\
ipAddr = "K-34461A-16054.local"
ports = 5025
message = '*RST;*CLS\n'\
'CONF:VOLT:DC 10, MAX;\n'\
'VOLT:DC:NPLC MIN;\n'\
'VOLT:DC:ZERO:AUTO OFF;\n'\
'VOLT:DC:NULL:STAT OFF;\n'\
'\n'\
'TRIG:SOURce IMMediate;\n'\
'TRIG:COUNt INFinity;\n'\
'TRIG:DEL 0;\n'\
'FORMat ASCii;\n'\
'*OPC?\n'\
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ipAddr, ports))
s.send(message.encode())
s1 = b''
if s.recv(8): # 1=ready
s.send(b'INIT\n')
s.send(b'DATA:POIN?\n')
c = s.recv(8)
#print(c)
cc = (str(c)[:-3])[3:]
print('new data is ', cc)
m = 'R? ' + str(cc) + '\n'
#print('send ', m)
s.send(m.encode())
s0 = s.recv(10)
#print('received')
#print(type(s0),s0)
#s1=s1+s0
ss = str(s0)[3:]
#print(type(ss),ss)
#print('keta ', ss[0])
if ss[0] == '1':
#print('1', ss[1:2])
nokori = len(ss[2:])
if ss[0] == '2':
#print('2', ss[1:3])
nokori = len(ss[3:])
if ss[0] == '3':
#print('3', ss[1:4])
nokori = len(ss[4:])
if ss[0] == '4':
#print('4', ss[1:5])
nokori = len(ss[5:])
if ss[0] == '5':
#print('5', ss[1:6])
nokori = len(ss[6:])
#print('nokori ', nokori)
mojisuu = int(ss[1:int(ss[0])+1])
print('mojisuu is ', mojisuu)
mojimax = mojisuu - nokori
ss0 = s.recv(mojimax+1)
#print(ss0)
ss1 = str(ss[int(ss[0])+1:-1]) + str(ss0)[3:-1]
sss = ss1.split(',')
print(sss)
f = [float(f) for f in sss]
print(f,len(f))
●連続して読み出す①
while 1: がループ部分です。R? ですぐにデータを読み出すと、要求しているデータ準備できていないことがあるので、time.sleep(0.1) でちょっとだけ待ちます。
import socket
import time
ipAddr = "K-34461A-16054.local"
ports = 5025
message = '*RST;*CLS\n'\
'CONF:VOLT:DC 10, MAX;\n'\
'SENS:VOLT:DC:APER 20E-6;\n'\
'VOLT:DC:NPLC MIN;\n'\
'VOLT:DC:ZERO:AUTO OFF;\n'\
'VOLT:DC:NULL:STAT OFF;\n'\
'\n'\
'TRIG:SOURce IMMediate;\n'\
'TRIG:COUNt INFinity;\n'\
'TRIG:DEL 0;\n'\
'FORMat ASCii;\n'
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ipAddr, ports))
s.send(message.encode())
s.send(b'*OPC?\n')
while s.recv(2): # 1=ready
s.send(b'INIT\n')
print('init')
break
while 1:
s.send(b'DATA:POIN?\n')
c = s.recv(6)
cc = (str(c)[:-3])[3:]
print('new data is ', cc)
m = 'R? ' + cc + '\n'
s.send(m.encode())
s0 = s.recv(2)
s1 = str(s0)[3:4] # keta
s2 = int(s.recv(int(s1)) ) # read data para
time.sleep(0.1) # need wait
s3 = s.recv(s2 + 1)
s4 = str(s3)[2:][:-1] # b' ' deleted
#if s4[-1] == 'n':
s5 = s4[:-2] # \n deleted
sss = s5.split(',')
f = [float(f) for f in sss]
print(f, '\ntotal ', len(f), 'read')
print('-----')
●連続して読み出す②
上記のプログラムを整理したバージョンです。
import socket
import time
ipAddr = "K-34461A-16054.local"
ports = 5025
message = '*RST;*CLS\n'\
'CONF:VOLT:DC 10, MAX;\n'\
'SENS:VOLT:DC:APER 20E-6;\n'\
'VOLT:DC:NPLC MIN;\n'\
'VOLT:DC:ZERO:AUTO OFF;\n'\
'VOLT:DC:NULL:STAT OFF;\n'\
'\n'\
'TRIG:SOURce IMMediate;\n'\
'TRIG:COUNt INFinity;\n'\
'TRIG:DEL 0;\n'\
'FORMat ASCii;\n'
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((ipAddr, ports))
s.send(message.encode())
s.send(b'*OPC?\n')
while s.recv(2): # 1=ready
s.send(b'INIT\n')
print('init')
break
while 1:
s.send(b'DATA:POIN?\n')
cc = (str(s.recv(6))[3:-3])
print('new data is ', cc)
m = 'R? ' + cc + '\n'
s.send(m.encode())
s1 = str(s.recv(2))[3:4] # digit
s2 = int(s.recv(int(s1))) # read data count
time.sleep(0.1) # need wait
s3 = str(s.recv(s2 + 1))[2:-3] # b' \n' deleted
s4 = s3.split(',')
f = [float(f) for f in s4]
print(f, '\ntotal ', len(f), 'read\n-----')
実行中の様子です。DMMには基準電圧ICTL431の出力をつないでいます。20分ほど動かしていましたが、エラーなく動いていました。
