1

i try to create an Android App that connects to two Bluetooth HC-05 Modules (which are connected to an Arduino).

I am able to connect to both of them and if i only send Data to one of them everything works fine, if im sending Data to both however it might work for some Time but than it stops sending to one Device.

On one Phone this leads to the App crashing, on another Phone nothing (no Exception or notification that the connection was aborted) happens.

So i checked the Internet and in the most Part it says you can connect to two Bluetooth Devices at once (e.g. here).

I cannot figure out what the reason for this error is. But i have some ideas. Maybe someone can confirm then, or knows the real Problem or better yet a solution:)

Since i use two HC-05 Bluetooth Modules they have the same UUID, which i belive may be problematic because that this UUID is not uniqe to one device. But im not sure if thats the issue. Maybe someone knows how to change the UUID of the HC-05?

Note that im am sending data at random intervalls to both machines. So i think that could cause the issue. That at some point the App tries to send to two Devices at once and that causes trouble. So i am thinking about making some kined of workaround for this. But im not sure how. Maybe some Stack in which i put the Data and the device it needs to send to and then i send them Item by item with maybe some delay in between. So the sending of Data is somewhat 'synchronised'. However i dont know if this is a good solution and im thankful for any advice i could get.

So right now i connect to the Devices like that:

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

And i am sending data like this (without excess code):

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

So i was also thinking wheater i might need to use BluetoothServerSocket somehow. But im not sure about that.

The connection works perfectely with one Device connected only or two Devices connected but only sending to one Device (Sending very ocasionaly Data to the second one works usually very long before causing trouble).

I tried solving this for a long time but i cant get it working, so any help is creatly apretiated.

Hannes
  • 442
  • 2
  • 10
  • What is the exception when the connection to the second device breaks? – greeble31 Oct 25 '18 at 00:35
  • I get no exception, at least i was not able to catch it somewhere. Once i got an exception system/software connection aborted or similar. – Hannes Oct 25 '18 at 09:20
  • So the process just crashes, without any traces in the logcat whatsoever? – greeble31 Oct 25 '18 at 12:40
  • on one phone it does not even crashes i just stop recieving on one BT device. on the other i had no traces in the logcat. it just stops – Hannes Oct 25 '18 at 16:27
  • Hmm I'd like to see all the code that deals with your socket lifecycle: creation, use, and disconnection. – greeble31 Oct 25 '18 at 16:35
  • So my creation and use are already in the question (the code to send is executed either by a handler or when the user clicks a button) This is the code i use to disconnect: `try { pause(); // send some data outputStream.close(); outputStream =null; socket.close(); } catch (Exception e) { e.printStackTrace(); }` – Hannes Oct 26 '18 at 12:50
  • That's not quite enough code; I'm trying to determine the answers to questions like: 1.) How quickly the two sockets are started in relation to each other 2.) How long they exist simultanteously 3.) What threads are they running on 4.) How you prompt them to send more data and 5) How often they reconnect, and the reconnect logic. From the blurb you've posted, it looks like you send 9 bytes to the device then disconnect immediately, which makes it unlikely you're ever simultaneously connected in the first place. – greeble31 Oct 26 '18 at 13:16
  • Im connecting to one BTDevice send 9 Bytes, then i connect to the other BTDevice and send 9 Bytes to that Device as well. Than throughout the entire Appliction i never reconnect. I just send from time to time 9 Bytes to the devices. Sometimes i send them to one Device and then to the other immediately after that. I tested it with sending two one of those Devices every 5 seconds or so. e.g. Device1 9 Bytes -5sec- Device1 9 Bytes -5sec- Device2 9 Bytes -5sec- and than repeat. after 5 sec. – Hannes Oct 26 '18 at 13:29
  • So I will assume that 1.) each socket is run on its own dedicated background thread 2.) that you've handled all the thread synchronization concerns properly and 3.) you have appropriate error handling & reconnection logic in the event one connection experiences a problem. Is that correct? And, on your first phone, you must've determined the exact line that causes the crash, perhaps by bracketing it with log statements? – greeble31 Oct 26 '18 at 13:48
  • How do you determine that 1 device has "stopped receiving"? How do you know your Arduino code isn't the problem? – greeble31 Oct 26 '18 at 13:50
  • So far i did no syncronisation whatsoever and the outputStream.write() is not necessarily called from another thread. And i am not receiving anyithing from the BT Devices, so i dont listen to any incoming data. On the arduino i have print to the serial port the number of available Bytes from the Bluetooth Module (Serial.available()) when it enters the method to check incommming BT data. So i know it checks and i know it didnt recieve any data. Sometimes i noticed that although i call flush() it appears to take same time to send the data (longer than usually. – Hannes Oct 26 '18 at 16:06
  • I'd like more details on how you're using threads, based on your reply and the statement "at some point the App tries to send to two Devices at once and that causes trouble" I can't be confident that you're handling all the thread safety concerns correctly. The other problem is your assertion that the sockets are failing without throwing, and the program crashes without any sort of logcat output. Both situations strike me as very unlikely. More must be done to explain this. Are you sure you know how to use logcat? And, can any determination be made about the exact line it crashes on? – greeble31 Oct 26 '18 at 16:37
  • Also please make sure that you are not clobbering an existing reference when you assign a value to `this.socket`/`this.outputStream`... I assume you have 2 instances of whatever class contains those members, but that is not clear in the posted code. – greeble31 Oct 26 '18 at 18:16
  • Thanks for the help so far. Ill do some more research on where the error acours in the next days and post more of that code than. In the code samples the this keyword is not necesary, so there is no local variable with the same name. There is just one global socket/output stream. – Hannes Oct 26 '18 at 20:35
  • OK. Good luck. By the way, I didn't mean local variable. I mean, whatever class holds that variable -- you need to make sure you have at least 2 of them. That's important! – greeble31 Oct 26 '18 at 21:01
  • "There is just one global socket/output stream" -- that doesn't sound right. You have two connections, you need two sockets. If you have two sockets, you need two output streams. – greeble31 Oct 26 '18 at 21:03

1 Answers1

0

You can't connect simultaneously to the multiple BT device each with same BT service. That sounds like this, you have two BT speaker and you connected both of them and you started the music then both speaker plays. Not possible.

But you can connect multiple BT devices each one is different BT service: For example: Using BT mouse and BT speaker simultaneously. This is possible.

Sinan Ceylan
  • 1,043
  • 1
  • 10
  • 14
  • Ok, thanks for that info. So the type of BT service is defined via the UUID right? So changing one UUID schould work then? And is there an explenation why it works for some times (with two devices same UUID recieving Data)? – Hannes Oct 25 '18 at 09:23
  • Please have a look at this thread: https://stackoverflow.com/questions/13964342/android-how-do-bluetooth-uuids-work, and this: https://www.bluetooth.com/specifications/assigned-numbers/service-discovery – Sinan Ceylan Oct 25 '18 at 16:19
  • -1 BT devices have MAC addresses that make them uniquely identifiable. UUID is just for service discovery, like USB device class ids. You should, in fact, be able to connect to two sets of BT speakers simultaneously, if you were inclined to write client software that supports that. – greeble31 Oct 25 '18 at 16:45
  • @greeble31 Do you mean to modify client device's firmware? – Sinan Ceylan Oct 25 '18 at 17:06
  • Modifying the firmware should not be necessary in this case because the sockets are created at the behest of user-space software. – greeble31 Oct 25 '18 at 17:21
  • Thinking BT UUIDs as TCP ports may be good to grasp to understand how bluetooth UUID works. They work like TCP sockets and we need that sockets supports multiple connection, at least on the server side. As an example, there is a new feature has come with BT 5.0 called Dual Audio; if you have BT 5.0 compatible phone, you can connect two regular(not BT 5.0) speaker at the same time. Because server side supports dual BT Audio and can connect two audio device simultaneously. So, it is required that the BT standard that we use should support multiple connection on same UUID. – Sinan Ceylan Oct 25 '18 at 18:20
  • I agree about the TCP analogy but don't think applies to the OP's case; his software is acting as a client. The HC-05s act as two individual servers. – greeble31 Oct 25 '18 at 22:48