C# 与Neurosky的统一-端口扫描
我在Unity上有一个C#脚本,用于扫描可用的串行端口以连接到Neurosky。但是,这是一种手动检测,仅适用于ThinkGear连接器起始端口为COM9的计算机C# 与Neurosky的统一-端口扫描,c#,unity3d,unityscript,C#,Unity3d,Unityscript,我在Unity上有一个C#脚本,用于扫描可用的串行端口以连接到Neurosky。但是,这是一种手动检测,仅适用于ThinkGear连接器起始端口为COM9的计算机 void setupNeuro() { tgHandleId = ThinkGear.TG_GetNewConnectionId(); tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId,
void setupNeuro() {
tgHandleId = ThinkGear.TG_GetNewConnectionId();
tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId,
"\\\\.\\COM9",
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
}
如何编辑此C#脚本以自动检测从COM1到COMxx的正确端口?这不是一个统一问题,而是一个C#问题。ThinkGear文档提到用户应该实现端口扫描,但我不记得提供了任何实现,尽管提供了存储前一个端口的建议 不幸的是,没有真正优雅的方法来实现这一点,但有一些方法 你能做的最好的事情就是在端口之间循环,直到你得到一个没有超时的端口,但这意味着每次检查至少需要2秒钟。更糟糕的是,在Unity中,从.NET连接串行端口的唯一方法也不能保证是最新的。这意味着您可能会以非常慢的方式枚举大量串行端口 要最小化搜索时间,应按以下顺序搜索:
- 使用的最后一个端口(将其存储在PlayerPrefs中)
- 由返回的所有端口。不会有很多,但不幸的是,不能保证它们都存在,因为正如文档所说,SerialPort.GetPortNames检查的注册表值并不总是最新的
- 端口0-10(如果尚未检查)
- 端口10-256,但请参见下文。此时,您必须至少给用户一个机会自己输入端口,或者给他们一个关于下一步需要多长时间的警告
我不建议走这么远(长达8分钟的搜索听起来合理吗?)。您已经花了多达20秒的时间扫描前10个端口。也许值得一试
- 向用户展示如何自己找到正确的端口
- 为每个平台编写一个小的外部程序,该程序使用方法显示用户要输入的正确端口
- 从特定于操作系统的库中访问这些低级方法,并从Unity中访问,以将搜索限制在有效端口。这是我的选择
注意:代码并不优雅,甚至可能无法编译(尽管它没有做任何不可能的事情)。将其作为非常有说服力的psuedo代码,并将其用作您的基础。通过已知端口循环,将COM编号替换为连接字符串,直到端口用完(未连接)或找到一个是…在使用标记之前阅读标记。
IEnumerable AttemptHeadsetConnection(int portNumber,Action<int,int> headsetConnectedCallback, Action attemptCompletedCallback)
{
var connectionString = string.Format("\\\\.\\COM{0}",portNumber);//That string literal should be elsewhere
return AttemptHeadsetConnection(connectionString, headsetConnectedCallback, attemptCompletedCallback);
}
IEnumerable AttemptHeadsetConnection(string connectionString,Action<int,int> headsetConnectedCallback,Action attemptCompletedCallback)
{
connectionID = ThinkGear.TG_GetNewConnectionId();
connectionStatus = ThinkGear.TG_Connect(connectionID ,
connectionString,
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
if(connectStatus >= 0)
{
yield return new WaitForSeconds(2f); //Give the headset at least 2 seconds to respond with valid data
int receivedPackets = ThinkGear.TG_ReadPackets(handleID, -1);//Read all the packets with -1
if(receivedPackets > 0)
{
headsetConnectedCallback(connectionID,connectionStatus);
}
else
{
ThinkGear.TG_FreeConnection(handleID);
}
}
attemptCompletedCallback();
}
foreach(var serialPort in SerialPort.GetPortNames())
{
var connectionCoroutine = AttemptHeadsetConnection(serialPort,onFoundHeadset,onAttemptCompleted);
StartCoroutine(connectionCoroutine);
}