##1. はじめに
Lチカで始めるテスト自動化シリーズ第三弾です。
昨今の省エネ事情を考慮しテスト対象のLEDの点灯方式をスタティック点灯からダイナミック点灯に仕様変更します。そこで、LEDの点灯電圧、点灯周波数をオシロスコープで測定してGo/No-Go判定を自動でできるようテストベンチを改修します。
これまでの記事はこちらをご覧ください。
##2. テスト対象の改修
スタティック点灯から1000Hz、デューティ比50%のダイナミック点灯に変更します。tone()、noTone()で点灯/消灯を制御します。
void Led::on(void)
{
//digitalWrite(m_led_pin, HIGH);
tone(m_led_pin, 1000);
}
void Led::off(void)
{
//digitalWrite(m_led_pin, LOW);
noTone(m_led_pin);
}
##3. テストランナーの改修
- 下記のコマンドを追加します。
|コマンド |引数 |機能
|-----------+----------------+----
|open_dso |なし |・PyVISAをimportしオシロスコープをopenする
|dso |VISAコマンド |・オシロスコープとコマンドを送受信する
・受信データに含まれる","は"-"に置換する
|eval_dbl_eq|期待値(double型1)|・変数valが期待値の値(double型)と等しいか評価する
|eval_dbl_gt|基準値(double型)|・変数valが基準値(double型)より大きいか評価する
|eval_dbl_lt|基準値(double型)|・変数valが基準値(double型)より小さいか評価する
#!/usr/bin/python3
#
# This software includes the work that is distributed in the Apache License 2.0
#
from time import sleep
import serial
import codecs
import csv
import sys
import visa
UNINITIALIZED = 0xdeadbeef
def serial_write(h, string):
if h == UNINITIALIZED:
print("UART Not Initialized.")
return False
else:
string = string + '\n'
string = str.encode(string)
h.write(string)
return True
def open_dso():
rm = visa.ResourceManager()
resources = rm.list_resources()
#print(resources)
for resource in resources:
#print(resource)
try:
dso = rm.open_resource(resource)
except:
print(resource, "Not Found.")
else:
print(resource, "Detected.")
return dso
#Throw an error to caller if none succeed.
return dso
def main():
is_passed = True
val = str(UNINITIALIZED)
dso = UNINITIALIZED
uart = UNINITIALIZED
arg = [""]
with codecs.open('script.csv', 'r', 'utf-8') as file:
script = csv.reader(file, delimiter=',', lineterminator='\r\n', quotechar='"')
with codecs.open('result.csv', 'w', 'utf-8') as file:
result = csv.writer(file, delimiter=',', lineterminator='\r\n', quotechar='"')
for cmd in script:
print(cmd)
if "#" in cmd[0]:
pass
elif cmd[0]=="sleep":
sleep(float(cmd[1]))
cmd.append("OK")
elif cmd[0]=="open_dso":
try:
dso = open_dso()
except:
cmd.append("NG")
is_passed = False
else:
cmd.append("OK")
elif cmd[0]=="dso":
try:
if "?" in cmd[1]:
val = dso.query(cmd[1]).rstrip().replace(",", "-")
cmd.append(val)
else:
dso.write(cmd[1])
cmd.append("OK")
except:
cmd.append("NG")
is_passed = False
elif cmd[0]=="open_uart":
try:
uart = serial.Serial(cmd[1], 115200, timeout=1.0, dsrdtr=1)
cmd.append("OK")
except:
cmd.append("NG")
is_passed = False
elif cmd[0]=="send":
ret = serial_write(uart, cmd[1])
if ret == True:
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="rcvd":
try:
val = uart.readline().strip().decode('utf-8')
cmd.append(val)
cmd.append("OK")
except:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_str_eq":
if str(val) == str(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_int_eq":
if int(val) == int(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_int_gt":
if int(val) > int(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_int_lt":
if int(val) < int(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_dbl_eq":
if float(val) == float(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_dbl_gt":
if float(val) > float(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
elif cmd[0]=="eval_dbl_lt":
if float(val) < float(cmd[1]):
cmd.append("OK")
else:
cmd.append("NG")
is_passed = False
else:
cmd.append("#")
print(cmd)
result.writerow(cmd)
if is_passed == False:
print("FAIL")
sys.exit(1)
if is_passed == True:
print("PASS")
sys.exit(0)
main()
##4. テストスクリプトおよびスクリプトジェネレータ
###4.1 (単機能)テストスクリプト
以下のテストスクリプトをscript-partsフォルダへ追加します。
- VISAコマンドはRIGOL製オシロスコープの例です。
- setup_dso.csvの機種の文字列はお使いの機種に合わせてください。
#
# Setup DSO
open_dso,
dso,*IDN?
eval_str_eq,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3
#
# Timebase Scale 200us
dso,:TIMebase:SCALe 0.0002
#
# 1.80V +/- 0.10V
dso,:MEASure:VMAX? CHANnel1
eval_dbl_gt,1.70
eval_dbl_lt,1.90
#
# 1000Hz +/- 5Hz
dso,:MEASure:FREQuency? CHANnel1
eval_dbl_gt,995
eval_dbl_lt,1005
###4.2 スクリプトジェネレータ
改修は下記2点です。
- オシロスコープのセットアップを追加
- LED点灯時のチェックをオシロスコープに変更
REM script generator for LED Light Test Bench
set script_parts_dir=script-parts
set script_file_name=script.csv
REM テストベンチのセットアップ
copy /b %script_parts_dir%\setup.csv %script_file_name%
REM デジタルオシロスコープのセットアップ
copy /b %script_file_name% + %script_parts_dir%\setup_dso.csv
copy /b %script_file_name% + %script_parts_dir%\dso_write_timescale_200us.csv
REM LEDが点灯していないこと(LEDの電圧が200mVより小さいこと)
copy /b %script_file_name% + %script_parts_dir%\eval_int_lt0200.csv
REM リレーをONし、
copy /b %script_file_name% + %script_parts_dir%\operation_relay_on.csv
REM 1. LEDの点灯電圧が1700mVより大きく1900mVより小さいこと
copy /b %script_file_name% + %script_parts_dir%\dso_query_vmax_gt1700-lt1900.csv
REM 2. LEDの点灯周波数が995Hzより大きく1005Hzより小さいこと
copy /b %script_file_name% + %script_parts_dir%\dso_query_freq_gt995-lt1005.csv
REM リレーをOFFし、LEDの電圧が200mVより小さいこと
copy /b %script_file_name% + %script_parts_dir%\operation_relay_off.csv
copy /b %script_file_name% + %script_parts_dir%\eval_int_lt0200.csv
##5. テスト実行結果
# setup
# wait for if restart Arduino Uno
sleep,2,OK
#
# Open UART
open_uart,COM3,OK
#
# model and version check
send,i,OK
rcvd,Arduino Test Bench Ver.100,OK
eval_str_eq,Arduino Test Bench Ver.100,OK
#
# relay assigned Pin number check
send,p,OK
rcvd,12,OK
eval_int_eq,12,OK
#
# Setup DSO
open_dso,,OK
dso,*IDN?,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3
eval_str_eq,RIGOL TECHNOLOGIES-DS1104Z-XXXXXXXXXXXXXX-00.04.04.SP3,OK
#
# Timebase Scale 200us
dso,:TIMebase:SCALe 0.0002,OK
#
# eval_int_lt0200
send,v,OK
rcvd,0,OK
eval_int_lt,200,OK
#
# relay ON
send,n,OK
sleep,1,OK
#
# 1.80V +/- 0.10V
dso,:MEASure:VMAX? CHANnel1,1.840000e+00
eval_dbl_gt,1.70,OK
eval_dbl_lt,1.90,OK
#
# 1000Hz +/- 5Hz
dso,:MEASure:FREQuency? CHANnel1,9.999999e+02
eval_dbl_gt,995,OK
eval_dbl_lt,1005,OK
#
# relay OFF
send,f,OK
sleep,1,OK
#
# eval_int_lt0200
send,v,OK
rcvd,0,OK
eval_int_lt,200,OK
##6. おわりに
オシロスコープの測定結果にもとづいたGo/No-Go判定をPythonで自動化できました\(^o^)/