6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Arduino治具とオシロスコープをRaspberry Piに接続してテストベンチを組み、Jenkinsでテストを自動化する

Posted at

1. はじめに

Raspberry PiのUSBにArduino治具とオシロスコープを接続し、Arduino治具にコマンドを送って生成した矩形波パルスをオシロスコープへ入力するとともにオシロスコープで周波数を測定し、その値をPyVISAで取得するというのをJenkinsのパイプラインで行います。テストベンチの構成を以下に示します。

jenkins-rpi-arduino-dso-with-comment.png

実行の様子です。

2. 補足

3. Arduino Leonardo治具

詳しくは「Arduino Leonardoで多目的ツールの製作」をご参照ください。

  • コマンド制御
    • Arduino LeonardoのDigital Pin #0、#1に接続しているUSBシリアル変換器(秋月電子AE-TTL-232R)を経由して行う
    • 通信速度は9600[bps]
    • 起動後、コマンドではない任意の文字(例:改行コード)の受信を以ってコマンド制御に遷移
  • 搭載コマンド→4.3コマンドモード
    • Digital Pin #10に矩形波パルスを出力:toneon <frequency>
    • Digital Pin #10の矩形波パルスを停止:toneoff
  • ソースコード→7.スケッチ

4. テストウェア

4.1 テストスクリプト

  • テストスクリプトはテスト実行プログラムへ与える命令を記述したCSVファイルです。
  • ファイル名は script.csv です。
  • CSVファイルの第一カラムに命令、第二カラムにパラメータを記述します。
  • #で始まる行はコメントです。

|命令 |動作|
|-------+----|
|sendcmd|Arduino治具へ自作コマンドを送信する|
|dso |Digital Storage OscilloscopeへSCPIコマンドを送信する|
|sleep |引数で与えられた秒数、sleepする|

script.csv
### start
sendcmd,""
sendcmd,ver
### LED Blinks
sendcmd,port 1 high
sleep,0.5
sendcmd,port 1 low
sleep,0.5
sendcmd,port 1 high
sleep,0.5
sendcmd,port 1 low
sleep,0.5
### Frequency Measurement
dso,*IDN?
dso,:TIM:SCAL 0.0002
sendcmd,toneon 1500
sleep,5.0
dso,:MEAS:FREQ? CHAN1
sleep,1.0
sendcmd,toneoff
### Unknown command check
undefined,"undefined command"
### end

4.2 テスト実行プログラム

  • 以下のデバイス名は決め打ちです。
    • USB-シリアル変換器のデバイス名
    • オシロスコープの機器ID
  • 実行結果は result.csv ファイルへ出力します。
    • script.csvの第一および第二カラムを転記
    • 実行結果を第三カラムへ出力
      • script.csvがコメントなど第一カラムのみの場合は第二カラムへ出力
    • 実行結果の出力内容
      • 命令がコメントの場合は "### COMMENT ###" を出力
      • 未定義の命令の場合は "### UNKNOWN ###" を出力
      • 命令がdsoでパラメータに?を含むものはオシロスコープの応答を出力
      • 上記以外は "OK" を出力
dso_query.py
#!/usr/bin/python

from time import sleep
import serial
import visa
import codecs
import csv

def serial_open(portname, baud):
    return serial.Serial(port=portname, baudrate=baud, timeout=1.0)

def serial_write(h, str):
    str = str + '\n'
    h.write(str)

def main():
    serial_h = serial_open("/dev/ttyUSB0", 9600)
    
    rm = visa.ResourceManager()
    print(rm.list_resources())
    dso_h = rm.open_resource('USB0::6833::1230::XXXXXXXXXXXXXX::0::INSTR')
    
    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]:
                    cmd.append("### COMMENT ###")
                    
                elif cmd[0]=="sendcmd":
                    serial_write(serial_h, cmd[1])
                    print(serial_h.read_until('$'))
                    cmd.append("OK")
                    
                elif cmd[0]=="sleep":
                    sleep(float(cmd[1]))
                    cmd.append("OK")
                    
                elif cmd[0]=="dso":
                    if '?' in cmd[1]:
                        string = dso_h.query(cmd[1])
                        values = string.splitlines()
                        cmd.append(values[0])
                    else:
                        dso_h.write(cmd[1])
                        cmd.append("OK")
                    
                else:
                    cmd.append("### UNKNOWN ###")
                
                print(cmd)
                result.writerow(cmd)
    
    dso_h.close()
    

main()

4.3 テスト実行結果ファイル

テスト実行結果を収めたファイルである result.csv の例を以下に示します。

  • Arduino治具へ "toneon 1500" コマンドを送信して1500Hzの矩形波パルスを生成し、オシロスコープの周波数測定値として "1.506024e+03" を得ました。
  • コメントや未定義の命令についても設計通りの文字列が格納されているのを確認できました。
resuly.csv
### start,### COMMENT ###
sendcmd,,OK
sendcmd,ver,OK
### LED Blinks,### COMMENT ###
sendcmd,port 1 high,OK
sleep,0.5,OK
sendcmd,port 1 low,OK
sleep,0.5,OK
sendcmd,port 1 high,OK
sleep,0.5,OK
sendcmd,port 1 low,OK
sleep,0.5,OK
### Frequency Measurement,### COMMENT ###
dso,*IDN?,"RIGOL TECHNOLOGIES,DS1054Z,XXXXXXXXXXXXXX,00.04.04.SP3"
dso,:TIM:SCAL 0.0002,OK
sendcmd,toneon 1500,OK
sleep,5.0,OK
dso,:MEAS:FREQ? CHAN1,1.506024e+03
sleep,1.0,OK
sendcmd,toneoff,OK
### Unknown command check,### COMMENT ###
undefined,undefined command,### UNKNOWN ###
### end,### COMMENT ###

5. Jenkinsパイプライン設定とコンソール出力

以下にパイプライン設定を示します。

  • MasterからSlaveへstash/unstashでテストウェアを転送しテスト実行プログラム dso_query.py をsudoで実行しています。
  • SlaveからMasterへstash/unstashでテスト実行結果ファイルを転送しています。
node('master') {
    stash name: 'project'
}
node('RPi00') {
    deleteDir()
    unstash 'project'
    sh 'ls -l'
    sh 'sudo chmod 755 *.py'
    sh 'sudo ./dso_query.py'
    sh 'cat result.csv'
    stash name: 'result'
}
node('master') {
    unstash 'result'
}
コンソール出力[^1]
ユーザー****が実行
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\pipelineSample
[Pipeline] {
[Pipeline] stash
Stashed 4 file(s)
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on RPi00 in /home/pi/jenkins/workspace/pipelineSample
[Pipeline] {
[Pipeline] deleteDir
[Pipeline] unstash
[Pipeline] sh
+ ls -l
合計 16
-rw-r--r-- 1 pi pi   42  6月 23 14:27 cmd.txt
-rw-r--r-- 1 pi pi 1957  6月 25 12:57 dso_query.py
-rw-r--r-- 1 pi pi  595  6月 25 13:03 result.csv
-rw-r--r-- 1 pi pi  388  6月 25 13:21 script.csv
[Pipeline] sh
+ sudo chmod 755 dso_query.py
[Pipeline] sh
+ sudo ./dso_query.py
(u'ASRL/dev/ttyUSB0::INSTR', u'ASRL/dev/ttyAMA0::INSTR', u'USB0::6833::1230::XXXXXXXXXXXXXX::0::INSTR')
['### start']
['### start', '### COMMENT ###']
['sendcmd', '']


?
$
['sendcmd', '', 'OK']
['sendcmd', 'ver']
ver

This is arduinoLeonardoToolsV2.ino Build at Jun 23 2018 20:08:09
OK
$
['sendcmd', 'ver', 'OK']
['### LED Blinks']
['### LED Blinks', '### COMMENT ###']
['sendcmd', 'port 1 high']
port 1 high

OK
$
['sendcmd', 'port 1 high', 'OK']
['sleep', '0.5']
['sleep', '0.5', 'OK']
['sendcmd', 'port 1 low']
port 1 low

OK
$
['sendcmd', 'port 1 low', 'OK']
['sleep', '0.5']
['sleep', '0.5', 'OK']
['sendcmd', 'port 1 high']
port 1 high

OK
$
['sendcmd', 'port 1 high', 'OK']
['sleep', '0.5']
['sleep', '0.5', 'OK']
['sendcmd', 'port 1 low']
port 1 low

OK
$
['sendcmd', 'port 1 low', 'OK']
['sleep', '0.5']
['sleep', '0.5', 'OK']
['### Frequency Measurement']
['### Frequency Measurement', '### COMMENT ###']
['dso', '*IDN?']
['dso', '*IDN?', u'RIGOL TECHNOLOGIES,DS1054Z,XXXXXXXXXXXXXX,00.04.04.SP3']
['dso', ':TIM:SCAL 0.0002']
['dso', ':TIM:SCAL 0.0002', 'OK']
['sendcmd', 'toneon 1500']
toneon 1500

OK
$
['sendcmd', 'toneon 1500', 'OK']
['sleep', '5.0']
['sleep', '5.0', 'OK']
['dso', ':MEAS:FREQ? CHAN1']
['dso', ':MEAS:FREQ? CHAN1', u'1.506024e+03']
['sleep', '1.0']
['sleep', '1.0', 'OK']
['sendcmd', 'toneoff']
toneoff

OK
$
['sendcmd', 'toneoff', 'OK']
['### Unknown command check']
['### Unknown command check', '### COMMENT ###']
['undefined', 'undefined command']
['undefined', 'undefined command', '### UNKNOWN ###']
['### end']
['### end', '### COMMENT ###']
[Pipeline] sh
+ cat result.csv
### start,### COMMENT ###
sendcmd,,OK
sendcmd,ver,OK
### LED Blinks,### COMMENT ###
sendcmd,port 1 high,OK
sleep,0.5,OK
sendcmd,port 1 low,OK
sleep,0.5,OK
sendcmd,port 1 high,OK
sleep,0.5,OK
sendcmd,port 1 low,OK
sleep,0.5,OK
### Frequency Measurement,### COMMENT ###
dso,*IDN?,"RIGOL TECHNOLOGIES,DS1054Z,XXXXXXXXXXXXXX,00.04.04.SP3"
dso,:TIM:SCAL 0.0002,OK
sendcmd,toneon 1500,OK
sleep,5.0,OK
dso,:MEAS:FREQ? CHAN1,1.506024e+03
sleep,1.0,OK
sendcmd,toneoff,OK
### Unknown command check,### COMMENT ###
undefined,undefined command,### UNKNOWN ###
### end,### COMMENT ###
[Pipeline] stash
Stashed 4 file(s)
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\pipelineSample
[Pipeline] {
[Pipeline] unstash
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

6. おわりに

  • Pythonで数十行書くだけで機器の操作を自動化できました。複数の機器や測定器にコマンドを送って性能テストを自動化するだけでなく、耐久テストや加速テストといった操作を何度も繰り返して最後に目視で実行結果を確認するようなテストもできそうです。
  • 以前「ArduinoとオシロスコープをExcelで制御して測定する」でExcel VBAでテスト自動化ツールを作りましたが、ExcelがインストールされているWindows PCをテストベンチの数だけ用意するのと比べるとRaspberry Piでできるこの方法はローコストで置き場所や電源の確保もやりやすいことや、Jenkinsでノード設定すれば台数を増やせるのはメリットと思いました。
  • 以下のようなアレンジは追々やってみたいです。
    • 繰り返し回数の指定
    • テスト実行結果にタイムスタンプを入れる
    • デバイス名を自動で解決する、あるいはコマンドの引数で指定する
    • テストスクリプトやテスト実行結果のファイル名をコマンドの引数で指定する
    • テスト実行結果のOK/NG判定
6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?