關於我自己

2012年6月8日 星期五

Android 藍芽連結NXT 控制馬達


The purpose of this thesis to research how to build a bluetooth connection between Android and LEGO-Mindstorm-NXT.

一開始用意不是做這個,是在做玩超音波的時候,

突然想到著不是跟台大研發的倒車雷達一樣嗎?

然後看著超音波偵測器想那跟手機結合那不是很好玩

又讓我想到RGB光源偵測器如果跟手機結合,那麼偵測器偵測到顏色把資料傳到手機,

手機在去呼叫聲音檔案例如:紅色叫聲 聲音檔案或者用手機的無線上網在另外傳送資料

所以才發著一篇 ~
(著一篇的Android 連結跟傳輸我並沒有寫分開有點令人詬病~所以請多多包涵)
==> 連結跟傳輸以分開(主程式碼已修改)



1.NXT 控制器左上角會顯示藍芽是否也連結的符號 (<:未連結       <>:已連結 ) 

 Note the screen in the upper-right corner of the picture ,
 symbol mean ( <:Not To Connect bluetooth   <>:To Connect bluetooth )

程式的介面(program interface):


 影片(Video):
 

開發環境: Windows 7 32Bit
使用:Eclipse + Android SDK + Java SDK

記得到AndroidManifest.xml寫入准許加入藍芽權限: 

you need to add the BLUETOOTH permission to your application

<uses-permission android:name=”android.permission.BLUETOOTH”/>
<uses-permission android:name=”android.permission.BLUETOOTH_ADMIN”/>



封包的格式: 下面的圖片是馬達封包的格式

要看比教詳細的介紹請看
 http://www.mindstorms.rwth-aachen.de/trac/wiki/MotorControl
Message format:開頭你會看到連結埠

然後參考馬達跟超音波的範例:
 http://cellbots.googlecode.com/svn-history/r15/trunk/android/Mindstorms_NXT/src/com/googlecode/cellbots/nxt/NxtConnectionService.java
你會看到
public int setMotor(String srcApp, int motor, int power) {  =>馬達
 public int setUltraSonicSensor(String srcApp, int port) { =>超音波

介面得程式碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開起藍芽裝置" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="搜尋藍芽裝置" />

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="連接藍芽裝置" />




    <Button
        android:id="@+id/button3"
        android:layout_width="146dp"
        android:layout_height="wrap_content"
        android:text="更新藍芽搜尋" />

    <Spinner
        android:id="@+id/spinner1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/button5"
        android:layout_width="190dp"
        android:layout_height="wrap_content"
        android:text="馬達A" />

</LinearLayout>
然後主程式碼:
package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;

public class MenuActivityActivity extends Activity {
   
    public static final String TAG = "test";
    private static final int REQUEST_ENABLE_BT = 2;
    public static final String MyUUID = "00001101-0000-1000-8000-00805F9B34FB";
    private ConnectThread mConnectThread;
    private ConnectedThread mConnectedThread;
    private TextView text_View1 ;
   
    BluetoothAdapter mBluetoothAdapter;
    ArrayAdapter<String> bondedDevices;
    ArrayAdapter<String> foundedDevices;
   
    Button turnOnButton, showPairedDevicesButton, scanForDevicesButton,connectButton,RunMotorA;
    TextView text;    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //=============== main.xml Set up =======================
        text_View1 = (TextView) findViewById(R.id.textView1);
        text = (TextView) findViewById(R.id.textView1);
        turnOnButton = (Button) findViewById(R.id.button1);
        showPairedDevicesButton = (Button) findViewById(R.id.button2);
        scanForDevicesButton = (Button) findViewById(R.id.button3);
        connectButton = (Button) findViewById(R.id.button4);
        RunMotorA = (Button) findViewById(R.id.button5);
       
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter != null) {text.setText("BlueTooth adapter found");}
       
        turnOnButton.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v) {
                turnOnBluetooth();
            }
        });

        showPairedDevicesButton.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v) {
                showPairedDevices();
            }
        });
       
        scanForDevicesButton.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v) {
                scanForDevices();
            }
        });
       
        connectButton.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v) {
                connectToDevice();
            }
        });
        RunMotorA.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v) {
                   int motor=0;    // NXT Port = 0:A Port , 1:B Port ,2:Port .....  
                   int power=50;
                   byte[] setCmd = new byte[13];
                        setCmd[0] = (byte) 0x80;
                        setCmd[1] = (byte) 0x04;
                        setCmd[2] = (byte) motor;
                        setCmd[3] = (byte) power;
                        setCmd[4] = (byte) 0x01;
                        setCmd[5] = (byte) 0x01;
                        setCmd[6] = (byte) 0x00;
                        setCmd[7] = (byte) 0x20;
                        setCmd[8] = (byte) 0x00;
                        setCmd[9] = (byte) 0x00;
                        setCmd[10] = (byte) 0x00;
                        setCmd[11] = (byte) 0x00;
                        setCmd[12] = (byte) 0x00;
                        long t2=0;            
                        while(1000>t2)
                        {
                            mConnectedThread.write(setCmd);
                            t2++;
                        }
            }
        });
        bondedDevices =  new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        foundedDevices =  new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
    }
   
    public void turnOnBluetooth(){
        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }
   
    public void showPairedDevices(){
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        // If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            for (BluetoothDevice device : pairedDevices) {
                // Add the name and address to an array adapter to show in a ListView
                bondedDevices.add(device.getName() + "\n" + device.getAddress());
                Log.d("debug",device.getName() + "\n" + device.getAddress() );
            }
        }
        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
        bondedDevices.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        s1.setAdapter(bondedDevices);
        s1.showContextMenu();
    }
   
 // Create a BroadcastReceiver for ACTION_FOUND
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // Add the name and address to an array adapter to show in a ListView
                foundedDevices.add(device.getName() + "\n" + device.getAddress());
                refreshNewDevices();
            }
        }
    };

    public void refreshNewDevices(){
        Spinner s2 = (Spinner) findViewById(R.id.spinner2);
        foundedDevices.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        s2.setAdapter(foundedDevices);
        s2.showContextMenu();
    }
   
    public void scanForDevices(){
        // Register the BroadcastReceiver
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
        mBluetoothAdapter.startDiscovery();
    }

    public synchronized void connectToDevice(){
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        BluetoothDevice stvorka = null;
        int t=0; // Device Count
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            for (BluetoothDevice device : pairedDevices) {
              //  if(device.getName().equals("stvorka"))
              //  stvorka = mBluetoothAdapter.getRemoteDevice(device.getAddress());
                  mConnectThread = new ConnectThread(device);
                  mConnectThread.start();
                  text_View1.setText(device.getAddress()+""+ t);
                  t++;     
            }
        }
        //  Start the thread to connect with the given device
        //  mConnectThread = new ConnectThread(stvorka);
        //  mConnectThread.start();
        //  text_View1.setText(stvorka.getName());
    }
   
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == REQUEST_ENABLE_BT){
                if(resultCode == Activity.RESULT_OK){
                        text.setText("Bluetooth enabled");
                }else if (resultCode == Activity.RESULT_CANCELED){
                        text.setText("Bluetooth not enabled");
                }
        }
    }
   
    /**
     * Start the ConnectedThread to begin managing a Bluetooth connection
     * @param socket  The BluetoothSocket on which the connection was made
     * @param device  The BluetoothDevice that has been connected
     */
    public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
        // Cancel the thread that completed the connection
        if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
        // Cancel any thread currently running a connection
        if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
        Log.d(TAG,"starting connecting to device");
        mConnectedThread = new ConnectedThread(socket);
        mConnectedThread.start();
    }

    public void move() {
        byte[] data = { 0x0c, 0x00, (byte) 0x80, 0x04, 0x02, 0x32, 0x07, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00 };
        int motor = 0;
        if (motor == 0) {
            data[4] = 0x02;
        } else {
            data[4] = 0x01;
        }
        data[5] = 0x20;
        if(mConnectedThread != null)
                mConnectedThread.write(data);
        else
                Log.d(TAG,"mConnectedThread is NULL");
    }
   
    /**
     * This thread runs while attempting to make an outgoing connection
     * with a device. It runs straight through; the connection either
     * succeeds or fails.
     */
    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;
       
        public ConnectThread(BluetoothDevice device) {
            mmDevice = device;
            BluetoothSocket tmp = null;
           
            try {
                tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(MyUUID));
            } catch (IOException e) {
                Log.d(TAG,"socket creation failed" ,e);
            }
            mmSocket = tmp;
        }
       
        @Override
        public void run() {
            setName("ConnectThread");
            Log.d(TAG,"running connected thread");
            mBluetoothAdapter.cancelDiscovery();
           
            try {
                mmSocket.connect();
                Log.d(TAG, "connection success");
            } catch (IOException e) {
                connectionFailed();
                Log.d(TAG,"connection failed" ,e);
                try {
                    mmSocket.close();
                } catch (IOException e1) {
                    Log.e(TAG,"connection failed" ,e);
                }
                return;
            }
            synchronized (MenuActivityActivity.this) {
                mConnectThread = null;
            }        
            connected(mmSocket, mmDevice);
        }
       
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * This thread runs during a connection with a remote device.
     * It handles all incoming and outgoing transmissions.
     */
    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;
        public ConnectedThread(BluetoothSocket socket) {
            Log.d(TAG, "create ConnectedThread");
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;
            // Get the BluetoothSocket input and output streams
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
                Log.d(TAG, "temp sockets not created", e);
            }
            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }
        public void write(int i) {
            // TODO Auto-generated method stub   
        }
        @Override
        public void run() {
            Log.d(TAG, "run listening");
            byte[] buffer = new byte[1024];
            int bytes;
           
            // Keep listening to the InputStream while connected
            while (true) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    Log.d(TAG, "listening.."+bytes);
                } catch (Exception e) {
                    Log.d(TAG, "disconnected");
                    connectionLost();
                    break;
                }
            }
        }

        /**
         * Write to the connected OutStream.
         * @param buffer  The bytes to write
         */
        public void write(byte[] buffer) {
            try {
               
                mmOutStream.write(buffer);
                Log.d(TAG, "sending to device"+buffer.toString());
            } catch (IOException e) {
                Log.d(TAG, "Exception during write", e);
            }
        }

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
                Log.d(TAG, "close() of connect socket failed", e);
            }
        }
    }
   
    /**
     * Indicate that the connection was lost and notify the UI Activity.
     */
    private void connectionLost() {
        // Start the service over to restart listening mode
        MenuActivityActivity.this.connectToDevice();
    }
   
    /**
     * Indicate that the connection attempt failed and notify the UI Activity.
     */
    private void connectionFailed() {
        connectionLost();
    }
        @Override
        protected void onStart() {
                super.onStart();
        }
        @Override
        protected void onResume() {
                super.onResume();
        }
        @Override
        protected void onPause() {
                super.onPause();
        }
        @Override
        protected void onStop() {
                super.onStop();
        }
        @Override
        protected void onDestroy() {
                if(mReceiver != null)
                        unregisterReceiver(mReceiver); // Don't forget to unregister during onDestroy
                super.onDestroy();
        }
}

32 則留言:

  1. 恩 ~ 不好意思 ~ 當初硬體搜尋 ~ 我寫成第一次搜尋到硬體ID才能連

    在第二次搜尋到的硬體ID會造成錯誤

    因為都沒有時間去看跟修改 ~

    如果想直接套用建議可以使用lejos網站有直接寫成jar套件使用
    (比較方便又簡單明瞭)


    網站
    http://lejos.sourceforge.net/

    Bluetooth (leJOS NXJ API documentation)
    文件:

    下載lejos.jar檔案
    http://lejos.sourceforge.net/tools/eclipse/plugin/nxj/


    直接在Google 下載DOC檔案就有範例可以參考
    Bluetooth communications sample code

    然後如何加入jar
    http://stackoverflow.com/questions/3280353/how-to-import-a-jar-in-eclipse

    回覆刪除
  2. lejos API 的涵式說明文件
    http://lejos.sourceforge.net/p_technologies/nxt/nxj/api/index-all.html
    你可以看到getSignalStrength是不是符合您的需求嗎?
    ^.^

    回覆刪除
  3. 作者已經移除這則留言。

    回覆刪除
  4. 您好~請問有單純利用藍芽傳輸字串的程式碼嗎?(我是新手)

    回覆刪除
  5. 不好意思 ~ 最近都在忙 ~ 那麼晚才發現您的留言!!

    你可以參考 android 官方的文件跟程式碼

    您的SDK裡面有下載Sample有著一個BluetoothChat - Bluetooth Chat

    1.藍芽聊天室
    http://jayxie.com/mirrors/android-sdk/resources/samples/BluetoothChat/index.html
    2.詳細的介紹流程
    http://developer.android.com/guide/topics/connectivity/bluetooth.html#SettingUp


    ^.^ (可用GOOGLE IE 自動把網頁翻成中文)





    回覆刪除
  6. 你好~我想知道其他封包的格式
    例如:觸碰或光感
    超音波是用LSWRITE和LSREAD這兩個直接指令
    其他SENSOR通用嗎?
    意思是說我要其他SENSOR的值,只需要去修改這部分的陣列嗎?
    感謝你

    回覆刪除
  7. 抱歉~不好意思~那麼晚才回
    是沒錯,因為是要對I2C晶片下指令
    http://hsrc.static.net/Research/NXT%20I2C%20Communication/
    中文:
    http://www.appinventor.tw/mindsensors
    像lejos API 的涵式說明文件:都有說的
    http://www.lejos.org/nxt/icommand/api/icommand/nxt/comm/NXTCommand.html
    比較詳細中文介紹,可以參考CH Lego Blog
    http://tw.myblog.yahoo.com/ch-lego/article?mid=516

    回覆刪除
  8. 不好意思,想請教一下
    這支程式連leJos NXT是可行的嗎?(藍芽連線的部分)
    因為有試過,但Android端的程式按下連線就跳掉了

    想請問有沒有跟leJos NXT藍芽連Android的相關的文獻可以參考
    找了好久都找不到想要的
    不是使用App Inventor 而是純正的Android的手寫程式

    回覆刪除
  9. lejos是可行的 ^.^ , 我的程式是直接用android的藍芽事件去傳輸功能(所以沒有用lejos)
    當初在寫的時候搜尋裝置跟連結部分寫的不太好
    發現到lejos都已經把藍芽事件寫程模組化,方便大家連線又簡單易懂
    我幫你找一個比較詳細的繁體PDF文件:
    http://www.csie.chu.edu.tw/ezfiles/11/1011/bbs/67/bbs_67_577555_82275.pdf
    簡體解說版:
    http://www.diy-robots.com/resources/LejosNxtTutorial_cn/communications/communications.php
    如果有什麼問題歡迎發問 ^.^

    回覆刪除
  10. 請問是否有 藍芽 發送 接收的範例嗎?
    我有用bluetooth chat 但是手機上不能執行 謝謝

    回覆刪除
    回覆
    1. 不好意思 ~ 可以問一下你的手機版本跟編譯器的版本是否相同?
      因為官方的範例,照理說應該不可能出錯 ^.^
      所以我們來看是不是設定上有問題或者有版本互衝之類的問題..
      (一步一步找問題,看問題在哪 ^.^)

      刪除
  11. 請問一下喔,我還是有點看不懂,就是兩個Spinner一個是顯示設備,另外一個是顯示與哪個設備做連接是嗎?

    回覆刪除
  12. 其實兩個都一樣的說 ~ 那時候在想為什麼搜尋第二次裝備值會跑掉
    所以故意新增兩個一樣,來驗證看看(其實是多此一舉)

    用下面搜尋方式,你就可以找到相關連的事件了 ^.^
    spinner1 => bondedDevices
    spinner2 => foundedDevices
    foundedDevices.add(device.getName() + "\n" + device.getAddress());
    bondedDevices.add(device.getName() + "\n" + device.getAddress());

    回覆刪除
  13. Dear Yen-Chu:
    不好意思 請問一下 你有實作Android java mailbox read/write message from smartphone的sample??

    回覆刪除
  14. 在Android 做MailBox部分 ~ 我沒有實做過
    不過如果要做的話 ~ 我會利用架設WebService
    http://bigbabaychu.blogspot.tw/2013/07/android-eclipse-web-service.html
    然後再利用JavaMail收發Mail ~ (JavaMail 範例可以搜尋Google ~ 有一堆範例的說)

    回覆刪除
    回覆
    1. 忘了補充 Android 怎麼連WebService
      我以前是利用ksoap2.jar 檔案
      http://javatutorialspoint.blogspot.tw/2012/02/android-web-service-access-using-ksoap2.html

      刪除
  15. 請問 我直接套用你的程式
    把 text 和 btn5 拿掉
    然後把一些名稱改好
    可以進行模擬
    但是按按鍵後就錯誤跳出了
    我有試著用手機安裝 手機 開啟後 直接跳出
    請問是不是哪裡沒設定
    還是不能這樣用 //我是新手 如果問了 笨問題 請包涵...

    回覆刪除
    回覆
    1. 抱歉,最近比較忙,才那麼晚回
      text = 顯示訊息
      btn5 = 傳送啟動A馬達指令
      照理說你刪得沒錯的說
      XML應該有加入藍芽的權限吧!!

      如果是我Debug模式:
      考慮
      1.Andorid SDK版本
      2.LEGO控制器版本

      先做一個開啟藍芽裝置,看看有沒有異常
      turnOnBluetooth

      所以建議從一步一步做起比較好方面看錯誤在哪裡!!

      刪除
  16. 我想問關於連線的,我有好多都看不懂
    不知道要怎麼問才好,所以先問一點點
    我沒有弄馬達的
    stvorka←這個是甚麼,是指搜尋到的裝置嗎?
    還有ConnectThread跟ConnectedThread差在哪裡?
    不好意思..程度比較不好....><

    回覆刪除
    回覆
    1. 您好阿 ^.^
      1.
      BluetoothDevice stvorka = null;
      stvork只是一個變數,以BluetoothDevice(藍芽裝置)宣告的變數

      2.
      mConnectThread => 用來連線上面的藍芽裝置
      mConnectedThread => 確認已連線,傳送我所標示的紅色指令

      刪除
  17. 作者已經移除這則留言。

    回覆刪除
    回覆
    1. 作者已經移除這則留言。

      刪除
    2. 作者已經移除這則留言。

      刪除
    3. 作者已經移除這則留言。

      刪除
    4. 作者已經移除這則留言。

      刪除
    5. 作者已經移除這則留言。

      刪除
    6. 給你一個網址: 介紹的蠻詳細的說
      http://lp43.blogspot.tw/2012/04/bluetoothchat.html

      刪除
  18. 您好:
    不曉得在這裡請教這個問題適不適當
    我目前在做一支手機對多隻機器人,目前是可以連上兩個裝置了,但是在傳值的部分
    遇到了麻煩ˊˋ,按下播放鍵只有其中一隻連線的做動作,另一隻完全沒反應

    想請教一下這是為什麼?要如何解決這個問題呢?

    回覆刪除
  19. 因為我沒有做過~怕無法給你詳細的解決方法(請多多包涵)
    我自己猜測是否是藍芽的連接方式的傳送
    我會把它當作TCP/IP的連接方式 ~ 把藍芽當作伺服器去連接客戶端
    而有A裝置跟B裝置 ~ 兩個裝置都是客戶端 ~ 假設A裝置的連線IP為001
    B裝置的連線IP為002 ~ 當你連上兩個裝置 ~ 對A裝置 藍芽發送001裝置啟動馬達
    相對你要對 B裝置啟動馬達 ~ 藍芽必須發動 002 裝置啟動馬達
    而我自己猜想你應該要對B裝置啟動馬達的時後 ~ 是發送001裝置啟動馬達
    給你看ㄧ個網站範例跟影片(在uniqueID的部分就可以看出來 )
    http://sariel.pl/2012/10/nxt-multiple-units-simple-control/

    回覆刪除
  20. 請問一下,我用bluetoothchat 範例,因為看起來跟你發布的code類似,所以請問看看,因為我手機跟其他人手機可以用這範例app互傳訊息,但是我手機配對其他藍芽模組可以配對,但是用這程式在連接那邊一直無法連接,請問這跟app code 有關係,還是藍芽模組有關係,如果可以就回我信箱 chiuka12@gmail.com ,謝謝!!如果需要我在把程式寄給你,謝謝

    回覆刪除
    回覆
    1. 不好意思~最近忙到翻了~所以才那麼慢回
      我在猜想~程式如果沒有問題
      那麼有可能是硬體的速率問題
      可以參考這一篇:
      http://gsyan888.blogspot.tw/2014/03/arduino-hc-06-at-command.html
      然後我也順便寄信給你

      刪除