置頂文字

歡迎來訪 !! 如有任何問題歡迎一起討論或是 eMail 給我 legorunmail@Gmail.com

2015年4月27日 星期一

兩台樂高機器人NXT 分工合作



 這次要做的題目是2台樂高機器人NXT 分工合作,而且盡可能把感應器都裝在NXT上這樣在程式設計時就能互相運用做出多樣化的動作與目的。



第一台樂高NXT機器人是「履帶車輛」,前面安裝超音波感應器(UltraSonic Sensor)與光線感應器(Light Sensor),後面安裝爪子與顏色感應器(Color Sensor)。


超音波感應器:負責偵測前方式否有物體存在。
光線感應器:負責車輛行駛在黑色路線軌跡上。


顏色感應器:負責偵測地面上特定顏色做出對應事件動作。






第二台樂高NXT機器人是「機械手臂」,安裝超音波感應器(UltraSonic Sensor)或碰觸感應器(Touch Sensor)負責偵測是否有物品需要抓取。


三顆樂高馬達(Motor)使用內建的角度偵測,所以抓取與放置都能固定在特定位置上。
第二顆升降馬達與第三顆抓取馬達構造圖



第一顆轉向馬達與第二顆升降馬達齒輪連結






當第三顆馬達抓取物品時齒輪經過轉向帶動下個齒輪與傳動軸會產生其它方向應力讓零件慢慢位移是甚至解體,因此在組裝上必須考量結構強度與預防零組件位移措施。


int iTch=Motor.A.getTachoCount();     //讀取A馬達角度值
Motor.A.resetTachoCount();                 //重設A馬達角度值


測試步驟:

1. Android手機與第一台樂高機器人藍芽連結並啟動NXT程式(非必要性只是測試Android手機與樂高機器人的互動)

2.光線感應器先偵測黑色與白色的反射數值當作黑色軌跡路線的判斷標準

3.當第一台NXT在軌跡路線上(PID)運行時,如果超音波感應器遇到前方12公分內有物品時,車輛迴轉180度讓後方的爪子去抓取物品,抓取物品後車輛再迴轉180度繼續在軌跡路線上前進,此時顏色感應器啟動偵測路面上是否有顏色標示。

4.當顏色感應器偵測到特定顏色時開始執行「放置物品」的對應動作


綠色:「右轉」直行一段距離放在固定位置,此時第二台樂高機器人的超音波感應器或碰觸感應器被觸動執行抓取物品然後放在固定位置(預計放在黑色路線上讓第一台樂機器人繼續抓取),如此一直無線迴圈讓兩台樂高機器人一直運作。(外加動作是BT向手機傳遞訊息如顏色)

藍色:不動作

紅色:不動作

黃色:不動作


5.當遇到「綠色」標示時第一台NXT會右轉後前進一段距離放置物品再回到黑色軌跡路線上,此時第二台NXT機器手臂的超音波感應器或碰觸感應器會偵測到有物品需要抓取,因此啟用抓取程式讓NXT機器手臂移動物品放置。


硬體與軟體

硬體組裝:用樂高零件組裝結構性與強度足夠的「履帶車輛」與「機器手臂」。

軟體設計:按照測試流程來設計程式,第一台樂高NXT動作多程式比較複雜,第二台樂高機器手臂動作固定程式碼較少。

Lejos 是架構在 Java語言下因此程式結構與延伸完整,本次程式設計運用行為模式(Behavior)因此可以把軌跡車、超音波偵測、顏色偵測等各自撰寫獨立的Class測試,最後再定義各種動作(軌蹟車、超音波、顏色感應)的優先順序一起整合運用,擺除以往把3顆馬達、所有Sensor動作與變數檢查都寫在一起有時候都不知道是那個環節出錯( Debug花費時間比寫程式還多)。



DIY場地:各色膠帶 + 白色真珠板.....準備測試。




YouTube影片資料














2015年4月14日 星期二

Android手機方向感應器與樂高NXT配合應用

當手機有方向感應器(ORIENTATION)能分辨東西南北時便可以把資訊分享給樂高NXT機器人作為判斷方向的用途

首先要了解Android方向感應器的三個數值的定義eventvalue

方位角 Value[0]:0代表北方、90代表東方、270代表西方、180代表南方 .............共360度

南北向 Value[1]:南北旋轉向...手機水平螢幕朝上=(0)、手機直立=(-90)、手機倒立=(90)、手機水平螢幕朝下=(正負180)

東西向 Value[2]:東西向旋轉...手機水平螢幕朝上=(0)、手機向右翻(-90)、手機向左翻(90)、手機水平螢幕朝下=(0)

方向感應器與3軸加速器的不同處在於方向感應器有「方位角」因此能分辨東西南北。

2015年4月10日 星期五

Android 三軸加速感應器與 Lego NXT 應用

Android 手機裡面有個Accelerometer 加速感應器,它的作用就是能即時知道手機的移動或翻轉位置狀態如下圖所示

X軸為「左右翻轉」的加速度
Y軸為「前後翻轉」的加速度
Z軸為「上下移動」的加速度




利用這個特性我們就可控制 Lego NXT 在行走時能左右轉或是加速、煞車、前進、後退
X軸往左翻負值、往右翻正直--->控制車子左右轉                      value:-10<=X軸<=10
Y軸往前翻負值、往後翻正直--->控制車子往前加速 往後煞車 value:-10<=Y軸<=10
Z軸目前用不著






App執行後的步驟
1.把樂高NXT啟動、藍芽開啟並執行程式等待手機App的藍芽連結此時顯示「Waiting」。
2.按下App「藍芽連結」鈕如果找到樂高NXT並連結成功後會顯示「Connected」,樂高會把爪子打開後關閉一次代表連結成功。
3.啟動App讀取手機上的三軸加速器資料,並把資料傳給樂高NXT接收與執行對應動作
A.X軸在正負2的數值內保值前進或後退,超過正負2代表要樂高要左轉或右轉
B.Y軸在直立超過9時代表樂高NXT要停止不動,其餘時候是前進或後退













2015年4月9日 星期四

Android 手機透過藍芽與 NXT Lejos 應用

 NXT主機上有藍芽BlueTooth因此能傳送與接收其他裝置的藍芽資料,本篇要實做用一般常見的Android手機與Lego NXT主機透過藍芽做資料交換。

準備的物件
1.Android手機一隻新舊款沒關係但要有藍芽功能。
2.Lego Mindstorms NXT 或EV3,馬達3顆接 A、B、C Port
3.先將手機與NXT 的藍芽都打開,讓手機尋找NXT主機內定密碼為1234,連結成功後手機上就有這台NXT的資訊與名字作為手機App要連結的目標。

由於Android手機有很多Sensor如重力感應器、方向感應器、光線感應器、GPS等如能加以應用等於幫NXT省下不少外購Sensor費用。

如果大家有淘汰的Android手機可以試試看本篇的應用。

一部份開發 Android App程式:

我在App主畫面上放了 9個 Button以方便未來擴充應用

執行 App 程式的主畫面


顯示手機上 Sensor 資訊




原始碼如下:開發環境 Eclipse 與 Android、Lejos套件

package com.example.lego_android;

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.graphics.Color;
import android.view.Window;
import android.widget.*;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.text.TextPaint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import java.util.*;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import android.content.*;


public class MainActivity extends Activity {

private  int MP=LinearLayout.LayoutParams.MATCH_PARENT;
private  int WC=LinearLayout.LayoutParams.WRAP_CONTENT;
private TableRow.LayoutParams view_layout2;
 private TextView txtID;
 private TextView txtSync;
 private TextView txtTitle01;
 private TextView txtTrending;
 private TextView txtTitle02;
 private String strTimeCnt="";
 private TextView txtVer;
 private boolean chkvername=false;
 private String strVer="";
 private int ifisze=18;
 private int iChnl=0;  
 private String strTitleH="LegoRun 資 訊 管 理";
 
 
   private BluetoothAdapter adapter;
private BluetoothSocket nxtSocket;
public DataInputStream nxtDataIn;
public DataOutputStream nxtDataOut;
   public final int MODE_CONTROL = 1;
   private int mode;
 
   private boolean bConnect_NXT=false;
   private String NXTUUID = "00001101-0000-1000-8000-00805F9B34FB";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

LinearLayout layout=new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);    
        layout.setLayoutParams(new LinearLayout.LayoutParams(MP,MP));
        layout.setBackgroundColor(Color.rgb(19,92,160));

        //標題隱藏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(layout);
     
     
        TableLayout tl= new TableLayout(this);
        tl.setLayoutParams(new LinearLayout.LayoutParams(MP,MP));
        tl.setBackgroundColor(Color.parseColor("#333333"));
        tl.setStretchAllColumns(true);
        layout.addView(tl);  
     
 
        TableLayout.LayoutParams row_layout_mid = new TableLayout.LayoutParams();
        row_layout_mid.weight=1f;
        row_layout_mid.setMargins(0,1,0,1); //setMargins(left, top, right, bottom);

        TableLayout.LayoutParams row_layout_max = new TableLayout.LayoutParams();
        row_layout_max.weight=8f;
        row_layout_max.setMargins(0,1,0,1); //setMargins(left, top, right, bottom);

        TableLayout.LayoutParams row_layout_min = new TableLayout.LayoutParams();
        row_layout_min.weight=0.2f;
        row_layout_min.setMargins(0,1,0,1); //setMargins(left, top, right, bottom);

        TableRow.LayoutParams view_layout1 = new TableRow.LayoutParams(MP,MP);
        view_layout1.span=2;

        view_layout2 = new TableRow.LayoutParams(getScrWH(MainActivity.this)[0]/2,MP);
        view_layout2.setMargins(1,0,0,0);

        TableRow tr1 = new TableRow(this);
        tr1.setLayoutParams(row_layout_mid);
        tr1.setGravity(Gravity.CENTER_HORIZONTAL);
        txtTitle01 = new TextView(this);
        txtTitle01.setLayoutParams(view_layout1);
        txtTitle01.setText(strTitleH);
        txtTitle01.setBackgroundColor(Color.parseColor("#00C9C9"));  //#46C7C7
        txtTitle01.setGravity(Gravity.CENTER);
        TextPaint tp = txtTitle01.getPaint();
        tp.setFakeBoldText(true);
        txtTitle01.setTextColor(Color.parseColor("#EEEEEE"));
        txtTitle01.setOnClickListener(new ButtonClickListener());
        txtTitle01.setTextSize(ifisze);
        txtTitle01.setTag("txtTitle01");
        tr1.addView(txtTitle01);
        tl.addView(tr1);

        TableRow tr2 = new TableRow(this);
        tr2.setLayoutParams(row_layout_mid);
        tr2.setGravity(Gravity.CENTER_HORIZONTAL);
        txtTitle02 = new TextView(this);
     
     
        txtTitle02.setText("尚未連結Lego NXT...");
     
        txtTitle02.setTextSize(18);
        txtTitle02.setLayoutParams(view_layout1);
        txtTitle02.setGravity(Gravity.CENTER);
        txtTitle02.setBackgroundColor(Color.WHITE);
        tr2.addView(txtTitle02);
        tl.addView(tr2);


        TableRow tr3 = new TableRow(this);
        tr3.setLayoutParams(row_layout_max);
        tr3.setGravity(Gravity.CENTER_HORIZONTAL);
        tl.addView(tr3);

        LinearLayout layoutBrick=new LinearLayout(this);
        layoutBrick.setOrientation(LinearLayout.VERTICAL);
        layoutBrick.setLayoutParams(view_layout1);
        layoutBrick.setBackgroundColor(Color.parseColor("#95B9C7"));
        tr3.addView(layoutBrick);


        TableLayout tl_Brick= new TableLayout(this);
        tl_Brick.setLayoutParams(new LinearLayout.LayoutParams(MP,MP));
        tl_Brick.setBackgroundColor(Color.parseColor("#FFFFFF"));
        tl_Brick.setStretchAllColumns(true);
        layoutBrick.addView(tl_Brick);

        TableLayout.LayoutParams row_layout_Brick = new TableLayout.LayoutParams();
        row_layout_Brick.weight=1f;
   
        TableRow.LayoutParams view_layout_Brick = new TableRow.LayoutParams(MP,MP);
        view_layout_Brick.weight=0.7f;
 
     
        int ibtn=0;
        for(int i=0;i<=2;i++){

            TableRow tr_Brick = new TableRow(this);
            tr_Brick.setLayoutParams(row_layout_Brick);
            tr_Brick.setGravity(Gravity.CENTER_HORIZONTAL);
            tl_Brick.addView(tr_Brick);

            for(int j=0;j<=2;j++){
                Button btn_Brick = new Button(this);
                btn_Brick.setLayoutParams(view_layout_Brick);              
                btn_setup(btn_Brick,ibtn); //設定按鈕外觀圖形
                btn_Brick.setOnClickListener(new ButtonClickListener());
             
                tr_Brick.addView(btn_Brick);
                ibtn++;
            }

        }



        TableRow tr4 = new TableRow(this);
        tr4.setLayoutParams(row_layout_min);
        tr4.setGravity(Gravity.CENTER_HORIZONTAL);

        txtTrending = new TextView(this);
        txtTrending.setText("資料設定");
        txtTrending.setTextSize(18);
        txtTrending.setLayoutParams(view_layout1);
        txtTrending.setGravity(Gravity.CENTER);
        txtTrending.setTag("txtTrending");
        txtTrending.setOnClickListener(new ButtonClickListener());
        txtTrending.setBackgroundColor(Color.parseColor("#E5E4E2"));
        tr4.addView(txtTrending);
        tl.addView(tr4);


        //-------------------------------------------
        TableRow tr5 = new TableRow(this);
        tr5.setLayoutParams(row_layout_mid);
        tr5.setGravity(Gravity.CENTER_HORIZONTAL);

        txtID = new TextView(this);
        setTxtView(txtID,"帳 號 設 定","txtID");
        tr5.addView(txtID);

        txtSync = new TextView(this);
        setTxtView(txtSync,"資 料 更 新","txtSync");
        tr5.addView(txtSync);

        tl.addView(tr5);

        //----------------------------------------------
        TableRow tr6 = new TableRow(this);
        tr6.setLayoutParams(row_layout_mid);
        tr6.setGravity(Gravity.CENTER_HORIZONTAL);

        TextView txtHelp = new TextView(this);
        setTxtView(txtHelp,"使 用 說 明","txtHelp");
        tr6.addView(txtHelp);

        txtVer = new TextView(this);
        setTxtView(txtVer,"版 本 資 訊","txtVer");
        tr6.addView(txtVer);
        tl.addView(tr6);
     
     
     
        //藍芽啟用
        adapter = BluetoothAdapter.getDefaultAdapter();
        if(adapter==null)
        {
        Toast.makeText(getApplication(), "No Bluetooth adapter found", Toast.LENGTH_SHORT).show();
        this.finish();
        }
     
    if(!adapter.isEnabled())
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE), 1);
   
   


}




@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

public int[] getScrWH(Activity activity){
        int scrWH[]={0,0};
        DisplayMetrics dm = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
        scrWH[0] = dm.widthPixels;
        scrWH[1] = dm.heightPixels;
        return scrWH;
    }


//按鈕事件
class ButtonClickListener implements OnClickListener  {
        // onClick 方法(觸碰按鈕時的事件處理器)
        public void onClick(View v){
            //取得 tag
            String tag = (String)v.getTag();

            if (tag.equals("btn0")){
           
            if(((Button)v).getText().equals("藍芽連結")){
           
            txtTitle02.setText("尋找藍芽中...");            
            //開啟藍芽
            if(connectNxt())
            ((Button)v).setText("關閉藍芽");
            }else{
            try {
            txtTitle02.setText("傳送功能 = 關閉藍芽連結");
    nxtDataOut.writeInt(999);
    nxtDataOut.flush();            
            nxtSocket.close();
            bConnect_NXT=false;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            ((Button)v).setText("藍芽連結");
            }
           
            }
         
         
            //傳送資料
            if (tag.equals("btn1")){
            try {
           
            if(((Button)v).getText().equals("啟動馬達A")){            
            txtTitle02.setText("傳送功能 = 啟動馬達A");
            nxtDataOut.writeInt(0);
            nxtDataOut.flush();
            ((Button)v).setText("關閉馬達A");
            }else{
            txtTitle02.setText("傳送功能 = 關閉馬達A");
            nxtDataOut.writeInt(1);
            nxtDataOut.flush();
            ((Button)v).setText("啟動馬達A");
            }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}        
           
            }
         
            if (tag.equals("btn2")){
            try {
            if(((Button)v).getText().equals("啟動馬達B")){            
            txtTitle02.setText("傳送功能 = 啟動馬達B");
            nxtDataOut.writeInt(2);
            nxtDataOut.flush();
            ((Button)v).setText("關閉馬達B");
            }else{
            txtTitle02.setText("傳送功能 = 關閉馬達B");
            nxtDataOut.writeInt(3);
            nxtDataOut.flush();
            ((Button)v).setText("啟動馬達B");
            }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}        
           
            }
         
         
            if (tag.equals("btn3")){
            try {
            if(((Button)v).getText().equals("啟動馬達C")){            
            txtTitle02.setText("傳送功能 = 啟動馬達C");
            nxtDataOut.writeInt(4);
            nxtDataOut.flush();
            ((Button)v).setText("關閉馬達C");
            }else{
            txtTitle02.setText("傳送功能 = 關閉馬達C");
            nxtDataOut.writeInt(5);
            nxtDataOut.flush();
            ((Button)v).setText("啟動馬達C");
            }

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}        
           
            }
         
         
        }

    }

private boolean connectNxt()
    {
    if(bConnect_NXT){
    txtTitle02.setText("手機已經連結成功不須再次連結");    
    return false;
    }
   
    String name="NXT8547";
    BluetoothDevice nxt = null;
   
   
   
        Set devicesSet = adapter.getBondedDevices(); 
     
        if(devicesSet.size()==0)
        {        
        txtTitle02.setText("手機上無任何藍芽連結裝置");
        return false;
        }
     
        for (BluetoothDevice device : devicesSet)
        {
            if (device.getName().equals(name))
            {
            nxt = device;
                break;
            }
        }
     
        if(nxt==null)
        {        
        txtTitle02.setText("找不到Lego NXT name:"+name);
        return false;
        }
     
        try
        {        
nxtSocket = nxt.createRfcommSocketToServiceRecord(UUID.fromString(NXTUUID));
nxtSocket.connect();
nxtDataOut = new DataOutputStream(nxtSocket.getOutputStream());
nxtDataIn = new DataInputStream(nxtSocket.getInputStream());
}
        catch(IOException e)
{
       
        txtTitle02.setText("連結此裝置:"+name+" 失敗!!");
        return false;
}
   
        txtTitle02.setText("連結此裝置:"+name+" 成功!!");
    bConnect_NXT=true;
    return true;


    }

private void setTxtView(TextView v,String strText,String strTag){
        v.setText(strText);
        v.setTextSize(ifisze);
        v.setLayoutParams(view_layout2);
        v.setGravity(Gravity.CENTER);
        v.setBackgroundColor(Color.parseColor("#F3F3F3"));
        v.setTag(strTag);
        v.setOnClickListener(new ButtonClickListener());
    }

private void btn_setup(Button btn_Brick,int ibtn){
        Context context=getApplicationContext();    


        Drawable[][] image=new Drawable[9][2];
        image[0][0]=context.getResources().getDrawable(R.drawable.net_42_128);
        image[0][1]=context.getResources().getDrawable(R.drawable.net_42_72);

        image[1][0]=context.getResources().getDrawable(R.drawable.net_24_128);
        image[1][1]=context.getResources().getDrawable(R.drawable.net_24_72);

        image[2][0]=context.getResources().getDrawable(R.drawable.net_18_128);
        image[2][1]=context.getResources().getDrawable(R.drawable.net_18_72);

        image[3][0]=context.getResources().getDrawable(R.drawable.net_08_128);
        image[3][1]=context.getResources().getDrawable(R.drawable.net_08_72);

        image[4][0]=context.getResources().getDrawable(R.drawable.net_21_128);
        image[4][1]=context.getResources().getDrawable(R.drawable.net_21_72);

        image[5][0]=context.getResources().getDrawable(R.drawable.net_27_128);
        image[5][1]=context.getResources().getDrawable(R.drawable.net_27_72);

        image[6][0]=context.getResources().getDrawable(R.drawable.net_22_128);
        image[6][1]=context.getResources().getDrawable(R.drawable.net_22_72);

        image[7][0]=context.getResources().getDrawable(R.drawable.net_01);
        image[7][1]=context.getResources().getDrawable(R.drawable.net_23_72);

        image[8][0]=context.getResources().getDrawable(R.drawable.net_26_128);
        image[8][1]=context.getResources().getDrawable(R.drawable.net_26_72);





        String[][] strBtn=new String[9][2];
        strBtn[0][0]="藍芽連結";
        strBtn[0][1]="btn0";
        strBtn[1][0]="啟動馬達A";
        strBtn[1][1]="btn1";
        strBtn[2][0]="啟動馬達B";
        strBtn[2][1]="btn2";
        strBtn[3][0]="啟動馬達C";
        strBtn[3][1]="btn3";

        strBtn[4][0]="啟動光線";
        strBtn[4][1]="btn6";
        strBtn[5][0]="Fun05";
        strBtn[5][1]="btn7";

        strBtn[6][0]="Fun06";
        strBtn[6][1]="btn4";
        strBtn[7][0]="Fun07";
        strBtn[7][1]="btn5";
        strBtn[8][0]="Fun08";
        strBtn[8][1]="btn8";
     
     


     

        btn_Brick.setText(strBtn[ibtn][0]);
        btn_Brick.setTextSize(ifisze);
        btn_Brick.setTag(strBtn[ibtn][1]);
        //-------------
        int spacing=0;
        int width=btn_Brick.getMeasuredWidth();
        int height=btn_Brick.getMeasuredHeight();
        int txt_width=(int)(btn_Brick.getTextSize()*btn_Brick.getText().length());
        int txt_height=(int)(btn_Brick.getLineCount()*btn_Brick.getLineHeight());

        int img_width=0;
        int img_height=0;
        int content_height=0;
        int content_width=0;
        int padding_w=0;
        int padding_h=0;
        int isel=0;

        if(getScrWH(this)[0]>=720){
            img_width=image[ibtn][0].getIntrinsicWidth();
            img_height=image[ibtn][0].getIntrinsicHeight();
            isel=0;
        }else{
            img_width=image[ibtn][1].getIntrinsicWidth();
            img_height=image[ibtn][1].getIntrinsicHeight();
            isel=1;
        }
        content_height=txt_height+img_height+spacing;
        content_width=txt_width+img_width+spacing;
        padding_w=width/2-content_width/2;
        padding_h=height/2-content_height/2;
        btn_Brick.setCompoundDrawablesWithIntrinsicBounds( null,image[ibtn][isel], null, null);
        ////setMargins(left, top, right, bottom);
        //btn_Brick.setPadding(0,padding_h,0,0);
        btn_Brick.setCompoundDrawablePadding(padding_h/2);
        //----------------

    }

}


第二部份開發Lejos NXT 程式

import lejos.nxt.Button;
import lejos.nxt.ButtonListener;
import lejos.nxt.LCD;
import lejos.nxt.Motor;
import lejos.nxt.comm.BTConnection;
import lejos.nxt.comm.Bluetooth;

import java.io.DataInputStream;
import java.io.DataOutputStream;

import lejos.nxt.comm.*;
import lejos.util.Delay;


public class BT_Frm01 {

public static void main(String[] args)throws Exception  {
// TODO Auto-generated method stub

Button.ESCAPE.addButtonListener(new ButtonListener(){
public void buttonPressed(Button b){System.exit(1);}
public void buttonReleased(Button b){}
});


LCD.drawString("Waiting",0,0);
BTConnection btc = Bluetooth.waitForConnection(0, NXTConnection.RAW);
DataInputStream din = btc.openDataInputStream();
DataOutputStream dout = btc.openDataOutputStream();
LCD.drawString("Connected",0,0);

Motor.A.setSpeed(450);
Motor.B.setSpeed(450);
Motor.C.setSpeed(450);

while(true){
int iData=din.readInt();
LCD.clear();
LCD.drawString("value="+String.valueOf(iData),0,2);


if(iData==999){
btc.close();
System.exit(1);
break;
}

switch(iData){
case 0:
Motor.A.forward();
break;
case 1:
Motor.A.stop();
break;
case 2:
Motor.B.forward();
break;
case 3:
Motor.B.stop();
break;
case 4:
Motor.C.forward();
break;
case 5:
Motor.C.stop();
break;

}



Delay.msDelay(1000);

}


}

}


除了手機可跟NTX互動溝通外不同的NXT主機也可以互動,這是我用第一台NXT主機當控制器透過BT遙控第二台NXT車輛的影片,第一隻馬達控制前輪方向動作、第二隻馬達控制後輪前進後退動作