2014-09-13 95 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號到連接字符串,直到您運行的端口(無任何連接),或者找到一個...