KW36: Multiple connection timing

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

KW36: Multiple connection timing

Jump to solution
1,531 Views
finn_schmitz
Contributor II

Hallo all,

I am running a FRDM-KW36 with SDK 2.2.1 as BLE central (without low power mode, module is always on) in an environment with multiple peripherals.

The overall data exchange and battery life requirements dictate, that the advertisement is quite slow (currently 3 s) and the connection intervals fast (10 ms). Nontheless, we need all peripherals to be connected once the central is switched on in a few seconds time.

My expectation was the following:

  • The KW36 would connect on the first scanned advertisement package from the peripheral it is supposed to connect to
  • The KW36 would scan/(initiate connections to the other peripherals) in parallel to any delay in the connection made to the first peripheral. So that there would be some kind of parallel handling

However the behavior I see (see screenshot) is the following:

  • The KW36 will initiate the connection on BleApp_ScanningCallback with event gDeviceScanned_c on the first package scanned, but the connection will only be done (BleApp_ConnectionCallback with gConnEvtConnected_c) one advertisement cycle later (so in my case 3s later). Can this be changed, so that not a whole advertisement intervall takes place to connect? I find the behavior surprising since The ScanningCallback directly calls App_Connect().
  • I would expect, that in the meantime (3s), the KW36 would continue to scan and hence also initiate connections with the other peripherals (BleApp_ScanningCallback with gDeviceScanned_c does not stop the scanning explicitly). But as you can see, the 3 peripherals are connected completely serially, which takes quite a long time in total. How can this be parallelized?

So I guess you get the overall question: What needs to be done here to get all peripherals to connect much quicker, WITHOUT reducing the advertisement interval of the peripherals? Or is the behavior I see a limitation of the stack or the controller?

For example when I trace a startup not with the KW36 but with an dedicated app on iPad to connect to the peripherals, I see a connection on the first advertisement package, it does not take 3 seconds.

Thank you for your help.

Kind regards

Finn

Labels (2)
1 Solution
1,369 Views
Xiang_Li
NXP Employee
NXP Employee

In fact I forget 1 thing which could help you maybe.

When making a connection, we could either choose 1 specific device address, or we could use the whitelist. If we are using the whitelist, the connection can be made if the adv address matches any entry inside the whitelist.

Refer to gapConnectionRequestParameters_t and bleInitiatorFilterPolicy_t.

So I would do this if I were you:

(1) Start scanning for several seconds, try to find all adv devices nearby. I would scan N sec (N = 6 or 9 or more) if the adv interval is 3s. This makes sure if we miss 1 adv packet, we still have chances to pick up for a 2nd try.

(2) When you receive a scan event, do not make connection immediately. Instead just remember the peer device address (to be connect later), and continue the scanning.

(3) After N sec, all adv address nearby should be picked up and saved in a local array/table.

(4) Update whitelist, add all addr values into whitelist.

(5) Check gap_interface.h, and APIs like Gap_ClearWhiteList(), Gap_AddDeviceToWhiteList() etc.

(6) Call gap_connect(), but setup the connection parameter to use whitelist as the filter policy. This makes sure the initiator to connect any adv device whose addr has been stored in the whitelist.

(7) If a connection complete event callback is returned, continue to do next gap_connect(), until all the connections are made.

This would be more efficient then your initial way.

And if you can presume/hardcoded peer device addresses, step 1-3 can be skipped, which will save you even more time.

View solution in original post

6 Replies
1,368 Views
Xiang_Li
NXP Employee
NXP Employee

Hi Finn,

In the BLE spec, if a central wants to connect to a peripheral device, it has to wait for an ADV packet, and then sends out a CONN_REQ packet 150us after that ADV packet.

In your case, when the central scanned the 1st ADV packet, it immediately switches to the connecting mode, and waits for the 2nd ADV packet where the CONN_REQ should be following.

But the adv interval is ~3s, so the CONN_REQ is sent in actual 3s later, and the whole connection procedure is also ~3s. The timing seems logical to me.

When receiving the event gDeviceScanned_c, we could try not to call Gap_StopScanning() and App_Connect(). This keeps the central device in the scanning mode to scan other adv devices.

But eventually we have to get into connecting mode, and then still it has to wait for the next ADV packet (max 3s) to come. So the total time is still (N devices) x (max 3s per devices).

I don't think KW36 can initiate connections to multiple devices at the same time, i.e. we have to call App/Gap_Connect() once, and wait for the connection complete event/callback, then in that callback we initiate connection to next device. So there are not much we can do if the ADV interval has to be 3s long.

Alternatively, there maybe another solution is try to keep your central / n peripherals always connected, if your central is not battery based (not power sensitive). The connection interval can set up to 4s. And you could use slave_latency feature to reduce the power consumption on the slave side.

You can always configure the connection event length properly, so when data exchange is needed, it can be done within 1 connection interval.

Regards,

Xiang

1,369 Views
finn_schmitz
Contributor II

Hallo Xiang,

oh, this is the response I was hoping not to get, actually.

Is there no way around the fact, that Gap_Connect() waits for the next advertisement package to send the connection request, even though it has been called immideately after the first advertisement package has been received?

As I said, when I trace the connection being initiated by an iPad, I clearly see that the connection request is send on the first package, not on the second.

Or is this simply a computational/time constrain on the micro?

I understand, that it is not implemented, to get other BleApp_ScanningCallback with gDeviceScanned_c while a Gap_Connect() call has not returned with its callback. But I would ask to give it a thought if this would not be a good update to your stack, since at least in our use case there would surely be ample time to go back into scanning in those 3 s, that are otherwise completely "lost time".

Kind regards

Finn Schmitz

0 Kudos
1,369 Views
Xiang_Li
NXP Employee
NXP Employee

Hi Finn,

When initiating a connection, the initiator device must know the address of the advertising address. To get to know which adv device is nearby, we do scan to discover those adv devices.

But when we already know the adv address, e.g. if we just made a connection, and trying to disconnect + reconnect, we can assume the adv device is still there. In this case, we can skip the scan procedure, and directly issue a connect command to the presumed adv device address.

For your case, if you know all the adv device addresses, i.e. if they are hardcoded or somehow they are pre-shared, we can modify the BLE application to skip scan and directly enter initiating state. And it would probably save you lots of time in total.

I don't know how iPad is doing this, but normally in BLE, devices would remember the last connected addresses, and use them to fast-reconnect to existing nearby devices.

>> since at least in our use case there would surely be ample time to go back into scanning in those 3s

Please note that, the scanning device cannot know what is the peer devices adv interval. It can be anything from 3s to 300ms to 30ms. In the future BLE spec there will be a periodic adv feature introduced, but not in the current implementation. So standing at the scanner's point of view, it cannot say: "hey, we just receive a  packet, the next one will come in 3s, so now we can do something else."

Unless if you control both ends of the BLE connection, then you can make assumption from system level, in that case some optimization could be assumed. But in general, Bluetooth is a public standard, when NXP is making a chip, we have to consider that it can be connected to any BLE chip made by any BLE vendors. So the "3s" assumption cannot be made.

But you are right it is technically possible to do (active/passive) scanning and initiating a connection simultaneously. In this case, if a packet arrives, the chip has to check on the fly that whether it is to be connected, or whether it is to be scanned. And if both conditions are met, which takes the priority. As you can see it would complicate the design a lot more, not as easy as it looks. To my knowledge it is not supported currently, but maybe a good idea to do in the future.

Kind regards,

Xiang

1,369 Views
finn_schmitz
Contributor II

Hallo Xiang,

thank you once again for your precise and all-encompassing answers!

Your comment on the central not knowing the advertisement interval makes total sense. I should have figuered that out myself. And I did not know, that you could connect direktly without scanning, I will try that and see what impact it has.

As for the second point, for us it would in fact still be very interesting and a useful feature, since we are planning to only be available to one type of peripheral, which is in our hands as well. So we would know the exact configuration of central and peripherals.

Kind regards

Finn

0 Kudos
1,370 Views
Xiang_Li
NXP Employee
NXP Employee

In fact I forget 1 thing which could help you maybe.

When making a connection, we could either choose 1 specific device address, or we could use the whitelist. If we are using the whitelist, the connection can be made if the adv address matches any entry inside the whitelist.

Refer to gapConnectionRequestParameters_t and bleInitiatorFilterPolicy_t.

So I would do this if I were you:

(1) Start scanning for several seconds, try to find all adv devices nearby. I would scan N sec (N = 6 or 9 or more) if the adv interval is 3s. This makes sure if we miss 1 adv packet, we still have chances to pick up for a 2nd try.

(2) When you receive a scan event, do not make connection immediately. Instead just remember the peer device address (to be connect later), and continue the scanning.

(3) After N sec, all adv address nearby should be picked up and saved in a local array/table.

(4) Update whitelist, add all addr values into whitelist.

(5) Check gap_interface.h, and APIs like Gap_ClearWhiteList(), Gap_AddDeviceToWhiteList() etc.

(6) Call gap_connect(), but setup the connection parameter to use whitelist as the filter policy. This makes sure the initiator to connect any adv device whose addr has been stored in the whitelist.

(7) If a connection complete event callback is returned, continue to do next gap_connect(), until all the connections are made.

This would be more efficient then your initial way.

And if you can presume/hardcoded peer device addresses, step 1-3 can be skipped, which will save you even more time.

1,369 Views
finn_schmitz
Contributor II

I have tried connecting directly with the hardcoded adresses and it works nicely. It reduces the connection time from 3-6 s to 0-3 s per peripheral, which is already good.

Using whitelist in addition to this makes it possible to get multiple peripherals connected within any 3 s time slot. 

This is a big performance difference, thank you very much!

Kind regards

Finn