
そんなの既製品でいくらでもある...たしかにそれはそうなんです。
リレーをCOMポートからON/OFFできるモジュールなんていくらでもあります。
AliExpressやAmazonで安く売っています。
ただ、リレーのやつしかないんですよね...
FETやトライアックといった半導体で電源をON/OFFしたくて作ってしまいました。
スポンサーリンク
Amazonでも似たようなものは売ってるけど...
Amazonなどで売ってるモジュールはリレーをシリアル通信で制御できるものです。
普通の用途であればこれで充分だと思います。
リレーじゃなくてロードスイッチやトライアックがいいんです...
制御にマイコンを使うのも面倒なので、FTDIのUSBシリアル変換ICのBitBangモードを使います。
今回はFT231Xを使いました。
FTDIのICはちょっと高めですが、ドライバのインストールが不要で資料も多くて作りやすいです。
回路図と基板実装
よくある回路でシンプルなので大したものではないです。
ACの方だけ載せておきます。
DCは P-ch MOSFET をフォトカプラで絶縁しただけのロードスイッチだから簡単ですよ。
3分クッキングのように端折りますが、さくっと基板設計・発注をして実装したのがこちらです。
ACの方のバリスタはミスって一回り大きいモノになってしまいました。
DCの方はUSB-Aも取り付けられるような設計です。
負荷についているコンデンサはなんとなくです、なくてもいいです。
3Dプリンタでケースをつくる
ケースはタカチのような汎用品でもいいと思ったのですが、せっかくなので3Dプリンタで作りました。
インサートナットを使った贅沢なケースです。
一昔前より苦労せずキレイに仕上がるのでだいぶ使いやすくなりました。
最近私の中で3Dプリンタへの興味が再燃しつつあります。
こういう小さいケースはパラメトリックに作れるようなモデルにしています。
高さや幅を指定するだけで簡単にケースが作れるのでおすすめです。
制御プログラム(Python)
シンプルなロードスイッチですが、USBでIOを制御するところをどうするかが肝です。
最初はCH341AというWCHのチップも候補に挙がっていましたが資料が少なくて諦めました。
PyFtdiというライブラリがあってこれが非常に便利なのでプログラムはPythonで書きます。
ただ、PyFtdiはWindowsの標準ドライバでは制御できないようです。
Zadigなどのツールを使用して標準ドライバをlibusb互換のドライバに置き換える必要があります。
これはちょっと面倒だと感じました。
そこで、Windowsでも標準ドライバで簡単に使えるPyFtdiWinというライブラリを使います。
PyFtdiWinはPyFtdiからフォークされたライブラリですので使い方はほとんど同じです。(更新がなく古そうですが...)
IO制御のところは特定の1ピンしか使わないので、これ以上の汎用性を今のところは考えていません。
デバイスのURLみたいな記述が必要なのですが、シリアルナンバーなどが入っているのでそれを調べて直書きするのは面倒です。
そこで、PIDなどから紐づけてURLを生成してCOMポートの番号を指定すれば実行できるようにしています。
そのため、プログラムがちょっと長めになってしまいました。
import sys import re import serial.tools.list_ports from pyftdi.ftdi import Ftdi from pyftdi.gpio import GpioAsyncController # Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 # RI DCD DSR DTR CTS RTS RXD TXD control_bit = 0b00000010 #コマンドライン引数を取得(COM, 0 or 1) if len(sys.argv) < 3: print("Usage: python bitbang_control.py <COM_PORT> <0|1>") sys.exit(1) com_name = sys.argv[1] io_state = sys.argv[2] # COMポートと FTDI URL の対応表を格納する辞書 com_to_ftdi_map = {} # FTDIのPIDに基づくURLのプレフィックスを設定 ftdi_chip_prefix = { 0x6001: "ftdi://ftdi:232", # FT232R 0x6010: "ftdi://ftdi:2232", # FT2232 0x6015: "ftdi://ftdi:ft-x", # FT230X,FT231X # 他のFTDI チップがあればここに追加 } # COMポートのリストを取得 ports = list(serial.tools.list_ports.comports()) for port in ports: if "FTDI" in port.manufacturer: # FTDIデバイスを特定 hwid_parts = port.hwid.split(" ") serial_number = None pid = None for part in hwid_parts: if "PID=" in part: pid = int(part.split(":")[-1], 16) # 16進数で取得 if part.startswith("SER="): # シリアル番号の部分を探す serial_number = part.split("=")[1] if serial_number and pid: # PID に基づいて URL プレフィックスを選択 ftdi_prefix = ftdi_chip_prefix.get(pid, "ftdi://ftdi:unknown") # シリアル番号の末尾が英字なら削除 serial_number = re.sub(r'[A-Za-z]$', '', serial_number) ftdi_url = f"{ftdi_prefix}:{serial_number}/1" # URLを作成 com_to_ftdi_map[port.device] = ftdi_url # 辞書に保存 # 結果を表示 for com_port, ftdi_url in com_to_ftdi_map.items(): print(f"COM Port: {com_port} -> FTDI URL: {ftdi_url}") # FTDIデバイスを検出(念の為確認) print(Ftdi.show_devices()) #コマンドライン引数(COMポート番号)から該当のURLを取得 if com_name in com_to_ftdi_map: gpio = GpioAsyncController() gpio.configure(com_to_ftdi_map[com_name], direction=control_bit) if io_state == "0": # GPIOのLOWにする gpio.write(control_bit) elif io_state == "1": # GPIOのHIGHにする gpio.write(0b00000000) else: print("Invalid argument. Use 0 or 1.") else: print(f"No FTDI device found for {com_name}")
このソースコードを保存して、bitbang-control.py みたいなファイルにするとコマンドプロンプトで下記の形式で実行します。
python bitbang_control.py <COM_PORT> <0|1>
スポンサーリンク
実例としては、たとえばCOM1に接続したモジュールで"ON"(1)にするのであれば下記のような記述です。
python bitbang_control.py COM1 1
使いどころは?
で、結局こんなものを作って何をしたいかというと、PCに接続されているオーディオ機器の電源のON/OFFを制御したいのです。
たとえばイヤホン出力には自作のNutubeのヘッドホンアンプがつながっています。
ずっと電源を入れっぱなしはいかがなものかということでUSBケーブルを抜いて電源を切っていますが、もっとスマートにON/OFFの制御をしたいなと思ったのがきっかけです。
だったらスピーカーも...ということで電源がACのスピーカーも制御しちゃおうという流れです。
スピーカーをリレーで電源投入するとポップノイズが発生します。
ゼロクロスのトライアックであればノイズが発生せず快適なのです。
Windowsの再生デバイスの切り替えはAutoHotKeyを使っていますので、切り替えの際のPythonのスクリプトを実行する部分を書き足します。
全部Pythonで書いてもいいのですが、すでにAHKを使っているので...
Run(A_ComSpec ' /c python "C:\...\bitbang-control.py" COM1 1', , "Hide")
C:\...\
の部分はPythonスクリプトを置いているフォルダのフルパスなので適宜設定します。
超シンプルなモジュールですが、電子機器のスマート化と省エネに貢献できるデバイスだと思います。
今どきであればWi-Fi対応で無線制御もありますが、そこまで大げさなものではないんですよね...
既製品で普通に売ってそうで売ってないので、AliExpressとかで似たようなものを売ってくれないかなと期待しています。
スポンサーリンク
Leave a Comment