Hi Ondrej,

Some tips inline below.

On Thu, Apr 9, 2020 at 5:46 PM Ondrej Pilat <ondrej.pi...@ozobot.com> wrote:

> Hi,
>
> I cannot find any documentation about Nimble connection events scheduling.
> I have following scenario:
>
> NRF52 Nimble is in dual role setting. Peripheral device connected to a PC
> with at least BLE 4.2 and MTU more than 153B. Central is connected to 18
> peripheral devices BLE 4.1 with MTU 27B.
>
> Do you think that Nimble can keep interval window 12.5ms with the PC and
> 37.5ms with all peripherals?
>
> My assumption are following:
>
>    - only one packet per each connection event
>    - send/receive 132B packet between NRF52 and PC each connection event
>    - send/receive 20B packet between NRF52 and peripheral each connection
>    event
>
> I made following rough computation:
>
> PC <-> NRF52: 132B data + 21B header => (153B * 8) / 1Mbps => 1224 uS +
> 150 uS IFR + 80 uS ACK + 150 uS IFR => 1604 uS * 2 (send/receive) => 3208
> uS
>
> NRF52 <-> peripheral: 20B data + 21B header => (41B * 8)  / 1Mbps => 328uS
> + 150 uS IFR + 80 uS ACK + 150uS IFR => 708uS * 2 (send/receive) => 1416 uS
>
> It means one big and six small packets should fit in each PC <-> NRF52
> connection event 3208 + 6 * 1416 = 11 704 < 12.5ms interval window. For 18
> peripherals it means 3 such cycles to serve them all therefore 37.5ms
> interval window between NRF52 and a peripheral.
>

You need to take NimBLE scheduling into account here. Each connection event
is preallocated a fixed amount of time in 1250us slots - see
BLE_LL_CONN_INIT_SLOTS. This means effectively connection events cannot be
scheduled less than 1250us apart. Also, scheduler overhead is ~200us (for
nRF52, may be different for nRF51) for each connection event so effective
connection event time with 1 slot allocated is 1050us. Note that this is
min time since connection events can be extended pretty much indefinitely
as long as there is no other activity scheduled so e.g. until another
connection event.

I do not know if "20B packet" means "20 bytes of LL payload", but will
assume so since we are talking LL level here. This can fit into a single
scheduled slot: 240us + 150us + 80us = 470us < 1050us. Let's assume 1ms for
each connection event including scheduler overhead so you need 18ms to
serve all 18 devices in one direction. If you need to send data in both
directions you need 240us + 150us + 240us = 630us < 1050us so nothing
changes and you still have quite a lot of extra time to spare in each
connection event (e.g. for retransmissions). It will be a bit different if
you need to transfer data in both directions in separate connection events
as basically you need twice as much connection events, this means you need
at least 36ms to serve all peripherals. One possible problem here is that
connection may not be scheduled exactly 1.25ms apart and this will create
gaps where no connection can be scheduled, you can't really control this
with default scheduler. Possible solution would be to use
BLE_LL_STRICT_CONN_SCHEDULING which schedules connections in central role
at fixed intervals, although I never used it so not sure if there's
anything that requires more configuration than just enabling this feature.

So dealing with peripherals should not be a problem. Connection with a PC
is a more troublesome since NimBLE has a slave role here so it needs to use
anchor point imposed by a master. In theory, as a slave you can request to
move anchor point but you would need to guarantee there is slot of proper
duration and at proper intervals (so slave connections need to be arranged
properly) for this to make any sense. NimBLE does not yet allow to move
anchor point since it does not have any logic to do this in a way that
makes any sense. Perhaps the best solution you could try for now is just to
ignore connection with a PC in your scheduling so it will be scheduled at
the time of some peripheral connection. In such case, NImBLE will let the
least recently active connection run so it will skip connection events on
"random" connections. It should not impact data throughput since
outstanding data will be sent at next connection interval, but it will
likely impact latency so you just need to check it this is acceptable in
your case.

Are following parameters good to achieve this:
>
> NRF52 <-> PC
>
> static const struct ble_gap_conn_params ble_gap_conn_params_ideal = {
>    .scan_itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN,
>    .scan_window = BLE_GAP_SCAN_FAST_WINDOW,
>    .itvl_min = 10,
>    .itvl_max = 10,
>    .latency = 0,
>    .supervision_timeout = 500,
>    .min_ce_len = 5, // 3.208 / 0.625 = 5.1328
>    .max_ce_len = 6,
> };
>
> NRF52 <-> Peripheral
>
> static const struct ble_gap_conn_params ble_gap_conn_params_ideal = {
>    .scan_itvl = BLE_GAP_SCAN_FAST_INTERVAL_MIN,
>    .scan_window = BLE_GAP_SCAN_FAST_WINDOW,
>    .itvl_min = 30,
>    .itvl_max = 30,
>    .latency = 0,
>    .supervision_timeout = 500,
>    .min_ce_len = 2, // 1.416 / 0.625 = 2.2656
>    .max_ce_len = 3,
> };
>

NimBLE controller does not use min/max ce len parameters, you can just
leave them at default values.


> Regards
>
> Ondrej
>
Best,
Andrzej


> --
>

Reply via email to