公開日: 2024年9月4日

【Python】シリアル通信プログラム開発環境構築 Windows 11 編

Python でシリアル通信プログラムが書ければ、通信相手にコマンドを 1000 回送りつけたり、応答が正しいかどうか自動で判定させたり、といったことが簡単に行えるようになると思います。また、「ヌルモデムエミュレーター」を導入すると、パソコンがシリアルポートを備えていなくても、セルフ送受信することができるので (1 人でボケて 1 人でつっこむ、みたいな)、作った通信プログラムの動作確認が容易です。ここでは Windows 11 上にそのような環境を構築します。FreeBSD の場合は次の記事を参照してください。

Python と pip のインストール

pySerial を利用するには、Python 本体と pip (Python のパッケージマネージャー) が必要です。ここでは、インストール不要な Embeddable Package 版の Python を使って開発環境を作ります。

配布元の https://www.python.org/downloads/windows/ から「Download Windows embeddable package (64-bit)」と書かれているリンク先のファイルをダウンロードしましょう。ダウンロード先は任意ですが、ここでは %HOME%\python\ としておきます。

この zip ファイルを解凍すると python-<バージョン>-embed-amd64 という名前のフォルダができますが、名前が長いので必要なら「epython」などにリネームします。そうするとこの例では、このフォルダの絶対パスは %HOME%\python\epython\ ということになります。

このフォルダの中にある python<バージョン>._pth をエディタで開き、コメントアウトされている「import site」の行のコメントアウトを解除します。pip を利用するために必要な措置のようです。情報源:

超軽量、超高速な配布用Python「embeddable python」
https://qiita.com/mm_sys/items/1fd3a50a930dac3db299

今のところ python.exe にパスが通っていないので、通すためのバッチファイルを書きます。ファイル名は任意ですが、ここでは startpy.cmd としておきます。

startpy.cmd
@echo off
rem ↓の PYTHONUTF8=1 はリダイレクトしたときに UnicodeDecodeError が出る問題の対策
set PYTHONUTF8=1
set pypath=%HOME%\python\epython
set PATH=%pypath%;%PATH%
cmd

あとはこの startpy.cmd をダブルクリックすれば、コマンドプロンプトが開き、パスが通って python.exe を実行できるようになります。

> python --version
Python 3.12.5

なお、Embeddable 版の Python にはひとつ注意点があります。このままではカレントディレクトリにあるモジュールをインポートすることができません。これを回避するには、Embeddable 版を展開したフォルダに、ファイル名はなんでもよいので、拡張子が「.pth」のファイルを用意して、次のように書いておいてください。

import sys; sys.path.append('')

やらなくても今回は特に問題となりませんが、後々のトラブルを避けるために、ここでやっておくとよいと思います。

次に pip です。https://bootstrap.pypa.io/ から get-pip.py をダウンロードして、実行しましょう。

> python get-pip.py
Collecting pip
  Downloading pip-24.2-py3-none-any.whl.metadata (3.6 kB)
Downloading pip-24.2-py3-none-any.whl (1.8 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.8/1.8 MB 33.0 MB/s eta 0:00:00
Installing collected packages: pip
  WARNING: The scripts pip.exe, pip3.12.exe and pip3.exe are installed in 'd:\mijinco\python\epython\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-24.2

これで pip が利用できるようになりました。pip.exe や pip3.12.exe や pip3.exe にパスが通ってないから必要なら通せ、といようなことを言われております。必要になったら考えることにして、とりあえず先を急ぎます。

pySerial のインストール

pip が利用できるようになったので、pySerial をインストールします。

> python -m pip install pyserial
Collecting pyserial
  Using cached pyserial-3.5-py2.py3-none-any.whl.metadata (1.6 kB)
Using cached pyserial-3.5-py2.py3-none-any.whl (90 kB)
Installing collected packages: pyserial
  WARNING: The scripts pyserial-miniterm.exe and pyserial-ports.exe are installed in 'd:\mijinco\python\epython\Scripts' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pyserial-3.5

先ほどと同じような忠告を受けてますが、これも特に問題なさそうな内容なので、とりあえず放っておくことにします。ちなみにアンインストール方法は次のとおり。

> python -m pip uninstall pyserial

ヌルモデムエミュレーターの準備

com0com というソフトウェアをインストールします。

com0com-3.0.0.0-i386-and-x64-signed.zip を選択してダウンロードします (signed はデジタル署名付き、unsigned はデジタル署名なし)。これを解凍してできるフォルダの中に x64 用と x86 用のインストーラが入っているので、自分の環境に合っているほうを実行します。インストールウィザードが起動したら流れに沿ってそのまま進めてください。

インストールに成功すると、スタートメニューの [すべてのアプリ] に [com0com] > [Setup Command Prompt] が追加されるので、それを起動します。プロンプトが表示されたら、「list」と打って次のように表示されれば OK です。

command> list
       CNCA0 PortName=-
       CNCB0 PortName=-
       CNCA1 PortName=COM#,RealPortName=COM3
       CNCB1 PortName=COM#,RealPortName=COM4

この表示例では、COM3 と COM4 が仮想的なクロスケーブルで接続されていることを示しています。ちなみにデバイスマネージャーは次のようになっていました。

図 1
図 1

実際に通信してみましょう。何かしらシリアル通信ができる端末エミュレーターを用意します。定番は Tera Term でしょうか。Tera Term を起動すると、図 2 のように通信設定ダイアログが表示されるので、[Serial] を選択してドロップダウンリストから com0com が用意したポートを指定します (上の例では COM3 か COM4)。

図 2
図 2

次に端末エミュレーターをもう 1 個起動します。ポートはもう一方のポートを指定します。COM4 の側からキーボードで「tuu」でも「kaa」でも適当な文字列を打ち込んでみましょう。COM3 側に表示されるはずです。逆方向も同様に送受信可能なはずです。

pySerial の動作確認

これでセルフ送受信ができるようになったので、pySerial が使えるかどうか、ちょっと確認してみましょう。次のように、COM4 を開いて適当な文字列を相手側に送りつけるだけの簡単なプログラムです。ファイル名は serialtest.py とでもしておきます。

serialtest.py
import serial

p = serial.Serial(port = 'COM4', baudrate = 9600, parity = 'N')
p.write('tuu\r\n'.encode('utf-8'))

実行します。

> python serialtest.py

COM3 側に「tuu」と表示されたでしょうか?されていれば、今日の作業はこれで終了です。お疲れさまでした。