注意! Leonardo系はポートによってインスタンスIDが替わるので使用できない
Arduinoを複数接続する場合や、PCを変えた際にCOMPortが入れ替わったりした場合に誤接続を防ぐため、COMPortの番号ではなくArduino個体のIDで接続したかった
pnputil
というコマンドで接続されているデバイスの情報を読み取れるのでこれを使ってみる
Windows10 バージョン2004以降でのみ有効
pnputiコマンドで接続されているArduinoを確認
/enum-devices /connected /class "Ports"
でクラス名Ports(COMPort)のデバイスを取得できる
pnputil /enum-devices /connected /class "Ports"
インスタンスIDがArduinoのユニークIDになるので、UnityではこのIDを指定して接続できるようにする
Unityでpnputiコマンド叩くスクリプト
- インスタンスID指定してデバイスを検索する
COMPort.cs
namespace COMPortUtil
{
using System.Diagnostics;
public class COMPort
{
public static void Find(
string findDveiceInstanceId,
DataReceivedEventHandler outputHandler = null,
DataReceivedEventHandler errorOutputHanlder = null,
System.EventHandler processExit = null)
{
Process process = new Process();
process.StartInfo.FileName = "pnputil";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(outputHandler);
process.StartInfo.RedirectStandardError = true;
process.ErrorDataReceived += new DataReceivedEventHandler(errorOutputHanlder);
process.StartInfo.RedirectStandardInput = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.LoadUserProfile = true;
process.StartInfo.Arguments = "/enum-devices /connected /instanceid " + findDveiceInstanceId;
process.EnableRaisingEvents = true;
process.Exited += new System.EventHandler(processExit);
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
}
}
- 検索結果からCOMPortの番号を取得する
FindComPort.cs
using COMPortUtil;
using System.Text.RegularExpressions;
public class FindComPort: MonoBehaviour
{
string comPortName;
void Start()
{
COMPortUtil.COMPort.Find(
" FTDIBUS\\VID_0403+PID_6001+AU013KJPA\\0000", // Dveice Instance Id
this.COMUtileOutputHandler,
this.COMUtileErrorOutputHanlder,
this.COMUtileProcess_Exit);
}
private void COMUtileOutputHandler(object sender, System.Diagnostics.DataReceivedEventArgs args)
{
if (!string.IsNullOrEmpty(args.Data))
{
// Debug.Log("output : " + args.Data);
string result = args.Data;
Match matchedObject = Regex.Match(result, @"COM\d+");
if (matchedObject.Value.Length >= 4)
{
string comPort = matchedObject.Value;
try
{
comPortName = comPort;
}
catch (System.IO.IOException ex)
{
Debug.Log(ex.Message);
}
}
}
}
private void COMUtileErrorOutputHanlder(object sender, System.Diagnostics.DataReceivedEventArgs args)
{
if (!string.IsNullOrEmpty(args.Data))
{
Debug.Log("error : " + args.Data);
}
}
private void COMUtileProcess_Exit(object sender, EventArgs e)
{
System.Diagnostics.Process proc = (System.Diagnostics.Process)sender;
proc.Kill();
}
}
あとはcomPortNameを使ってシリアルポートをオープンするだけ