我在 Unity 上有 C#脚本来扫描可用的串口以连接 Neurosky 。但是,这是手动检测,这只适用于ThinkGear Connector的起始端口为 COM9 的计算机。
void setupNeuro() {
tgHandleId = ThinkGear.TG_GetNewConnectionId();
tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId,
"\\\\.\\COM9",
ThinkGear.BAUD_9600,
ThinkGear.STREAM_PACKETS);
}
如何编辑此C#脚本以自动检测从COM1到COMxx的正确端口?
答案 0 :(得分:1)
这不是Unity问题,而是C#问题。 ThinkGear文档提到用户应该实现端口扫描,但我不记得提供了任何实现,尽管提供了存储以前端口的建议。
不幸的是,没有真正优雅的方法来实现这一点,但有一些方法。
您可以做的最好的事情是循环通过端口,直到您得到一个没有超时的端口,但这意味着每次检查需要至少花费2秒钟。更糟糕的是,在Unity中从.NET连接串行端口的唯一方法也不保证是最新的。这意味着您最终可能会以非常缓慢的方式枚举大量串行端口。
为了尽量缩短搜索时间,您应该按以下顺序搜索:
使用的最后一个端口(将其存储在PlayerPrefs中)
SerialPort.GetPortNames返回的所有端口。不会有很多,但不幸的是,并不能保证它们都存在,因为正如文档所说, SerialPort.GetPortNames 检查的注册表值并非总是如此日期。
如果您尚未检查过端口0-10。
端口10 - 256,但请参见下文。此时,您必须至少给用户一个自己进入端口的机会,或者给他们一个关于下一步将花多长时间的警告。
我不建议走这么远(最多8分钟的搜索声音合理吗?)。您已经花了长达20秒的时间扫描前10个端口。
可能是值得的检查端口是这样的(由于使用协程,需要lambda):
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);
}
关于代码的注意事项:它不优雅,甚至可能无法编译(尽管它没有做任何不可能的事情)。把它作为非常有说服力的伪代码并用它作为你的基础。
答案 1 :(得分:0)
循环通过已知端口将COM编号替换为连接字符串,直到您用完了端口(没有连接)或找到一个...