Joe*_*son 25 android bluetooth arduino
我正在和我大学的一些学生一起开发一个简单的蓝牙Android应用程序,该应用程序将用于连接到蓝牙模块的Arduino微控制器的串行通信(RFCOMM).
据我所知,我正在使用正确的蓝牙地址和UUID RFCOMM/SPP 00001101-0000-1000-8000-00805F9B34FB.我的应用程序启动一个尝试使用连接到设备的线程BluetoothDevice.createRfcommSocketToServiceRecord(UUID).但由于某种原因,我们没有看到成功的联系.在调用来自上面的调用connect()的结果时BluetoothSocket,操作总是失败.
当我在运行HTC的Gingerbread变种的HTC Evo上进行测试时,通常会失败并显示"服务发现无法启动"的异常消息.我做了一些阅读,发现有人说HTC在蓝牙堆栈中对RFCOMM的实现是错误的,所以我们决定在另一个学生的三星Galaxy S上试用它.代码第一次运行时,一切都运行良好.Arduino微控制器连接到一个小电动机,开始按预期工作.我没有排除问题是否可能出在微控制器方面.connect()
随后在Samsung设备上使用该应用程序失败,现在显示"Service Discovery Failed"消息.对我来说,似乎设备端的蓝牙模块可能认为RFCOMM服务仍在使用中.但是我们重新启动了微控制器并且仍然看到了相同的结果.
我刚刚列出了线程代码,因为它是真正相关的.我已经读过使用反射这些问题有一个非常常见的解决方法(hack).我对它的尝试也失败了但是在那里并且被注释掉了.希望有人能引导我朝着正确的方向前进.另请注意,我确实在清单中启用了必要的权限,在这两种情况下,设备都使用Android的用户界面成功与Arduino配对.
private class ClientThread extends Thread {
private String _btAddress;
/**
* A handle to the local device's Bluetooth adapter hardware.
*/
private BluetoothAdapter _btAdapter = BluetoothAdapter.getDefaultAdapter();
/**
* A handle to the remote device Bluetooth context.
*/
private BluetoothDevice _btRemoteDevice;
/**
* A handle to the Bluetooth serial socket.
*/
private BluetoothSocket _btSocket;
/**
* Constructor.
* @param btAddress The BluetoothHardware address.
*/
public ClientThread(String btAddress)
{
_btAddress = btAddress;
}
public void run()
{
// Retrieves the device identified by the _btAddress property.
_btRemoteDevice = retrieveDevice();
if ( _btRemoteDevice == null )
sendUIMessage( CONNECTION_BT_DEVICE_NOT_BONDED );
else
sendBeacon();
}
/**
* Retrieves the device associated with this client thread.
* @return
*/
private BluetoothDevice retrieveDevice()
{
Set<BluetoothDevice> btDevices = _btAdapter.getBondedDevices();
for (BluetoothDevice btd : btDevices)
{
String addr = btd.getAddress();
String name = btd.getName();
if ( addr.equalsIgnoreCase(_btAddress) )
return btd;
}
return null;
}
/**
* Sends the beacon to the Bluetooth device.
*/
private void sendBeacon()
{
// Holds the output stream of the BluetoothDevice.
OutputStream os = null;
try
{
_btSocket = _btRemoteDevice.createRfcommSocketToServiceRecord( UUID.fromString( "00001101-0000-1000-8000-00805F9B34FB" ) );
//Method m = _btRemoteDevice.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});
//_btSocket = (BluetoothSocket) m.invoke(_btRemoteDevice, 1);
_btSocket.connect();
os = _btSocket.getOutputStream();
os.write('L');
}
catch (IOException e)
{
String message = e.getMessage();
e.printStackTrace();
sendUIMessage(CONNECTION_FAILURE_IO);
}
catch (Exception e)
{
e.printStackTrace();
sendUIMessage(CONNECTION_FAILURE_UNKNOWN);
}
finally
{
try
{
if (_btSocket != null)
_btSocket.close();
}
catch (IOException e)
{
System.out.println("Failed closing Bluetooth output stream.");
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:蓝牙模块是MDFLY RF-BT0417CB.我知道在arduino上运行的代码并不多,只是使用Serial.available()和Serial.read()与BT模块进行通信.但是,我有一条可能更有用的新信息.当我的应用程序安装在三星设备上时,它只运行一次,并在后续试验中失败.不久前,我正在使用的另一名学生使用Android App Inventor(一种拖放式GUI工具,也可以创建逻辑工作工件)来创建一个连接相同BT模块/ arduino板的简单应用程序.他说,当我的应用程序安装完毕后,其他应用程序无法连接到BT模块,这让我相信系统仍然认为资源已分配给我的应用程序.在他卸载我的应用程序后,另一个能够连接.他没有其他应用程序的源代码,但我将自己尝试使用App Inventor来查看它生成的源代码是否生成了不同的内容.据我所知,我遵守Android文档中定义的大多数标准实践,所以也许BT模块或者arduino代码不一定以编程方式控制BT模块这一事实.
另一个编辑:我不是蓝牙专家,但我们能够找到一个解决方案.有些人都知道,有许多公共BluetoothDevice API在编译时隐藏,但在运行时使用反射合法公开.其中之一是createRfCommSocket(int).此API不在官方文档中,因为它是隐藏的,但您可以在此处阅读.我还没有尝试使用文档支持的API,但问题似乎是手机和串行板之间的并发问题.手机发送了一条消息,这当然是一个阻塞呼叫,当它从那里返回时,关闭了连接.然后,串行板上的屏蔽也将关闭连接,因此arduino应用程序无法获得数据.我们在android端调试模式下见证成功通信时意识到这一点,但在发布模式下失败了.在android端添加半秒延迟,在BluetoothSocket的传输和关闭之间修复了这个问题.我不能说这个问题是否归因于arduino代码,因为我对这个架构不是很熟悉,但是我们学生们缺乏经验所以不会让我感到惊讶.
| 归档时间: |
|
| 查看次数: |
10687 次 |
| 最近记录: |