2010-01-06

使用NXC在程式中建立藍芽連結的方式

NXT的程式如果有需要使用藍芽來進行通訊時, 通常必須先以手動方式建立好連結之後, 再啟動程式的執行, 不過若使用John Hansen enhanced firmware的加強功能, 就可以直接在程式中啟動建立藍芽連結的程序, 省掉手動操作的步驟.


以下就說明如何以NXC來建立藍芽連結的方法.


NXC Comm module API用法說明


NXT firmware Comm module中有許多關於藍芽通訊的功能, 稱為Primary functions, 詳細的功能清單可以參考” NXC Programmer’s Guide” P40的表格, 在表格中的第4個功能: INTF_CONNECT亦即為建立藍芽連結的Primary function, 而執行這些Primary function的NXC API有以下兩個:


l   SysCall(funcID, args) - API用法請參考” NXC Programmer’s Guide” P42說明


這個API是用來執行NXT firmware內建的33個系統功能, 詳細的項目可以參考”LEGO MINDSTORMS NXT Executable File Specification” P55, 不過如果是John Hansen的enhanced firmware就額外多了5個加強功能, 其中CommExecuteFunction就是藍芽通訊功能的Function ID, 也是第1個參數funcID的值.


而第2個參數args則是依據不同Function ID所需求的struct 型態去宣告出來的變數, struct 所定義的member field 用來作為執行Function ID系統功能所需要的參數, 而CommExecuteFunction Function ID所使用的struct型態定義為:


struct CommExecuteFunctionType {
  unsigned int Result;
  byte Cmd;
  byte Parm1;
  byte Parm2;
  byte Parm3;
  string name;
  unsigned int RetVal
};


在NXC已經內建定義了這個struct型態, 因此可以直接引用來宣告args參數變數:


CmmExecuteFunctionType args;


而args的struct各個member field的指定值為:


args.Cmd欄位存入INTF_CONNECT這個Primary function值, 表示要執行建立藍芽連結的功能:


args.Cmd = INTF_CONNECT;


接下來參考” NXC Programmer’s Guide” P40表格的第3欄(Parm1,Parm2,Parm3,Name),













Cmd



Meaning



(Parm1,Parm2,Parm3,Name)



INTF_CONNECT



Connect to a Bluetooth device



(DeviceIndex,Connection,x,x)



對於INTF_CONNECT這個Primary function, args的4個member fields參數 (Parm1,Parm2,Parm3,Name)使用的定義為: (DeviceIndex,Connection,x,x), 所以args.Parm1存放的是Slave裝置在藍芽配對清單中的索引編號, 可以使用Brick name到Bluetooth Device table中搜尋, 而若只有一筆則設成0即可,


args.Parm1 = 0;


args.Parm2存放對Slave裝置的Connection channel, 通常是1-3, 若只對單一Slave建立連結, 則設成1即可,


args.Parm2 = 1;


因此, 呼叫SysCall(funcID, args)函數的相關參數指派方式如下:


CmmExecuteFunctionType args; //宣告參數變數args


args.Cmd = INTF_CONNECT;  //指定Primary function


args.Parm1 = 0;               //Slave device index


args.Parm2 = 1;               //Connection channel


SysCall(CommExecuteFunction, args);


l   SysCommExecuteFunction(args) - API用法請參考” NXC Programmer’s Guide” P39說明


這個API事實上就相當於SysCall(CommExecuteFunction, args), 所以參數args的用法相同, 而呼叫SysCommExecuteFunction(args)函數的參數指派方式如下:


CmmExecuteFunctionType args; //宣告參數變數args


args.Cmd = INTF_CONNECT;  //指定Primary function


args.Parm1 = 0;               //Slave device index


args.Parm2 = 1;               //Connection channel


SysCommExecuteFunction(args);


實作範例說明


在以下的程式範例, Master NXT會先檢查是否已經與Slave NXT建立藍芽連結, 若沒有則進行建立連結的程序, 隨後remote start Slave NXT程式的執行.


Slave NXT的相關資料如下:


-  Brick name: "CH_NXT_B"


-  Connection channel: 1


-  Remote start program: "NRLink-8183CPM3.rxe"(NXT Remote control L8183 Racer driving unit)


l   檢查藍芽連結狀態:


if (BluetoothStatus(BtChannel) == NO_ERR) isOK = TRUE;     //檢查連結狀態
else if (Build_Connection(BtChannel, BtDevname)) isOK = TRUE;//
若無則建立連結
    else …


l   以NXT Brick name搜尋Bluetooth Device table以取得Device index:


byte idx  = 0;
for (byte xii=0; xii<BTDeviceCount(); xii++) //
Search Bluetooth device table
{
   if (BTDeviceName(xii) == BtDevname)  //
If matched
   {
     idx  = xii;                        //
Get device index
     isOK = TRUE;
     break;
     }
 }


l   建立藍芽連結:


CommExecuteFunctionType cefArgs; //宣告參數變數
cefArgs.Cmd  = INTF_CONNECT; //
Primary function
cefArgs.Param1 = idx;            //
Slave Device index
cefArgs.Param2 = BtChannel;      //Connection channel

isOK  = FALSE;
for (byte xii=0; xii<20; xii++)      //
測試20次直到連結成功
{
   SysCommExecuteFunction(cefArgs);//
建立藍芽連結
   Wait(500);
   if (cefArgs.Result == LDR_SUCCESS)
   {
     isOK = TRUE;
     break;
    }
}


l   Master端完整的範例程式在此(NXTCommM01.nxc)


 


沒有留言:

張貼留言