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)