如何将 Android 应用程序正确连接到支持蓝牙的 Arduino 微控制器上的 RFCOMM 插座? [英] How can I properly connect an Android application to an RFCOMM socket on a Bluetooth enabled Arduino microcontroller?

查看:25
本文介绍了如何将 Android 应用程序正确连接到支持蓝牙的 Arduino 微控制器上的 RFCOMM 插座?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与我大学的一些学生合作开发一个简单的蓝牙 Android 应用程序,该应用程序将用于与连接有蓝牙模块的 Arduino 微控制器进行串行通信 (RFCOMM).

I'm working with some students at my university developing a simple Bluetooth Android application that will be used for serial communication (RFCOMM) to an Arduino microcontroller with a Bluetooth module connected to it.

据我所知,我为 RFCOMM/SPP 00001101-0000-1000-8000-00805F9B34FB 使用了正确的蓝牙地址和 UUID.我的应用程序启动一个线程,尝试使用 BluetoothDevice.createRfcommSocketToServiceRecord(UUID) 连接到设备.但出于某种原因,我们没有看到成功的连接.对来自上述调用的结果 BluetoothSocket 调用 connect() 时,操作总是失败.

To the best of my knowledge, I'm using the correct Bluetooth address and UUID for RFCOMM/SPP 00001101-0000-1000-8000-00805F9B34FB. My application starts a thread that attempts to connect to the device using BluetoothDevice.createRfcommSocketToServiceRecord(UUID). But for one reason or another, we are not seeing a successful connection. The operation always fails upon invoking connect() on the resulting BluetoothSocket that comes from the invocation above.

在我的 HTC Evo 上测试时,运行 HTC 的 Gingerbreadconnect() 调用通常会失败并显示异常消息Service Discovery could Not Be开始了."我做了一些阅读,发现有人说 HTC 在蓝牙堆栈中对 RFCOMM 的实现有问题,所以我们决定在另一个学生的 三星 Galaxy S.第一次运行代码时,一切正常.Arduino 微控制器连接到一个小型电动机,该电动机开始按预期工作.我没有排除问题是否出在微控制器方面.

When tested on my HTC Evo, running HTC's variant of Gingerbread, the connect() call usually fails with the exception message "Service Discovery Could Not Be Started." I did some reading and found that some said that HTC's implementation for RFCOMM in the Bluetooth stack was buggy, so we decided to try it on another student's Samsung Galaxy S. The first time the code ran, everything worked perfectly. The Arduino microcontroller is connected to a small electric motor which began working as expected. I have not ruled out whether or not the problem could be on the microcontroller's side.

随后在三星设备上使用该应用程序失败,现在显示一条消息服务发现失败".在我看来,可能是设备端的蓝牙模块认为RFCOMM服务还在使用.但是我们重启了微控制器,结果还是一样.

Subsequent uses of the application on the Samsung device then failed, now with a message saying "Service Discovery Failed". To me, it seems that perhaps the Bluetooth module on the device side thinks that the RFCOMM service is still in use. But we've restarted the microcontroller and still saw the same result.

我刚刚列出了线程代码,因为它是真正相关的所有内容.我已经读过使用反射解决这些问题的非常常见的解决方法(hack).我对它的尝试也失败了,但在那里并被注释掉了.希望有人能在这里引导我朝着正确的方向前进.另请注意,我确实在清单中启用了必要的权限,并且在这两种情况下,设备都使用 Android 的用户界面成功配对到 Arduino.

I've just listed the thread code as it is all that is really relevant. I've read that there is a pretty common workaround (hack) for these issues using reflection. My attempts at it have also failed but are there and commented out. Hopefully someone can steer me in the right direction here. Also note that I do have the necessary permissions enabled in the manifest and in both cases, the device was successfully paired to the Arduino using Android's user interface.

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();
            }
        }
    }
}

蓝牙模块是 MDFLY RF-BT0417CB.我知道在 arduino 上运行的代码并不多,只是使用 Serial.available() 和 Serial.read() 与 BT 模块进行通信.但是,我有一条可能更有用的新信息.当我的应用程序安装在三星设备上时,它只运行了一次,但在随后的试验中失败了.不久前,与我一起工作的另一个学生使用 Android App Inventor(一个拖放 GUI 工具,也可以创建逻辑工作工件)来创建一个简单的应用程序,该应用程序连接相同的 BT 模块/arduino 板,该应用程序有效.他说安装我的应用程序时,另一个应用程序无法连接到 BT 模块,这让我相信系统一直认为资源已分配给我的应用程序.他卸载我的应用程序后,另一个能够连接.他没有其他应用程序的源代码,但我将自己尝试 App Inventor,看看它生成的源代码是否有任何不同.据我所知,我遵守了 Android 文档中定义的大多数标准实践,所以 BT 模块可能有些奇怪,或者 arduino 代码不一定以编程方式控制 BT 模块.

The Bluetooth module is an MDFLY RF-BT0417CB. I know that the code that is running on the arduino is not much and is simply communicating with the BT module using Serial.available() and Serial.read(). However I have a new piece of information that may be of more use. When my application was installed on the Samsung device, it worked just once, and failed on subsequent trials. A while back, the other student I'm working with, used Android App Inventor (a drag and drop GUI tool that also can create logical working artifacts) to create a simple application that connects the same BT module/arduino board, which worked. He said that when my application was installed, that the other application was unable to ever connect to the BT module, which leads me to believe the system stayed thinking that the resource was allocated to my application. After he uninstalled my app, the other was able to connect. He does not have the source code to the other application, but I am going to try App Inventor myself to see if the source code it generates it generates is doing anything different. To the best of my knowledge, I am complying with most of the standard practices defined in Android's documentation, so perhaps it's something strange about the BT module or the fact that the arduino code isn't necessarily programmatically controlling the BT module.

另一个我不是蓝牙专家,但我们能够找到解决方法.正如一些人所知道的,有一堆公共蓝牙设备 API,在编译时隐藏,但在运行时使用反射合法公开.其中之一是 createRfCommSocket(int).这个 API 不在官方文档中,因为它是隐藏的,但你可以阅读它 here.我还没有尝试使用文档支持的 API,但问题似乎是手机和串行板之间的并发问题.手机发送了一条消息,这当然是一个阻塞呼叫,当它从那里返回时,关闭了连接.串行板上的屏蔽也会关闭连接,因此数据对 arduino 应用程序不可用.我们在 android 端调试模式下见证成功通信时意识到这一点,但在发布模式下失败.在 android 端添加半秒延迟,在 BluetoothSocket 的传输和关闭之间修复了该问题.我不能说这个问题是否归因于 arduino 代码,因为我对架构不是很熟悉,但我们作为学生缺乏经验,所以我不会感到惊讶.

ANOTHER I'm not a Bluetooth expert, but we were able to figure out a work around. As some are aware, there are a bunch of public BluetoothDevice API's, hidden at compile time, but are legally public at runtime using reflection. One of them is createRfCommSocket(int). This API is not in the official documentation since it is hidden, but you can read it here. I haven't tried it yet with the documentation supported API, but the problem appeared to be something of a concurrency issue between the handset and the serial board. The handset sent a message, which is of course a blocking call, and when it returned from there, closed the connection. The shield on the serial board would then also close the connection and hence the data was not available to the arduino application. We realized this when witnessing successful communication while in debug mode on the android side, but failure in release mode. Adding a half second delay on the android side, between the transmission and closure of the BluetoothSocket fixed the issue. I cannot say whether this issue was attributed to by the arduino code or not as I am not very familiar with the architecture, but we as students lack experience so it wouldn't surprise me.

推荐答案

Android 与 Arduino 蓝牙通信(1)

我认为这对您有帮助.你能提供一些细节吗?我看过一个链接,你也可以看到这个.让我知道这是否有帮助?如何在Android中创建不安全的RFCOMM Socket?

I think this will be helpful to you. Can you provide some detail on this.I have seen one link ,you can see this too. Let me know whether this is helpfull or no? How to create Insecure RFCOMM Socket in Android?

这篇关于如何将 Android 应用程序正确连接到支持蓝牙的 Arduino 微控制器上的 RFCOMM 插座?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆