2014-09-13 97 views
1

我有统一C#脚本扫描可用的串行端口连接到NeuroSky公司。但是,这是一个手册检测,这只适用于ThinkGear连接器的起始端口号为COM9的计算机。团结与NeuroSky公司 - 端口扫描

void setupNeuro() { 
    tgHandleId = ThinkGear.TG_GetNewConnectionId(); 
    tgConnectionStatus = ThinkGear.TG_Connect(tgHandleId, 
               "\\\\.\\COM9", 
               ThinkGear.BAUD_9600, 
               ThinkGear.STREAM_PACKETS); 
    } 

如何编辑这个C#脚本自动检测从COM1权端口COMxx?

+1

读什么标签是使用它之前。 – Mephy 2014-09-13 03:41:47

回答

1

这不是一个Unity问题,而是一个C#问题。 ThinkGear文档提到用户应该实现端口扫描,但我不记得提供了任何实现,但提供了存储以前端口的建议。

不幸的是,没有真正优雅的方法来实现这一点,但有一些方法。

你可以做的最好的事情是循环通过端口,直到你得到一个不超时,但这意味着每个检查需要至少2秒。更糟糕的是,您必须从Unity的.NET中获取连接串行端口的唯一方法并不保证是最新的。这意味着您可能会以非常缓慢的方式列举大量串行端口。

为了减少搜索时间,你应该按以下顺序进行搜索:

  • 末端口使用的是(在PlayerPrefs存储这个)

  • 通过SerialPort.GetPortNames返回的所有端口。不会有太多,但不幸的是,并不能保证它们全都存在,因为正如文档所说,SerialPort.GetPortNames会检查并非总是最新的注册表值。

  • 端口0-10如果您还没有检查过它们。

  • 端口10 - 256,但见下文。此时,您至少必须让用户有机会自己进入港口,或者向他们发出警告,告知下一步需要多长时间。

    我不会推荐走这么远(最长8分钟的搜索声音是否合理?)。你已经花了20秒钟扫描前10个端口。这可能是值得

    • 显示用户如何找到合适的端口自己
    • 写一个小的外部程序使用lower level方法来显示正确的端口供用户输入每个平台。
    • 从特定于操作系统的库访问这些较低级别的方法,并从Unity访问它以将您的搜索限制为有效端口。这是我的选择。

检查端口是这样的(因为使用协同程序的需要拉姆达):

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); 
} 

关于代码的注意事项:这并不优雅,它甚至可能不会编译(虽然它不会执行任何操作)不可能)。把它作为非常有说服力的伪代码,并用它作为你的基础。

0

环路直通的已知端口代替COM号到连接字符串,直到您运行的端口(无任何连接),或者找到一个...