BLE Connect timeout

I’m trying to use the Boron as a central device to connect to a peripheral advertising at a rate of 5.140s. I’m able to successfully scan for it, but not connect. I’m calling:
BlePeerDevice peer = BLE.connect(scanResult->address);

I always get the following response after a few seconds:
[hal.ble] ERROR: connection failed: -250

I don’t see any options in the BLE documentation for extending the connection timeout period (the timeout parameter refers to timeout once a connection is already made, not timeout trying to connect). When connecting with a smartphone it usually successfully connects at second 10 or 15, but sometimes even longer, but it appears with the Boron it will stop trying to connect after 5 seconds, so it will never even have the chance to connect successfully to my peripheral. My Boron is running OS 1.4.4. Is there a way to extend the duration of attempting to connect, or do I just need to keep running BLE.connect multiple times until it works?

Have you tried multiple consecutive BLE.connect() calls?
What device is that slow connecting?

Ok, now on fail I have it trying again. I’m using the scanCallback and on detecting my sensor I stop scanning and try to connect;

0000020393 [app] INFO: Scanned our target sensor! Trying to connect...
0000025346 [hal.ble] ERROR: connection failed: -250
0000030300 [hal.ble] ERROR: connection failed: -250
0000035254 [hal.ble] ERROR: connection failed: -250
0000040208 [hal.ble] ERROR: connection failed: -250
0000045161 [hal.ble] ERROR: connection failed: -250

It’s clearly bailing after 5 seconds of trying to connect, and since it corresponds to our 5 second advertising rate it just lines up poorly. I then put a delay(2000) in before making the first attempt so that I could offset the advertising and the connection attempt, and that actually worked reliably. So while I’d say the solution is less than ideal, it’s manageable. I think the preference would be to make the connect timeout configurable so that we would only have to make a single call to BLE.connect.

To answer your other question, we’re trying to connect to our sensors, which run for more than a year on a CR2032. When they collect an event they advertise very quickly for a period, then less quickly for a period, then after about a minute they back off and go into slow advertising. Usually connecting to them isn’t a problem immediately after an event, but if the sensor isn’t near the Boron when the event happens, we have to be able to connect to our sensor even in slow advertising mode. Delaying 2 seconds before connecting just means that when the sensor is in fast advertising mode it is blasting out packets and burning energy for 2 seconds longer than it needs to be.

Hi… I saw your post and it’s the same issue I am having.

I’m using a Boron with multiple BLE sensors. I use the same logic as you when an event occurs in one of the sensors I go into fast advertising (around 25 ms) for the first 15 seconds, then drop down to about 2 seconds advertising for the next 15 seconds then after 30 seconds back to slow which I have around 7.5 seconds. This works for me in my application.

So by delaying at the start this give the fast advertising a chance to send connection packets so the connection works OK.

The one issue I would like to resolve is, I would like to write a service characteristic anytime I want to one of the sensors. But this requires that I connect first and I will be in slow (7.5 sec.) advertising. So far I haven’t figured a way to connect while in this slow mode.

Have you come across this issue and if so have you figured a way to do thus?

The answer I posted above IS our solution to this problem, and you can repeat scans as much as you want. If you’re advertising every 7.5 seconds, and the Boron will only scan for 5 seconds, then you can scan for 5 seconds, and if that fails scan immediately again, and you’ll have had a 10 second window where there was only a brief period that it didn’t scan. You can put a 1s delay in between scans to make sure that you don’t overlap the same window interval. You’ll miss about 15% of the time, but catch it on the next advertisement. So you’ll still connect in 7.5 seconds or less, but sometimes you’ll miss and it’ll be less than 13.5 seconds total before you catch the second advertisement.

You should be able to connect to a device even if you haven’t scanned it as long you know its address.
If you hold a repository of known sensor addresses (e.g. scanned within the last 24 hours) you can just pick any of these stored addresses to connect to even between advertising packets (as long the devices don’t actually sleep between adverts).

I’m not sure that’s right because connection packets are sent back from the BLE sensor at the speed the advertising is set . In my case it is about 7.5 seconds, so if the Boron times out in 5 seconds it may not catch the returning connection packets. I may be wrong on this so if anyone else has more information please respond.

I tried what you suggested and it works about 50%, but you are right if you keep a list of addresses you can start the connection process, here is the code I used to do it:

const BleAddress   ble_peer_address = BleAddress("D0:39:72:BA:0E:74");

bool connectandwriteCharacteristic()
            //try connecting up to 2 time
            for (int x = 0; x <= 1; x++) 
                ble_peer = BLE.connect(ble_peer_address1);
                if (ble_peer.connected()) 
                  Serial.println("Connecting successfully");   
            // Get the characteristic
                  bResult =  ble_peer.getCharacteristicByUUID(sensorCharacteristic, myCustomchar);
                  if (bResult) 
                        theValue = writevalue;                                  //value to write to the target characteristic
                        bResult = sensorCharacteristic.setValue(theValue);      //actually write the target characteristic
                        if (bResult)
                            Serial.println("Write Characteristic successful");
              // Disconnect from the peer and exit
                   return true;
            }   //end of connecting loop
                // publish("connection failed");
                Serial.println("Connection failed");
                return false; 

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.