動機
- (1)を見てください
環境
- Windows10
- Anaconda(3.x)
- (2)でpySerialを
conda install
しました
目標
- わたしの環境でのマニュアル操作の自動化を例として、自動化方法を示す
方法
pandasというPythonで使える、Excelのような表操作に適したパッケージがあります。これとmatplotlibというグラフを簡単にきれいに描画できるパッケージを用いて「自動で取得した電圧値をグラフ化する」の例を提示します。
例
空間に電流が広範囲に、一方向に流れているときに、空間より小さいマトを使って電流を測定するとします。マトを電流に対して垂直に少しずつ横切らせ、ステップごとの電流を記録するとき、その「移動の制御」と「電流の測定」をpyserialから制御します。移動の制御はシグマ光機SHOT102、電流の測定はADVANTEST社のR6441シリーズを用いています。
Cell1
import serial
import time
import pandas as pd
import matplotlib.pyplot as plt
serial
はpyserialを使う、time
はシリアル通信のインターバル時間を作る、pandas
はdataframeを使う、matplotlib.pyplot
はグラフの描画のために使います。
Cell2
## 定数指定
MAX = 42000
COMpulse = "COM9"
COMampere = "COM10"
bitRate = 9600
pyserial
で用いる定数を指定します。
Cell3
## 変数初期化
pulse = 0
ampere_list = []
pulse_list = []
ampere_average_list =[]
使用する変数を初期化します。
Cell4(省略可)
## 奥原点移動(初期化)
ser = serial.Serial(COMpulse, bitRate, timeout=0.1)
ser.write(b"H:2-\r\n")
time.sleep(0.1)
print(ser.read_all())
ser.close()
動作確認と計測原点に移ります。
Cell5
pulse
は0-42000の値を取り、1パルスあたり3μm移動します。(実際は2パルスあたり6μm動きますが、コマンドはこのように記述するようです)。各positionでの電流の値を5回サンプリングし、平均してその点での値とします。平均する回数は任意です。光学台を最後まで動かし終わったら、電流と位置の値のリストをdataframeとしてくっつけて、pulse値を実際の長さに変換し、matplotlibで描画する。という流れになっています。(ついでにdataframeをcsvに出しています。)
## 測定開始
while 1:
if pulse >= MAX:
## 位置がMAXまで来ている場合while文を終了
break
## 現在位置の情報を記録
pulse_list.append(pulse/2) #pulseは何故か2倍で指定して命令するので2で割っている
## 電流を測定する(5回とって平均したものをその位置での値とする)
for i in range(5):
ser = serial.Serial(COMampere,bitRate,timeout=0.1)
time.sleep(0.5)
ser.write(b"MD?\r\n")
time.sleep(0.5)
tmp = ser.read_all()
ampere = float(tmp.split()[1])
ampere_average_list.append(ampere)
ser.close()
## 電流とpulse(位置)をlistに追加
ampere_list.append(sum(ampere_average_list)/len(ampere_average_list))
ampere_average_list = [] #リストを初期化
## 光学台を動かす
pulse += 1000
position = "A:2+P"+str(pulse)+"\r\n" # コマンドを文字列の結合で作る
ser = serial.Serial(COMpulse,bitRate,timeout=0.1)
ser.write(bytes(position, 'UTF-8'))
time.sleep(0.5)
ser.write(b"G:\r\n")
ser.close()
## リストをdataframeに変える
print(ampere_list)
print(pulse_list)
df = pd.DataFrame({'ampere(A)':ampere_list,'pulse':pulse_list})
## pulse値を長さに変える
def pulseToMilliMeter(pulse):
return pulse*0.006
df["position(mm)"] = df["pulse"].map(pulseToMilliMeter) # Excelの一括関数適用のようなことができる
df.to_csv('./csv/hoge/result.csv',index=False)
## matplotlibを用いてグラフを描画する
plt.figure()
df.plot(x='position(mm)',y='ampere(A)')
plt.savefig('./img/sample.png')
plt.close('all')
おわりに
以上で効率化できたとします。実際Enterを押すだけなので、かなりシンプルになりましたし、再現性も高まります。他にも効率化できるネタができたら、続きを書きます。