買書捐殘盟

2011年8月13日 星期六

利用藍芽技術,讓電腦可控制NXT主機

NXT Brick本身已內建藍芽裝置,對於想透過藍芽技術對NXT予以控制的玩家早已躍躍欲試。
目前已有相當齊備的文獻:
1.有些玩家透過兩台NXT,一台當作Master、一台當作Slave,由Master主機對Slave進行直接控制。
2.透過電腦PC與NXT,由電腦端(主控端)傳送控制指令(Send Message),並由NXT回饋數值給主控端。
3.利用Android 手機與NXT,傳送控制指令(Send Message)對NXT下達操作指令。


本文旨在建立Visual Basic 介面,利用藍芽技術,由電腦操控NXT

一、首先,利用Visual Basic Express ,建立一個操控界面

     (圖一)

上圖,通訊埠預設COM1~4,依使用者需要自行增加,通訊埠請選擇[VB工具箱/元件/SerialPort]物件,把該物件拖曳至介面中。

二、介面中的[通訊埠],每一個選項(COM1~4),假設使用者選擇COM1,程式會先判斷目前電腦是否與NXT連線,如早已連線,會先中斷連線,並再次連線,以確保不重複連線的問題。
    COM1ToolStripMenuItem.Checked = True

    COM2ToolStripMenuItem.Checked = False
    COM3ToolStripMenuItem.Checked = False
    COM4ToolStripMenuItem.Checked = False
    If SerialPort1.IsOpen() Then
      SerialPort1.Close()
    End If
    SerialPort1.PortName = COM1ToolStripMenuItem.Text
    SerialPort1.Open()
    ConnText.Text = "已連線"
上述部分的程式碼,其中
1.COM1ToolStripMenuItem是介面中COM1的選項Name,COM1ToolStripMenuItem.Checked用以告知使用者當前選擇哪一個通訊埠,會在該選項出現打勾
2.使用者該選擇哪一個通訊埠?請打開電腦藍芽選項,先讓電腦搜尋可與電腦藍芽連線的裝置,當然,你一定要記得先打開NXT的電源以及藍芽(ON),才能讓電腦搜尋的到。當使用者找到NXT後,會要求使用者輸入密碼,預設為1234,因此在電腦輸入1234的密碼後,便與NXT匹配連線了
3.此時,點選可與電腦連線的裝置兩下,可看到設定的選項,其中[輸出序列埠]就是預備和NXT連線的對外通訊埠。這個通訊埠即我們要選擇的。


三、介面中有[前進]、[後退]、[向左]、[向右]四個按鈕,使用者按下按鈕後,會傳出指令給NXT,因此相關設定的程式碼如下:
  Dim byteOut(9) As Byte
  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")
  byteOut(7) = Asc(" ") ' space ASCII code
  byteOut(8) = &H0 'null terminator
  SerialPort1.Write(byteOut, 0, 9)

1.上述程式碼是[前進]按鈕的功能。其他[後退]、[向左]、[向右]程式碼均相同,可複製貼上至其他按鈕。
2.唯一需要修改的,在於byteOut(6)。茲設定的[前進],當按下按鈕時,送出字元F;
[後退]送出字元B;[向左]送出字元L;[向右]送出字元R
3.byteOut為電腦與NXT之間通訊的方式,相關文獻可參考[NXTreme]、[研發養成所]及[VB and Connecting the NXT with Bluetooth]
4.電腦傳輸命令至NXT,是送到指定的信箱(MAILBOX),所以byteOut(4)=&H0是MAILBOX1,由使用者自行定義要傳到哪一個信箱,以便NXT接收。當然,NXT的程式碼,其收件信箱也要指定相同的MAILBOX,投遞與接收要相同。

至此,VB的通訊介面業已底定。
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
其次,NXT的接收程式碼,茲以Brixcc的NXC碼編寫,程式碼如下:

#include "NXCDefs.h"


#define MAILBOX1 0
#define Touch IN_1

void BTCommCheck(int conn)
{
if (BluetoothStatus(conn)!=NO_ERR) //如果nxt未與主機連線
{
TextOut(5,LCD_LINE2,"Error");
Wait(1000);
Stop(true);
}
}

//-----------------------------------------
task main()
{
string ControlMessage;
BTCommCheck(0);
SetSensorTouch(Touch);
ClearScreen();
while(SENSOR_1==0)
{
ReceiveRemoteString(MAILBOX1,true,ControlMessage);
TextOut(0,LCD_LINE1,ControlMessage);
}
}
1.程式開啟後,NXT會先檢查是否與PC連線,如果未連線,則出現ERROR畫面並結束程式,使用者必須先啟動前述建立的VB介面軟體,點選通訊埠連線
2.連線後,當使用者在VB介面軟體按下[前進]、[後退]、[向左]、[向右]任一按鈕,則於NXT畫面顯示相對應的字元(F、B、L、R)
3.BTCommCheck(0)之引數0,代表NXT設定為slave端。
4.從電腦發送的命令,直至NXT接收,本身為字元,所以設定一個變數ControlMessage接收之

3 則留言:

  1. 關於電腦與nxt之間的通訊,可參考Lego mindstorms nxt'reme(Lego Mindstorms NXT Direct commands).

    文件下載網址http://smart-robot.googlecode.com/files/Appendix%202-LEGO%20MINDSTORMS%20NXT%20Direct%20commands.pdf

    回覆刪除
  2. hi 薛老師您好:

    想請問一下
    目前我寫VB.NET和NXT做雙向溝通時遇到一個問題
    訊息在pc和nxt傳遞並無問題

    但唯一奇怪之處是VB.NET裡serialport的DataReceived 事件無法被觸發,但程式強制去讀取,是可以讀到資料的

    也就是必須在VB.NET的程式裡不斷讀取,才能即時取到nxt送出的訊號,不曉得這部份會是哪邊出了問題,還是NXT和PC的溝通本來就是這 ??

    網路上蠻多人遇到這類藍芽的問題,無法在NXT送出訊號時,就觸動VB.NET上的事件

    回覆刪除
  3. 陳玟志您好:
    關於您的問題,我想到的也許是鮑率(Baud rate)設定的問題。在VB.net使用serial port,在屬性設定上調小BaudRate值。

    回覆刪除