安卓与乐高Mindstorm NXT之间的蓝牙连接

12

有人知道如何在Android和LEGO-Mindstorm-NXT之间建立蓝牙连接吗? 两个NXT之间的连接很好用。但是另一种连接类型看起来并不那么容易。 我正在使用LeJOS Firmware 0.85和Android SDK工具(2.2 Froyo)。


你成功地将Android和LEGO-Mindstorm-NXT配对了吗? - garzanti
请看下面我的回答,了解它是如何工作的。在第一次运行或第一次连接到NXT时,智能手机将自动与NXT配对,并要求您输入NXT的密钥以进行配对。 - joen
2个回答

21

我已经解决了这个问题,并将展示如何解决,因为我看到很多人都有这个问题。

该类包括4个函数:

  • 如果之前未启用,则启用蓝牙-> enableBT()
  • 连接两个NXT -> connectToNXTs()
  • 向其中一个NXT写入消息-> writeMessage(byte msg, String nxt)
  • 从其中一个NXT读取消息-> readMessage(String nxt)

这是Android设备的代码(BT_comm.java):

package de.joen.android.CubeScan;


import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.UUID;


import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;

import android.util.Log;

public class BT_Comm {

  //Target NXTs for communication
  final String nxt2 = "00:16:53:04:52:3A";
  final String nxt1 = "00:16:53:07:AA:F6";

  BluetoothAdapter localAdapter;
  BluetoothSocket socket_nxt1, socket_nxt2;
  boolean success = false;

  // Enables Bluetooth if not enabled
  public void enableBT(){
    localAdapter = BluetoothAdapter.getDefaultAdapter();
    // If Bluetooth not enable then do it
    if (!localAdapter.isEnabled()) {
      localAdapter.enable();
      while(!(localAdapter.isEnabled()));
    }
  }

  // Connect to both NXTs
  public boolean connectToNXTs() {

    // Get the BluetoothDevice of the NXT
    BluetoothDevice nxt_2 = localAdapter.getRemoteDevice(nxt2);
    BluetoothDevice nxt_1 = localAdapter.getRemoteDevice(nxt1);
    // Try to connect to the nxt
    try {
      socket_nxt2 = nxt_2.createRfcommSocketToServiceRecord(UUID
          .fromString("00001101-0000-1000-8000-00805F9B34FB"));

      socket_nxt1 = nxt_1.createRfcommSocketToServiceRecord(UUID
          .fromString("00001101-0000-1000-8000-00805F9B34FB"));

      socket_nxt2.connect();    
      socket_nxt1.connect();      

      success = true;

    } catch (IOException e) {
      Log.d("Bluetooth","Err: Device not found or cannot connect");
      success=false;
    }
    return success;    
  }


  public void writeMessage(byte msg, String nxt) throws InterruptedException {
    BluetoothSocket connSock;

    // Swith nxt socket
    if (nxt.equals("nxt2")) {
      connSock=socket_nxt2;
    } else if(nxt.equals("nxt1")) {
      connSock = socket_nxt1;
    } else {
      connSock=null;
    }

    if (connSock!=null) {
      try {

        OutputStreamWriter out = new OutputStreamWriter(connSock.getOutputStream());
        out.write(msg);
        out.flush();

        Thread.sleep(1000);

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

  public int readMessage(String nxt) {
    BluetoothSocket connSock;
    int n;

    // Swith nxt socket
    if (nxt.equals("nxt2")) {
      connSock=socket_nxt2;
    } else if (nxt.equals("nxt1")) {
      connSock=socket_nxt1;
    } else {
      connSock=null;
    }

    if (connSock!=null) {
      try {

        InputStreamReader in = new InputStreamReader(connSock.getInputStream());
        n = in.read();
        return n;

      } catch (IOException e) {
        // TODO: Auto-generated catch block
        e.printStackTrace();
        return -1;
      }
    } else {
      // Error
      return -1;
    }
  }
}

要从Android智能手机获取消息,必须在NXT端进行读取调用。

这是来自NXT端的代码,将接受来自智能手机的连接并读取消息:

Boolean isrunning = true;

// Main loop   
while (true)
{
  LCD.drawString(waiting,0,0);
  LCD.refresh();

  // Listen for incoming connection

  NXTConnection btc = Bluetooth.waitForConnection();

  btc.setIOMode(NXTConnection.RAW);

  LCD.clear();
  LCD.drawString(connected,0,0);
  LCD.refresh();  


  // The InputStream for read data 
  DataInputStream dis = btc.openDataInputStream();


  // Loop for read data  
  while (isrunning) {
    Byte n = dis.readByte();
    LCD.clear();
    LCD.drawInt(n, 4, 4);
  }

  dis.close();

  // Wait for data to drain
  Thread.sleep(100); 

  LCD.clear();
  LCD.drawString(closing,0,0);
  LCD.refresh();

  btc.close();

  LCD.clear();
}

希望这能帮到其他人...


我在HTC Desire上使用createRfcommSocketToServiceRecord时遇到了问题,如果您计划分发代码,您可能需要注意这一点。请参见(https://dev59.com/Kuo6XIcBkEYKwwoYTzAd)。 - Joubarc
有人留言建议您使用OutputStream而不是OutputStreamWriter,因为outputstream编码为Unicode并且对于大于127的值会出现错误...不知道这意味着什么,但可以删除该回答。 - Sam Saffron
这真的帮了我很多。如果我可以给你点赞超过一次,我一定会的! - Ben Pearson

4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接