Как правильно подключить приложение Android к разъему RFCOMM на микроконтроллере Arduino с поддержкой Bluetooth? - PullRequest
25 голосов
/ 02 ноября 2011

Я работаю с некоторыми студентами в моем университете над разработкой простого приложения Bluetooth для Android, которое будет использоваться для последовательной связи (RFCOMM) с микроконтроллером Arduino с подключенным модулем Bluetooth.

Насколько мне известно, я использую правильный адрес Bluetooth и UUID для RFCOMM/SPP 00001101-0000-1000-8000-00805F9B34FB. Мое приложение запускает поток, который пытается подключиться к устройству, используя BluetoothDevice.createRfcommSocketToServiceRecord(UUID). Но по той или иной причине мы не видим успешной связи. Операция всегда завершается ошибкой при вызове connect() для результирующего BluetoothSocket, полученного из вызова выше.

При тестировании на моем HTC Evo , работающем с вариантом HTC Gingerbread , вызов connect() обычно завершается ошибкой с сообщением об исключении «Обнаружение службы не может быть запущено». Я немного почитал и обнаружил, что некоторые говорят, что реализация HTC для RFCOMM в стеке Bluetooth глючит, поэтому мы решили попробовать его на Samsung Galaxy S другого студента. При первом запуске кода все работало отлично. Микроконтроллер Arduino подключен к небольшому электромотору, который начал работать как положено. Я не исключаю, может ли проблема быть на стороне микроконтроллера.

Затем последующее использование приложения на устройстве Samsung завершилось неудачно, теперь с сообщением «Ошибка обнаружения службы». Мне кажется, что, возможно, модуль Bluetooth на стороне устройства считает, что служба RFCOMM все еще используется. Но мы перезапустили микроконтроллер и увидели тот же результат.

Я только что перечислил код потока, так как это все, что действительно важно. Я читал, что существует довольно распространенный способ решения этих проблем с помощью рефлексии. Мои попытки также провалились, но есть и закомментированы. Надеюсь, кто-то может направить меня в правильном направлении здесь. Также обратите внимание, что в манифесте у меня включены необходимые разрешения, и в обоих случаях устройство было успешно сопряжено с Arduino с помощью пользовательского интерфейса Android.

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

EDIT: Модуль Bluetooth является MDFLY RF-BT0417CB. Я знаю, что код, работающий на Arduino, невелик и просто взаимодействует с модулем BT с помощью Serial.available () и Serial.read (). Однако у меня есть новая информация, которая может быть более полезной. Когда мое приложение было установлено на устройстве Samsung, оно работало только один раз и не получалось при последующих испытаниях. Некоторое время назад другой ученик, с которым я работаю, использовал Android App Inventor (инструмент с графическим интерфейсом для перетаскивания, который также может создавать логические рабочие артефакты), чтобы создать простое приложение, которое подключает тот же модуль BT / Arduino, который работал. Он сказал, что когда мое приложение было установлено, другое приложение не смогло когда-либо подключиться к модулю BT, что заставило меня поверить, что система продолжала думать, что ресурс был выделен для моего приложения. После того как он удалил мое приложение, другой смог подключиться. У него нет исходного кода для другого приложения, но я собираюсь попробовать App Inventor самостоятельно, чтобы увидеть, не делает ли исходный код, который он генерирует, что-то другое. Насколько мне известно, я соблюдаю большинство стандартных практик, определенных в документации Android, поэтому, возможно, что-то странное в модуле BT или в том факте, что код arduino не обязательно программно контролирует модуль BT.

ДРУГОЕ РЕДАКТИРОВАНИЕ:Я не эксперт по Bluetooth, но мы смогли обойти это.Некоторые знают, что существует множество открытых API BluetoothDevice, которые скрыты во время компиляции, но юридически публичны во время выполнения с использованием отражения.Одним из них является createRfCommSocket (int).Этот API отсутствует в официальной документации, так как он скрыт, но вы можете прочитать его здесь .Я еще не пробовал это с API, поддерживаемым документацией, но проблема, казалось, была чем-то вроде проблемы параллелизма между телефоном и последовательной платой.Трубка отправила сообщение, которое, конечно, является блокирующим вызовом, и когда она оттуда вернулась, закрыла соединение.Экран на последовательной плате также закроет соединение, и, следовательно, данные не будут доступны для приложения Arduino.Мы поняли это, когда стали свидетелями успешного общения в режиме отладки на стороне андроида, но с ошибкой в ​​режиме выпуска.Добавление полсекундной задержки на стороне Android между передачей и закрытием BluetoothSocket решило проблему.Я не могу сказать, была ли эта проблема связана с кодом Arduino или нет, поскольку я не очень знаком с архитектурой, но у нас, как у студентов, нет опыта, поэтому меня это не удивит.

Ответы [ 2 ]

1 голос
/ 25 ноября 2011

Связь между Android и Arduino с Bluetooth (1)

Я думаю, это будет вам полезно. Можете ли вы предоставить некоторые подробности об этом. Я видел одну ссылку, вы можете увидеть это тоже. Дайте мне знать, полезно это или нет? Как создать небезопасный сокет RFCOMM в Android?

0 голосов
/ 12 декабря 2011

Amarino Toolkit был создан специально для облегчения последовательной связи Bluetooth между устройством Android и Arduino с Bluetooth.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...