3
1

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.

マイコンのUARTコマンド制御をJenkins、Raspberry Pi、Pythonで行う

Last updated at Posted at 2019-06-16

1. はじめに

ハードウェアをE2Eテストできないなんて誰が言った? - IoTのテストを自動化するメソッド」を拝見1したところ以下のような工夫が紹介されていました。

  1. テストスクリプトをクラウドへ集約する
  • テストのコントロールにJenkinsを使用する
  • テストランナーにRaspberry Piを使用する
  • センサやサーボなどの制御はRaspberry Piに接続したArduinoで行う

また、筆者は以前「ArduinoとオシロスコープをPythonで制御して測定する」でマイコンのUARTコマンド制御や測定器の操作をPySerialやPyVISAで試したのですがこれらはRaspberry Piで簡単に動かせることがわかりました。

そこで、これまで筆者はJenkinsの環境を組んだりRaspberry Piを使ったりしたことがなかったため以下のようなテストベンチを構築し、初めてらしくLチカ2を試しました。

jenkins-rpi-arduinoJigu.png

Windows 10のPCをJenkinsのMasterに、Raspberry Pi 3B+をJenkinsのSlaveに使用し、パイプラインでMasterのワークスペースに配置したスクリプトをSlaveで実行します。Raspberry PiにArduino Leonardo治具を接続しPySerialで治具へコマンドを送信してArduino Leonardoに実装されているLED3を点滅させます。

2. Arduino Leonardo治具

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

  • コマンド制御
    • Arduino LeonardoのDigital Pin #0、#1に接続しているUSBシリアル変換器(秋月電子AE-TTL-232R)を経由して行う
    • 通信速度は9600[bps]
    • 起動後、コマンドではない任意の文字(例:"x")の受信を以ってコマンド制御に遷移
  • 搭載コマンド→4.3コマンドモード
    • Digital Pin #13に接続されているLEDの点灯:port 4 high
    • Digital Pin #13に接続されているLEDの消灯:port 4 low
  • ソースコード→7.スケッチ

3. Raspberry Pi

3.1 ハードウェア

最低限の入出力としてワイヤレスのタッチパッド付きキーボードとHDMI接続の5インチ(800x480)液晶モニタをRaspberry Pi 3B+に接続しました。ROMイメージを焼くMicro SDカードはAmazon Choiceの適当なやつです。電源も5V 3Aを給電可能なものを選んでいます。

3.2 Raspbianのインストールと設定

  • RaspbianからRaspbian Stretch with desktop and recommended software(2019-04-08)をダウンロードしました。
  • Micro SDカードのフォーマットにSDメモリカードフォーマッターを使用しました。
  • ROM焼きにWin32 Disk Imagerを使用しました。
  • sshでログインできるようRaspberry Piの設定→インターフェース→SSHを有効にしました。

以下はお好みでどうぞ。

  • VNCを使えるようにRaspberry Piの設定→インターフェース→VNCを有効にしました。
  • vimをインストールしました。sudo apt-get install vim

3.3 PySerialのインストール

Raspberry PiにPySerialとPyVISA(3.4参照)をインストールします。

3.3.1 インストール

pip install pyserial

3.3.2 動作確認

  • Arduino LeonardoのDigital Pin #0、#1に接続しているUSB-TTL変換器(秋月電子AE-TTL-232R)とRaspberry Piを接続する
  • 以下のport4_led_blink.pyをRaspberry Piに配置する
    • 改行コードはLF
  • port4_led_blinkh.pyを実行しArduino LeonardoのDigltal Pin #13に接続しているLEDが点滅すればOK
port4_led_blink.py(2019/6/23更新)
#!/usr/bin/python

from time import sleep
import serial

cmd = [
       ["sendcmd" , "x"],
       ["sendcmd" , "port 4 high"],
       ["sleep"   , "0.500"],
       ["sendcmd" , "port 4 low"],
       ["sleep"   , "0.500"],
       ["sendcmd" , "port 4 high"],
       ["sleep"   , "0.500"],
       ["sendcmd" , "port 4 low"]
      ]

def serial_open(port, baudrate):
    return serial.Serial(port, baudrate)

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

def parse_cmd(operation, parameter):
    print(operation, parameter)
    
    if operation=="sendcmd" :
        serial_write(serial_h, parameter)
    elif operation=="sleep" :
        sleep( float(parameter) )

def main():
    for i in cmd:
        parse_cmd(i[0], i[1])

serial_h = serial_open("/dev/ttyUSB0", 9600)
main()
旧バージョン
port4_led_blink.py

#!/usr/bin/python

from time import sleep
import serial

ser = serial.Serial("/dev/ttyUSB0", 9600)
data = "x"
data = data + '\r\n'
ser.write(data)

data = "port 4 high"
data = data + '\r\n'
ser.write(data)

sleep(0.500)

data = "port 4 low"
data = data + '\r\n'
ser.write(data)

sleep(0.500)

data = "port 4 high"
data = data + '\r\n'
ser.write(data)

sleep(0.500)

data = "port 4 low"
data = data + '\r\n'
ser.write(data)

3.4 PyVISAのインストール

今回は使用しませんが測定器を制御できるようRaspberry PiにVISAをインストールします4

3.4.1 インストール

sudo pip install pyusb
sudo pip install pyvisa
sudo pip install pyvisa-py

3.4.2動作確認

  • VISA対応の測定器(例:RIGOL DS1104Z)とRaspberry Piを接続する
  • ターミナルで以下の操作を行う

$ sudo python
import visa
rm=visa.ResourceManager('@py')
rm.list_resources()
※ここで測定器から応答が返って来ればOK

3.5 Jenkinsはインストールしない

スレーブ側であるRaspberry PiにJenkinsを手動でインストールする必要はありません。もしRaspberry PiでJenkinsが動作している場合は停めます。

sudo /etc/init.d/jenkins stop

4. マスター側Jenkins

4.1 Jenkinsのインストール

ふだん使っているWindows 10のPCにJenkinsをインストールします。

  • こちらからWindows版Jenkinsをダウンロードし、インストールします。
  • JavaはZuluからOpenJDK Ver.8u202のものをダウンロード、インストールしました。
  • SSH Agentプラグインをインストールしました。

4.2 ワークスペースのフォルダの変更

ワークスペースのフォルダがC:\Program Files (x86)\Jenkins\workspaceのままだとファイルを編集するたびに管理者権限のダイアログが出るのでC:\jenkins\workspaceへ変更しました。

下記ファイルをいったんデスクトップへ移動し、
C:\Program Files (x86)\Jenkins\config.xml

workspaceDirの設定を以下のように編集し、
編集前:${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}
編集後:C:/jenkins/workspace/${ITEM_FULL_NAME}

デスクトップから元のフォルダへ戻します。

その後、Jenkinsの管理→設定の再読み込みでJenkinsを再起動します。

4.3 スレーブの追加

Jenkinsダッシュボード→Jenkinsの管理→ノードの管理→新規ノード作成
ノード名:RPi00 (あとで増やせるよう00から連番)
Permanent AgentのラジオボタンをクリックしOKボタンを押下すると詳細な設定画面に遷移します。

項目 補足
ノード名 RPi00 前のページで入力した値がプリセットされています。
説明 空欄のまま default値
同時ビルド数 1 default値
リモートFSルート /home/pi/jenkins Raspberry Piに左記のフォルダを作成します
ラベル autotest とりあえず設定してみた
用途 このスレーブをできるだけ利用する
起動方法 SSH経由でUnixマシンのスレーブエージェントを起動
ホスト 192.168.0.10 Raspberry PiのIPアドレスを設定します
認証情報 pi/****** 4.4参照
Host Key Verification Strategy Non verifying Verification Strategy 閉じたネットワーク内で動かすので
可用性 Keep this agent online as much as possible

ノードプロパティはいずれもチェックなしで保存ボタンを押下します。

4.4 認証情報

認証情報欄の「追加」ボタンを押下すると"Jenkins Credentials Provider: Jenkins"というダイアログがポップアップしますのでRaspberry PiへSSHでログインするためのユーザー名とパスワードを設定します。

項目 補足
Domain グローバルドメイン
種類 ユーザー名とパスワード
スコープ システム
ユーザー名 pi
パスワード (ログインするためのパスワードを入力)
ID RPi00 この認証情報にIDを振ります
説明 RPi login ID/PW わかりやすい説明を記入します

5. Lチカ実行

3.3.2で使用したport4_led_blink.pyをJenkinsで実行します。

  • マスターのワークスペース(C:\jenkins\workspace\pipelineSample)にport4_led_blink.pyを配置
  • Jenkinsでパイプラインの新規ジョブを作成(アイテム名:pipelineSample)
  • stash/unstashでノード間のファイルを転送5
    • スレーブ側はunstash実行前にdeleteDir()でディレクトリを削除しています
  • スレーブ側でport4_led_blink.pyに実行権限を付与し実行
    • unstashしただけだとファイルのパーミッションが644で実行権限がないため
パイプラインの定義
node('master') {
    stash name: 'project'
}
node('RPi00') {
    deleteDir()
    unstash 'project'
    sh 'ls -l'
    sh 'sudo chmod 755 *.py'
    sh 'sudo ./port4_led_blink.py'
}
コンソール出力
ユーザー****が実行
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in C:\jenkins\workspace\pipelineSample
[Pipeline] {
[Pipeline] stash
Stashed 1 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
合計 4
-rw-r--r-- 1 pi pi 798  6月 23 00:49 port4_led_blink.py
[Pipeline] sh
+ sudo chmod 755 port4_led_blink.py
[Pipeline] sh
+ sudo ./port4_led_blink.py
('sendcmd', 'x')
('sendcmd', 'port 4 high')
('sleep', '0.500')
('sendcmd', 'port 4 low')
('sleep', '0.500')
('sendcmd', 'port 4 high')
('sleep', '0.500')
('sendcmd', 'port 4 low')
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

ビルドを実行しArduino LeonardoのLEDが点滅すればOKです。

6. おわりに

WindowsのJenkinsのマスターからRaspberry Piのスレーブを経由してArduino Leonardoまで土管をつなぐことができました。次のステップとしてもうちょっとPythonらしいスクリプトを書いたり6PyVISAや「M5StackとPythonで受入テスト自動化の要素技術を試す」で触ったOpenCV、PyOCRなども集約してみたいと思います。

  1. builderscon tokyo 2018 に登壇してきました」も併せて参考にさせていただきました。

  2. LEDを点滅(チカチカ)させることをLチカと呼びます。初めて作るプログラムの定番ですね。

  3. Arduino Leonardoの電源端子そばの「L」とシルクの入っているDigital Pin #13に接続されているLEDです。

  4. 詳しくは「How to Control Your Instruments From A Computer: It’s Easier Than You Think」をご覧ください。sudo重要。

  5. Jenkins パイプラインの stash/unstash を使ってノード間でファイルを転送する」を参考にさせていただきました。

  6. port4_led_blink.pyを改修しました(2019/6/23)。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?