Pythonでシリアル通信:仮想ポート作成とpyserialの使い方

組み込み機器開発では、シリアル通信でログを取得したりデータを設定したりすることがよくあります。従来はTeratermでログを確認したり、.NETで専用ログViewerを作ったりしていましたが、Pythonを使えば簡単に実現できま す。この記事では、Pythonでシリアル通信を行う方法を解説します。

仮想ポート作成

まず、シリアル通信環境がない場合、Windowsに仮想COMポートを作成して通信する方法を紹介します。仮想COMポートの作成には「com0com」というツールを使用します。

com0comのインストール

  1. com0comのダウンロードページからインストーラをダウンロードします。
  2. ダウンロードしたファイルを解凍し、環境に合ったSetupファイルを実行します。
  3. インストーラの指示に従ってインストールを進めます。

仮想ポートのセットアップ

まず、com0comのセットアップツールを起動します。
アプリの一覧からcom0comを探し、その中のSetupを実行し起動します。

起動すると以下のような画面が表示されます。

まず、ややこしいので、Virtual Port Pair 0と1を削除します。

以下の画面になればすべて削除完了です。

ではポートを作成していきます。
Add Pairをクリックし、ポートの名前をいれます。

COMの名前を入れたら、Applyをクリックして適用します。
※他のチェックボックスはとりあえず無視で大丈夫です。

はい。これで仮想ポートの生成完了です。
生成できているか確認しましょう
デバイスマネージャーを起動します。 デバイスマネージャー の起動の仕方は、Windowsマークを右クリックすれば表示されます。

↓のような画面が出てきますので、com0comの項目を探して、先ほどの設定した名前があるか確認してください。

#もし、△のマークがついて、デジタル署名がないと警告が出ている場合は、右クリックしてドライバーの更新をして、ドライバをダウンロードしてください。

これで仮想ポートの準備は完了です。
シリアル通信の方法については、次ページに記載します。

ではここからPythonでのシリアル通信について記述します。

Pythonでのシリアル通信

まず、Pythonでシリアル通信するためにはpyserialというライブラリをインストールします。
おなじみ、pipコマンドでインストールします。
以下コマンドを実行してください。

pip install pyserial

では、実際のプログラムです。
送信側と受信側の2つのプログラムを用意します。

送信プログラム

import serial

def main_func():
    ser = serial.Serial('COM1',115200,timeout=1)
    ser.write(str.encode('hello\n'))
    ser.close()

if __name__ == '__main__':
    main_func()

受信プログラム

import serial

def main_func():
    ser = serial.Serial('COM2',115200,timeout=0.1)
    while True:
        try:
            data = ser.readline()
            if len(data) != 0:
                print(data)
        except KeyboardInterrupt:
                break
    ser.close()

if __name__ == '__main__':
    main_func()

はい。ここからは簡単にですが、pyserialの使い方を説明します。

pyserialの使い方

pyserialの使い方は以下の流れで行います。

①シリアルポートのオープン
②データの送受信
③ポートのクローズ

まずはじめのポートのオープンは以下で行っています。

ポートオープン処理

これは、第1引数で、COMポート指定。 第2引数でボーレートを設定、第3引数でタイムアウト時間を指定しています。
※第3引数のタイムアウトは、 pyserial の送受信関数は、同期関数となりますので何かしらアクションがないと関数から抜けれなくなるので、設定しています。

    ser = serial.Serial('COM2',115200,timeout=0.1)

データの送受信処理

データの送受信は以下の関数で行います。

ser.write(str.encode('hello\n'))      #送信
data = ser.readline()                 #1行受信

受信については、read()関数でデータのサイズ指定で読み出しすることもできます。

一点注意点ですが、こちらの送受信関数は同期関数となります。ですので相手からの何かしらのアクションがないとこの関数から戻ってこなくなり処理が止まってしまします。
※コマンドプロンプトからのプログラム中断も受け付けてくれなくなります。

ですので、このAPIは前回の記事で記載したマルチスレッドと併用で使用するのがよいと思います。
マルチスレッドについて知りたい方は↓を見てみてください。
この中で、マルチスレッドのやり方を記載しています。

ポートクローズ処理

最後はポートのクローズです。
開きっぱなしで、アプリを落としたりするとポートを掴みっぱなしになり、次回オープンできなくなったりする可能性もあるので、おまじないとして必ず行ってください。

    ser.close()

まとめ

この記事では、Pythonでシリアル通信を行う方法を解説しました。仮想ポート作成からpyserialライブラリの使い方、注意点まで詳しく説明しました。
シリアル通信は、処理の流れとしては簡単ですが、きちんとプログラミングしないと処理が返ってこなくなったり、いろいろとトラブルがあるので、みなさん気を付けてください。

Pythonについて勉強したい人は以下がおすすめです。私も持っていてたまに眺めて勉強していますものですのでぜひ購入して学習してみてください。

にいやん

出身 : 関西 居住区 : 関西 職業 : 組み込み機器エンジニア (エンジニア歴13年) 年齢 : 38歳(2022年11月現在) 最近 業務の効率化で噂もありPython言語に興味を持ち勉強しています。 そこで学んだことを記事にして皆さんとシェアさせていただければと思いブログをはじめました!! 興味ある記事があれば皆さん見ていってください!! にほんブログ村