Commit 9d2a823
committed
drv/bluetooth: Fix broadcasting and observing at the same time.
All three Bluetooth drivers scanned with the window equal to the interval,
30ms of every 30ms, so the radio was never free and a hub that broadcasts
while observing could hardly transmit. Measurements in
https://github.com/orgs/pybricks/discussions/2822 show a City Hub dropping
from 28 packets/s to under 4 when it does both at once.
Halving the window is not enough on its own: a 20ms interval with a 10ms
window only reached 5.7 packets/s. Duty cycle does not set throughput by
itself, because starting and ending a scan costs radio turnaround and
scheduler time, and a 20ms period pays that fifty times a second. Use a 70ms
interval with a 35ms window, which measured 12.3 to 13.0 packets/s. 70ms is
not a multiple of the 25 to 30ms advertising interval of the faster hubs nor
of the Move Hub's 100ms, so reception does not settle into a pattern of
repeatedly missing a peer.
Broadcasting on the BTstack hubs goes from every 100ms to every 30ms. 100ms
was the Bluetooth 4.x minimum for non-connectable advertising, but the
CC2564C is 5.1, where the minimum is 20ms, so the old value only limited how
quickly other hubs could hear it. The Move Hub keeps 100ms because the
BlueNRG-MS is a 4.1 controller and cannot go faster; it is the most limited
hub, so it is allowed to be the slow one rather than holding the others
back.
City Hub and Technic Hub need one more setting. TI documents
TGAP_CONN_SCAN_INT and _WIND as the scan parameters for the Link Layer
Initiating state, in other words for connecting to a device, so we set only
the general discovery pair. But GAP_DeviceDiscoveryRequest() uses the
connection pair in place of the discovery pair whenever a connection exists,
which is ordinary observing and not initiating at all. With a computer
connected the chip therefore used TI's defaults of a 150ms window every
300ms. That is also a 50% duty cycle, so it looked harmless, and transmit
throughput even appeared better when connected.
Timestamping every advertisement received shows why it was not harmless. A
City Hub observing a Technic Hub that only broadcasts received 4.9 packets/s
while connected against 16.5 standalone, and the gaps between updates were
either under 40ms or over 150ms with nothing in between: one short burst of
reception every 300ms. The window never ran to completion either, because a
connection event cuts the scan short and the remainder is discarded rather
than resumed, leaving about 48ms of the 150ms. Transmit throughput looked
good for the same reason the hub could barely hear anything.
Worse, 300ms is a whole number of connection intervals for every interval a
host is likely to choose, so the offset between a scan window and the next
connection event never drifts and the same slice is lost every time. Apple
hosts use 15ms, which would cap the effective window at a 5% duty cycle.
Setting the pair to the same 70ms and 35ms brings reception while connected
to 11.5 packets/s, and the typical wait for an update from 192ms down to
71ms against 64ms standalone. The worst case is unchanged at about 300ms,
now an occasional stall rather than the normal cycle. A connected hub
broadcasting and observing at once still transmits about 19 packets/s, so
none of this was paid for out of the first fix.1 parent 11d0901 commit 9d2a823
4 files changed
Lines changed: 31 additions & 7 deletions
File tree
- lib/pbio/drv/bluetooth
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
12 | 18 | | |
13 | 19 | | |
14 | 20 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1156 | 1156 | | |
1157 | 1157 | | |
1158 | 1158 | | |
1159 | | - | |
| 1159 | + | |
| 1160 | + | |
1160 | 1161 | | |
1161 | 1162 | | |
1162 | 1163 | | |
| |||
1175 | 1176 | | |
1176 | 1177 | | |
1177 | 1178 | | |
1178 | | - | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
1179 | 1183 | | |
1180 | 1184 | | |
1181 | 1185 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
587 | 587 | | |
588 | 588 | | |
589 | 589 | | |
| 590 | + | |
| 591 | + | |
590 | 592 | | |
591 | 593 | | |
592 | 594 | | |
| |||
642 | 644 | | |
643 | 645 | | |
644 | 646 | | |
645 | | - | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
646 | 651 | | |
647 | 652 | | |
648 | 653 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1562 | 1562 | | |
1563 | 1563 | | |
1564 | 1564 | | |
1565 | | - | |
1566 | | - | |
1567 | | - | |
1568 | | - | |
| 1565 | + | |
| 1566 | + | |
| 1567 | + | |
| 1568 | + | |
| 1569 | + | |
| 1570 | + | |
| 1571 | + | |
| 1572 | + | |
| 1573 | + | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
1569 | 1578 | | |
1570 | 1579 | | |
1571 | 1580 | | |
| |||
0 commit comments