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 functionNXC API有以下兩個:


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


這個API是用來執行NXT firmware內建的33個系統功能, 詳細的項目可以參考LEGO MINDSTORMS NXT Executable File Specification” P55, 不過如果是John Hansenenhanced 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;


argsstruct各個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, args4member fields參數 (Parm1,Parm2,Parm3,Name)使用的定義為: (DeviceIndex,Connection,x,x), 所以args.Parm1存放的是Slave裝置在藍芽配對清單中的索引編號, 可以使用Brick nameBluetooth 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)


 


沒有留言:

張貼留言