2009年5月9日 星期六

VB - Communication with NXT over Bluetooth

http://4rdp.blogspot.com/2009/05/vb-communication-with-nxt-over.html

接續前一篇貼文,我們先設計一個六面體遙控程式,也就是點選程式上的按鍵,然後以藍芽遙控 LEGO MINDSTORMS NXT 正轉反轉 90 度,這裡用 NXC 設計 NXT 程式。

//
// Author: Bridan
//         http://4rdp.blogspot.com
// Date:   2009/05/09
//
// Brief:  Remote control NXT motor by bluetooth
//

#include "NXCDefs.h"

#define FRONT_C "F "
#define FRONT_R "F'"
#define CLEAR   true
#define INBOX1  0

sub BTCheck(int conn)
{
if (!BluetoothStatus(conn)==NO_ERR){
TextOut(5,LCD_LINE2,"Error");
Wait(1000);
Stop(true);
}

}

task main()
{
string   control;
string   str;

BTCheck(0);

while (true) {
ReceiveRemoteString(INBOX1, CLEAR, control);

if (control == FRONT_C) {
RotateMotor(OUT_A,50,90);
} else if (control == FRONT_R) {
RotateMotor(OUT_A,50,-90);
} else {
continue;
}

str = StrCat("Control = ",control);
TextOut(0, LCD_LINE1, str, true);
}
}


這裡先說明 NXC 程式,
BTCheck 副程式主要檢查 Bluetooth 通訊狀態,如果無法通訊就會在 NXT 螢幕上顯示錯誤,不然就正常執行顯示 Control = ,等待 PC 傳送控制命令。"F " 控制 Motor A 正轉 90 度,"F'" 反轉 90 度,這些字串是自行定義的,你也可以修改成其它,不過為了與全球接軌,我使用大家解魔方共通的符號,這在設計時應該考量,工程界稱這些通訊協定為 Protocol

NXT 透過 conn = 0 (slave) 與 PC (master) 通訊,每個 NXT 可以透過 conn = 1 ~ 3 (master) 再和其它 slave NXT 連線,slave 須使用 conn = 0 與 master 通訊。依據這樣通訊結構,其實可以連線 NXT 的上限不只四隻,如果你有很多 Bluetooth Dongle,那麼可以一個 Dongle 控制一隻 NXT,PC 直接控制多個 NXT;或是串聯控制,上層 NXT 控制下一層 NXT,這樣一層層串聯;或是樹狀串聯,甚至環狀串聯,我沒那麼多隻 NXT,這需要其它玩家協助證明。

值得注意 INBOX1 = 0,NXT 提供十個 Mailbox 給 Bluetooth 通訊使用,我只用 BOX1 也就是 NXT-G Mailbox1,但是在 NXC 的對應數值為 0,也就是 NXT-G Mailbox 1 ~ 10,對應 NXC 0 ~ 9,如果搞錯了你就連線不起來。 另外可參考 NXT 之間的通訊一文 (2009.10.17)。

MINDSTORMS NXT's reme 是 LEGO NXT 專業玩家必訪的技術聖地,它揭露 NXT 相關技術,從電路圖到韌體程式通通都有,想以 VB 用 Bluetooth 控制 NXT,應閱讀 Bluetooth Developer Kit (BDK) 中的 Direct Commands pdf 一文,相同的觀念也可以應用於其它程式語言,這裡只使用 MESSAGEWRITE 指令傳送字串,指令格式如下:


byteOut(0) = 2 + 5    '2 bytes in output message
byteOut(1) = &H0      'should be 0 for NXT
byteOut(2) = &H80     'Direct Command no reply expected
byteOut(3) = &H9      'MESSAGEWRITE
byteOut(4) = &H0      'Box Number - 1
byteOut(5) = 2 + 1    '2-byte message size with null terminator
byteOut(6) = Asc("F") ' F ASCII code
byteOut(7) = Asc(" ") ' space ASCII code
byteOut(8) = &H0      'null terminator

指令是一 byte 一 byte 傳送,byte 0、1 表示傳送指令長度但是不含這兩個,byte 2 = &H80 指令型態 NXT 無須回覆,byte 3 = &H9 MESSAGEWRITE 指令,byte 4 = 0 Mailbox1,byte 5 字串長度再加一個結尾字元,byte 6、7 是程式傳送的重點,byte 8 結尾字元,C 語言規範字串結尾字元為零,這樣子 NXC 程式才能正常接收執行,了解 NXT protocol 就可以自行制定修改。

再來說明如何在 VB 中加入通訊埠,







我的電腦使用 COM 6 與 NXT 通訊,讀者依據各自情況自行修改。


範例程式請點此下載。

PS. 網友 Sean 提到他遇到的問題,下圖為錯誤訊息顯示:



之所以會出現這情形,是因為那一個 OPEN 按鈕被按兩次,這個程式,並未加入防呆機制,當您按 OPEN 時,它可以正常開啟 COM port,此時顯示變成 Connected,表示已經連通。如果再被按,因為這個 COM port 已經開啟,不能再被開第二次,所以產生錯誤訊息。有興趣的朋友可以想一想,如何修改程式避免這樣問題。

21 則留言:

  1. 你好我們有下載您所分享的程式
    可是在COM更改時,卻無法連線
    想請問是為什麼呢?
    不曉的您是否可以分享您的E-MAIL
    我們想把所拍攝到的畫面給您看看
    還望您能幫我們解答
    y17101988@hotmail.com
    這是我們的E-MAIL
    我們有用NXC確定藍芽可以連線了
    也可以透過NXC做移動上的遠端操作
    可是透過您所寫的介面在com的連線就無法
    還望您能幫我們解答一下謝謝

    回覆刪除
  2. Hi Sean,

    歡迎您蒞臨 研發養成所
    關於您的問題,可能有幾項因素影響
    如果你的電腦使用 COM 3 是正常的,改到其他的 COM 當然是不行的,或是 其它的程式 先佔用該 COM 而未釋放,那麼後來的程式是無法連接的。

    這兩點請先釐清,如果都不是時,那就寄畫面給我參考。

    回覆刪除
  3. Dear Bridan:
    sub BTCheck(int conn){
    if(!BluetoothStatus(conn)==NO_ERR){
    TextOut(0,LCD_LINE3,"ConnectError");
    Wait(1000);
    }
    }

    task main(){
    BTCheck(0);
    }

    看不太懂!BluetoothStatus(conn)是要指定何值,才不會出現ConnetErr?

    ps.我的藍芽裝置設定:
    COM7 連出 NXT DevB
    COM8 連入 NXT

    回覆刪除
  4. 薛老師您好,

    關於藍芽通訊,您可以先參考 http://4rdp.blogspot.com/2008/04/lego-mindstorms-nxt-v2.html 一文,依據經驗電腦雖然可以顯示NXT,但並不表示完全連接正常,這是因為 Bluetooth SPP 連線區分兩種層次,第一層為Discovery,也就是兩個裝置可以相互發現,第二層為Link,需要特殊藍芽指令啟動連結,所以常常有網友反應藍芽已經接上但是通訊仍然不通。我不知道您的NXT firmware版本以及電腦驅動程式為何,為了確保正常連通,最簡單的方法,先接上USB再試Bluetooth連線,通常可以正常連線,這是我最近的發現。

    接下來,我假設您的NXT已經正常連上PC,藍芽裝置會出現兩個COM,一個連入一個連出,我是使用連出的那一個,從電腦到NXT,因為我的VB程式是單向傳送,VB程式須配合你的條件修改,現在想從NXT傳資料回來,可能需要測看看才知道。

    再來談談NXC程式,if條件看不懂,你可以把它修改為
    if (BluetoothStatus(conn)!=NO_ERR){
    也就是BluetoothStatus(conn)回傳NO_ERR時,就是連線正常,main()程式所執行的BTCheck(0);,conn就是代入0,代表資料往電腦傳送。

    回覆刪除
  5. 正在研究您這一篇VB communication.

    Bridan,您如何得知byteout0~8的設定?

    另外,範例程式在google論壇,似乎無法連結?(剛剛想下載參考,卻不可以)

    回覆刪除
  6. 薛老師您好,

    MINDSTORMS NXT's reme 是 LEGO NXT 專業玩家必訪的技術聖地,它揭露 NXT 相關技術,從電路圖到韌體程式通通都有,想以 VB 用 Bluetooth 控制 NXT,應閱讀 Bluetooth Developer Kit (BDK) 中的 Direct Commands pdf 一文,我是從此文得知的。

    另外,更新範例程式下載地點,可惜原有研發養成所線上論壇,Google 不再支援。

    若有問題再跟我聯繫,謝謝。

    回覆刪除
  7. Bridan:我已測試成功,可以從電腦發送,nxt 主機可接收到訊號

    明天我再整理到我自己網站。

    很有意思,下一步就可以從電腦傳送指令給nxt來進行動作!

    回覆刪除
  8. 薛老師您好,

    很高興知道您試驗成功,期待您的分享。

    回覆刪除
  9. 薛老師您好
    請問你新的範例程式存放位置在哪
    還有請問哪裡可學習nxc bluetooth

    回覆刪除
  10. 不好意思,反而占用Bridan版面討論我VB的程式。
    您可先連http://cmackimo.blogspot.com/2011/08/nxt.html

    內頁有VB藍芽的相關操作。有必要請email告訴我(master.yrhsieh@seed.net.tw)

    這個技術請益於Bridan,其實更應該請教Bridan。

    回覆刪除
  11. 薛老師及 Eddie 你們好,

    這裡是知識討論的開放園地,我只是起個頭而已,歡迎大家在此交流意見。

    回覆刪除
  12. Brudan 我想請問一下nxc的bluetooth可接收以android系統平版的藍芽嗎?

    回覆刪除
  13. Bridan對不起打錯你的名字

    回覆刪除
  14. Eddie 您好,

    NXT 可以接受任何符合藍牙 SPP 的裝置,並且之間通訊也要是 NXT Direct Command 的格式,CAVE 本月底即將出版 Android 與 NXT 控制書籍,推薦你參考。

    Apple 的 iPhone 及 iPad 未開放 Bluetooth SPP,因此 NXT 玩家無法自行設計這方面程式。

    回覆刪除
  15. 請問Bridan 提到android 控制nxt的書的書名稱是什?
    因為最近用Android 連nxc的藍芽一直失敗

    回覆刪除
  16. Eddie 您好,

    CAVE 的新書是 Android / NXT 機 器人大戰:智慧型手機控制機器人 ,請參考
    http://tw.myblog.yahoo.com/lego-caveschool/article?mid=6445

    回覆刪除
  17. 你好! 請問一下,
    如果我要從NXT傳一個值到PC 我該怎麼做呢?
    vb 和 nxc 要如何寫呢?
    (如果可以還請您回復完整的程式碼^^)
    因為我剛接觸NXC,所以不懂還請您多多幫忙。
    非常感謝!

    回覆刪除
  18. 翔您好,

    我提供的例子是 PC 單向傳值到 NXT,關於從 NXT 傳值回 PC,我是故意保留給 NXT 玩家去研究,因此手上並無範例程式可以供你參考。

    如果你手上有 CAVE 「機器人新視界 NXC & NXT」(第二版)一書,可以參考第十章有豐富 NXC 說明,書局或圖書館可以找看看,不然你就得看原文的 MINDSTORMS NXT's reme 。

    VB 的 COM INPUT 指令,就可以接收資料,細節找 VB 串列埠通訊的書或其他網路資源參考。

    回覆刪除
  19. 嗚~嗚~嗚~ Bridan 我還是搞不定拉 T.T

    請求支援! 我試過各種方法就是沒辦法從NXT傳資料到電腦捏。

    VB2008的接收是用data=SerialPort1.ReadByte()嗎?

    那NXT呢?是用
    #define BT_CONN 1
    #define OUTBOX 5
    .
    .
    .
    BTCheck(CONN);
    .
    .
    .
    SendRemotesString(BT_CONN,OUTBOX,i);


    這樣嗎?可是他就是沒辦法~ T.T 請您幫幫我! (我要程式碼拉~~ 拜託那~~)
    信箱 lucky861223@yahoo.com.tw

    回覆刪除
  20. 翔您好,

    這些天我公出在外,無法測試程式,只能猜測問題原因,首先修改
    #define BT_CONN 0
    NXT與PC相連,是0不是1,

    那個 readbyte 是一次一個byte 請注意,如果很多資料要讀很多次,祝你成功。

    回覆刪除
  21. 薛老師您好,

    謝謝你將Direct command 文件網址幫忙貼出, 其實這應該是想寫程式的學生,自己應該去找以及研究的。


    翔,

    如果還有問題,把程式貼出來,大家可以幫你看看問題。

    回覆刪除