Подключайтесь к двум устройствам Bluetooth с одинаковым UUID одновременно

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

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

На одном телефоне это приводит к сбою приложения, на другом - ничего (исключение или уведомление о разрыве соединения) не происходит.

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

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

Поскольку я использую два модуля Bluetooth HC-05, у них одинаковый UUID, что, как я полагаю, может быть проблематичным, потому что этот UUID не уникален для одного устройства. Но я не уверен, что проблема в этом. Может кто знает как поменять UUID HC-05?

Обратите внимание, что я отправляю данные через случайные интервалы на обе машины. Так что я думаю, что это могло вызвать проблему. В какой-то момент приложение пытается отправить сообщение сразу на два устройства, и это вызывает проблемы. Итак, я думаю о том, чтобы сделать какое-то обходное решение для этого. Но я не знаю, как это сделать. Может быть, какой-то стек, в который я помещаю данные и устройство, на которое они должны отправить, а затем я отправляю их элемент за элементом, возможно, с некоторой задержкой между ними. Таким образом, отправка данных несколько «синхронизирована». Однако я не знаю, хорошее ли это решение, и я благодарен за любой совет, который я мог получить.

Итак, прямо сейчас я подключаюсь к таким устройствам:

 public void connect(String mac){
    Set<BluetoothDevice> bondedDevices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
    for (BluetoothDevice devices : bondedDevices)
        if (devices.getAddress().equals(mac)) {
            this.device = devices;
            break;
        }

    if (this.device == null) {
        //some error handling
    } else {
        UUID id= UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        try {
            this.socket = this.device.createRfcommSocketToServiceRecord(id);
            this.socket.connect();
            this.outputStream = this.socket.getOutputStream();
            final InputStream  st = this.socket.getInputStream();
            //some more init stuff
        } catch (Exception e) {
            e.printStackTrace();
            this.disconnect();
        }
    }
}

И я отправляю такие данные (без лишнего кода):

byte[] send = new byte[9];
//fill Data
try {
    this.outputStream.write(send);
    this.outputStream.flush();       
} catch (Exception e) {
    //Displaying Toast with Error message                  
    Toast.makeText(DirtyCode.appcont, e.getMessage(), Toast.LENGTH_LONG).show();
    Log.e("SEND EXCEPTION:" + device.getName(), e.getMessage());
    e.printStackTrace();
    return false;
}

Так что я также думал, что мне может понадобиться как-то использовать BluetoothServerSocket. Но я в этом не уверен.

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

Я пытался решить это в течение долгого времени, но я не могу заставить его работать, поэтому любая помощь действительно приветствуется.

Какое исключение при обрыве связи со вторым устройством?

greeble31 25.10.2018 02:35

У меня нет исключения, по крайней мере, я не смог где-то его поймать. Как только я получил исключение, соединение системы / программного обеспечения прервано или подобное.

Hannes 25.10.2018 11:20

Значит, процесс просто вылетает, без каких-либо следов в логарифме?

greeble31 25.10.2018 14:40

на одном телефоне даже не вылетает я просто перестаю принимать на одном устройстве BT. с другой стороны, у меня не было следов в логарифме. это просто останавливается

Hannes 25.10.2018 18:27

Хм, я бы хотел увидеть весь код, который имеет дело с жизненным циклом вашего сокета: создание, использование и отключение.

greeble31 25.10.2018 18:35

Итак, мое создание и использование уже под вопросом (код для отправки выполняется либо обработчиком, либо когда пользователь нажимает кнопку). Это код, который я использую для отключения: try { pause(); // send some data outputStream.close(); outputStream =null; socket.close(); } catch (Exception e) { e.printStackTrace(); }

Hannes 26.10.2018 14:50

Этого кода недостаточно; Я пытаюсь определить ответы на такие вопросы, как: 1.) Как быстро два сокета запускаются относительно друг друга 2.) Как долго они существуют одновременно 3.) На каких потоках они работают 4.) Как вы подсказываете им отправлять больше данных и 5) Как часто они подключаются и логика переподключения. Судя по опубликованному вами рекламному объявлению, похоже, что вы отправляете 9 байтов на устройство, а затем немедленно отключаетесь, что делает маловероятным, что вы когда-либо одновременно подключаетесь.

greeble31 26.10.2018 15:16

Я подключаюсь к одному BTDevice, отправляю 9 байтов, затем подключаюсь к другому BTDevice и отправляю 9 байтов на это устройство. Чем на протяжении всего приложения я никогда не подключаюсь повторно. Я просто время от времени отправляю на устройства 9 байтов. Иногда я отправляю их на одно устройство, а затем сразу после этого на другое. Я тестировал его, отправляя два таких устройства каждые 5 секунд или около того. например Device1 9 байтов -5sec- Device1 9 байтов -5sec- Device2 9 байтов -5sec- и затем повторить. через 5 сек.

Hannes 26.10.2018 15:29

Итак, я предполагаю, что 1.) каждый сокет запускается в своем собственном выделенном фоновом потоке 2.) что вы правильно обработали все проблемы синхронизации потоков и 3.) у вас есть соответствующая логика обработки ошибок и повторного подключения на случай, если произойдет одно соединение. проблема. Это верно? И на своем первом телефоне вы, должно быть, определили точную строку, которая вызывает сбой, возможно, заключив ее в скобки с операторами журнала?

greeble31 26.10.2018 15:48

Как определить, что 1 устройство "перестало принимать"? Откуда вы знаете, что ваш код Arduino не является проблемой?

greeble31 26.10.2018 15:50

Пока я вообще не выполнял синхронизацию, и outputStream.write () не обязательно вызывается из другого потока. И я не получаю ничего от устройств BT, поэтому я не слушаю никаких входящих данных. На arduino мне нужно распечатать на последовательный порт количество доступных байтов из модуля Bluetooth (Serial.available ()), когда он входит в метод проверки входящих данных BT. Итак, я знаю, что он проверяет, и я знаю, что он не получил никаких данных. Иногда я замечал, что, хотя я вызываю flush (), для отправки данных требуется такое же время (дольше, чем обычно.

Hannes 26.10.2018 18:06

Я хотел бы получить более подробную информацию о том, как вы используете потоки, на основе вашего ответа и утверждения «в какой-то момент приложение пытается отправить на два устройства одновременно, и это вызывает проблемы». Я не могу быть уверен, что вы правильная обработка всех проблем безопасности потоков. Другая проблема заключается в вашем утверждении, что сокеты не работают без выброса, и программа вылетает без какого-либо вывода logcat. Обе ситуации кажутся мне очень маловероятными. Чтобы объяснить это, нужно сделать больше. Вы уверены, что знаете, как использовать logcat? И можно ли определить точную линию, на которой происходит сбой?

greeble31 26.10.2018 18:37

Также убедитесь, что вы не затираете существующую ссылку, когда присваиваете значение this.socket / this.outputStream ... Я предполагаю, что у вас есть 2 экземпляра любого класса, который содержит эти члены, но это не ясно в опубликованном коде.

greeble31 26.10.2018 20:16

Спасибо за помощь. Я проведу еще несколько исследований о том, где возникает ошибка в ближайшие дни, и опубликую больше этого кода, чем. В примерах кода ключевое слово this не обязательно, поэтому нет локальной переменной с таким же именем. Есть только один глобальный поток сокета / вывода.

Hannes 26.10.2018 22:35

OK. Удачи. Кстати, я не имел в виду локальную переменную. Я имею в виду, какой бы класс ни содержал эту переменную - вам нужно убедиться, что у вас есть как минимум 2 из них. Это важно!

greeble31 26.10.2018 23:01

«Есть только один глобальный сокет / выходной поток» - звучит неправильно. У вас два подключения, вам нужно две розетки. Если у вас два сокета, вам нужно два выходных потока.

greeble31 26.10.2018 23:03
1
16
678
1

Ответы 1

Вы не можете одновременно подключиться к нескольким устройствам BT, каждое из которых имеет одну и ту же услугу BT. Это звучит так: у вас есть два динамика BT, вы подключили их оба, и вы начали музыку, а затем воспроизводятся оба динамика. Невозможно.

Но вы можете подключить несколько устройств BT, каждое из которых является отдельной службой BT: Например: одновременное использование мыши BT и динамика BT. Это возможно.

Хорошо, спасибо за эту информацию. Итак, тип службы BT определяется через UUID, верно? Значит, изменение одного UUID может сработать? И есть объяснение, почему он работает несколько раз (с двумя устройствами, получающими данные с одним и тем же UUID)?

Hannes 25.10.2018 11:23

Пожалуйста, посмотрите эту ветку: stackoverflow.com/questions/13964342/…, и это: bluetooth.com/specifications/assigned-numbers/service-discov‌ ery

Sinan Ceylan 25.10.2018 18:19

-1 Устройства BT имеют MAC-адреса, которые делают их однозначно идентифицируемыми. UUID предназначен только для обнаружения служб, например идентификаторов классов USB-устройств. Фактически, вы должны иметь возможность подключаться к двум парам динамиков BT одновременно, если бы вы были склонны писать клиентское программное обеспечение, поддерживающее это.

greeble31 25.10.2018 18:45

@ greeble31 Вы хотите изменить прошивку клиентского устройства?

Sinan Ceylan 25.10.2018 19:06

В этом случае изменение прошивки не требуется, поскольку сокеты создаются по указанию программного обеспечения пользовательского пространства.

greeble31 25.10.2018 19:21

Думая о BT UUID как о TCP-портах, может быть полезно понять, как работает bluetooth UUID. Они работают как сокеты TCP, и нам нужно, чтобы сокеты поддерживали множественное соединение, по крайней мере, на стороне сервера. Например, в BT 5.0 появилась новая функция под названием Dual Audio; если у вас есть телефон с поддержкой BT 5.0, вы можете одновременно подключить два обычных (не BT 5.0) динамика. Потому что серверная сторона поддерживает двойной BT Audio и может одновременно подключать два аудиоустройства. Таким образом, требуется, чтобы используемый нами стандарт BT поддерживал множественное соединение с одним и тем же UUID.

Sinan Ceylan 25.10.2018 20:20

Я согласен с аналогией с TCP, но не думаю, что она применима к случаю OP; его программное обеспечение действует как клиент. HC-05 действуют как два отдельных сервера.

greeble31 26.10.2018 00:48

Другие вопросы по теме