以前書いた UnityでArduinoの接続にユニークIDを使う (Windows) をLeonardo系のArduino対応にも対応した
注意!VID PIDのみの判定になるので、Leonardo系の複数同時接続はできない
Windows10 バージョン2004以降でのみ有効
pnputiコマンドで接続されているArduinoを確認
/enum-devices /connected /class "Ports"
でクラス名Ports(COMPort)のデバイスを取得できる
pnputil /enum-devices /connected /class "Ports"
インスタンスIDがArduinoのユニークIDになるので、UnityではこのIDを指定して接続できるようにする
ArduinoLeonardoでは接続するポートによってインスタンスIDの USB\\VID_XXXX&PID_XXXX 以降 の文字列が変わるため、
USB\\VID_XXXX&PID_XXXX までをコピーして使用する
Unityでpnputiコマンド叩くスクリプト
- インスタンスID指定してデバイスを検索する
COMPort.cs
namespace COMPortUtil
{
using System.Diagnostics;
public class COMPort
{
public static string Find(
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 /class " + "Ports";
process.EnableRaisingEvents = true;
process.Exited += new System.EventHandler(processExit);
process.Start();
string results = process.StandardOutput.ReadToEnd();
process.BeginErrorReadLine();
process.WaitForExit();
process.Close();
return results;
}
}
}
- 検索結果からCOMPortの番号を取得する
SerialHandler.cs
using COMPortUtil;
using System.Text.RegularExpressions;
public class SerialHandler: MonoBehaviour
{
string comPortName;
void Start()
{
comPortName = FindPort(@"USB\\VID_2341&PID_8037");
}
public string FindPort(string searchID)
{
string standardOutput = COMPortUtil.COMPorts.Find(
this.COMUtileOutputHandler,
this.COMUtileErrorOutputHanlder,
this.COMUtileProcess_Exit);
var lines = Regex.Split(standardOutput, @"\r\n|\r|\n");
for(int i = 0;i < lines.Length; i++)
{
if(Regex.IsMatch(lines[i], searchID))
{
Match matchedObject = Regex.Match(lines[i + 1], @"COM\d+");
if (matchedObject.Value.Length >= 4)
{
string comPort = matchedObject.Value;
try
{
return comPort;
}
catch (System.IO.IOException ex)
{
Debug.LogError("Could not find port.");
return null;
}
}
}
}
Debug.LogError("Could not find port.");
return null;
}
private void COMUtileOutputHandler(object sender, System.Diagnostics.DataReceivedEventArgs args)
{
}
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, System.EventArgs e)
{
System.Diagnostics.Process proc = (System.Diagnostics.Process)sender;
// proc.Kill();
}
}
あとはcomPortNameを使ってシリアルポートをオープンするだけ