<python>arduinoがつながるポートを自動で見つける

はじめに

今回のエントリは以下のエントリの続きです.
poolbooyer.hatenablog.jp
見る順番に関してはどちらが先でも問題はないと思いますが、新規で追加した機能の部分しか記述しないので順番通りで読むのをお勧めします.

portを探すのって地味にめんどい

arduinoに関わらず、様々なデバイスとシリアル通信するときに必ず必要になるのが接続しているポートを特定する作業です.繋ぎっぱなしだったら一回プログラム書くときにそこを直書き(?)してしまえば特に問題はありませんがそんなことほぼないです(よね?).

面倒なことはpythonにやらせよう

今回やること

  • osのデバイス情報を取得
  • pythonを使ってportを取得
  • 取得したportに接続する

今回新しく触れたもの

  • OSライブラリ

実際にやってみよう

実際に作成したコード

#coding:utf-8

#システムのインポート
import sys
sys.path.append('/Library/Python/2.7/site-packages')
#シリアル通信のインポート
import serial
from serial.tools import list_ports
#OS関連のインポート
import os
import io
#tkinterのインポート
import tkinter
from tkinter import messagebox

#シリアル設定
#前回は直書きしてました
#ser=serial.Serial("/dev/cu.usbmodem1421",9600)

#ウィンドウ生成
top=tkinter.Tk()
top.title("serial sample")
top.geometry("400x300")
#top.iconbitmap("led.ico")

#シリアル通信オブジェクトの生成
ser= serial.Serial()
ser.bsudrate=9600
ser.timeout=0.1

#アプリケーションクラスの作成
class Application(tkinter.Frame):
    def __init__(self,master=None):
        super().__init__(master)
        self.pack()
        self.create_widgets()

    #ボタンの作成
    def create_widgets(self):

        #検索ボタンの生成
        #ここで繋がってるポートを探すボタンを作る
        self.hi_there=tkinter.Button(self)
        self.hi_there["text"]="serch"
        self.hi_there["command"]=self.serch_device
        self.hi_there.pack(side="top")

        #LED点灯用ボタン
        self.hi_there=tkinter.Button(self)
        self.hi_there["text"]="LED ON"
        self.hi_there["command"]=self.tx_on
        self.hi_there.pack(side="top")

        #LED消灯用ボタン
        self.hi_there=tkinter.Button(self)
        self.hi_there["text"]="LED OFF"
        self.hi_there["command"]=self.tx_off
        self.hi_there.pack(side="top")

        #シリアル通信終了用ボタン
        self.hi_there=tkinter.Button(self)
        self.hi_there["text"]="close connection"
        self.hi_there["command"]=self.close
        self.hi_there.pack(side="top")

        #アプリケーション終了ボタン
        self.quit=tkinter.Button(self,text="Exit",command=self.master.destroy)
        self.quit.pack(side="bottom")

    #検索を行う
    def serch_device(self):

          #/dev配下にあるファイルリストの取得
          files=os.listdir('/dev')
          #usbデバイスが見つかった時の処理
          #macではtty.usbmodem以下の数値が変化するので検索する検索内容をターゲットに記述
          target="tty.usbmodem"
          #前方一致をやった結果をdevnameに格納
          devname=[data for data in files if target in data]
          if len(devname)!=0:
              #見つかったことを示すダイアログボックスを作成
              found()
              #serialオブジェクトのポート情報を書き換え
              ser.port='/dev/'+str(devname[0])
              #serial通信の開始
              ser.open()
          #usbデバイスが見つからなかった時の処理
          else:
              #繋がらなかったことを示すダイアログボックスを作成
              not_found()
    #点灯用ボタンの動作の定義
    def tx_on(self):
        ser.write(bytes("n",'utf-8'))

    #消灯用ボタンの動作の定義
    def tx_off(self):
        ser.write(bytes("f",'utf-8'))

    #シリアル通信終了用ボタンの動作の定義
    def close(self):
        ser.close()
#見つからなかった時のメッセージボックス
def not_found():
    messagebox.showerror("error!!","device not found")
#見つかった時のメッセージボックス
def found():
    messagebox.showinfo("find!!","device is found")

app=Application(master=top)
#ウィンドウの生成
app.mainloop()

これでできます.
ちなみに完全Mac用です.
windows用も今後作成しようかなと思っています.