Foundational time-division scheduler for transmission slots of UWB, BLE and L-MESH protocols.
Time-Division Multiple Access divides time into repeating superframes, and each superframe into slots. A device transmits only inside the slot assigned to it, so two devices never transmit at the same moment.
The alternative is random access: a device transmits whenever its own timer expires, and collisions are resolved by retrying. That works at low device counts and degrades sharply as they rise — a slotted random-access medium peaks at roughly 37% of channel capacity, beyond which a growing share of exchanges collide and are lost. Scheduling removes those collisions, and with them the defensive guard delays that exist only because transmissions are unpredictable.
| Region | Purpose |
|---|---|
| SYNC | Beacon from the sync master. Defines the time origin of the superframe and carries the schedule. |
| CFP — contention-free period | Assigned slots. A device transmits only inside its own slot, so exchanges never collide. |
| Sensor slots | Scheduled telemetry bursts (frame type 0x25), carrying Sensor TLV records. |
| CAP — contention access period | Open window where unsynced or newly arrived devices transmit to be discovered and admitted to the schedule. |
The same scheduler, the same superframe arithmetic and the same parameters serve deployments built on different radios. Two properties make that possible.
The ranging technology used inside the schedule is a runtime setting — the schedule itself does not change:
Parameter 0x7A | Mode | Behaviour |
|---|---|---|
0 | UWB only | UWB ranging in every slot — TWR or TDoA |
1 | UWB + BLE | Both technologies scheduled in one superframe; BLE slots allocated by parameter 0x7B |
2 | BLE only | No UWB radio in the deployment; BLE ranging and telemetry use the same slot structure |
Because the mode is a parameter rather than a different firmware or a different scheduler, a site can change configuration without re-provisioning the schedule.
Slot arithmetic is not tied to any one clock. The scheduler is given a counter width and a tick rate, so it runs on whichever clock the hardware in a given deployment actually has:
| Clock | Width / rate | Used when |
|---|---|---|
| UWB timestamp counter | 40-bit at 63.8976 GHz (~15.65 ps per tick) | UWB is present — the same clock the ranging engine timestamps frames with |
| MCU timer | 32-bit at 16 MHz | BLE-only deployments |
| Low-power RTC | 24-bit at 32.768 kHz (~30 µs per tick) | BLE-only, where the schedule must survive low-power modes |
Generalising the clock costs no accuracy. Fine timestamp resolution matters for ranging, not for scheduling: slot boundaries are milliseconds apart, which even a 32.768 kHz tick resolves comfortably. The picosecond timestamp is still used where it matters — in TWR and TDoA measurement.
All slot arithmetic is performed modulo the counter width, so a wrapping counter needs no special handling by the caller.
Schedule fields are master-authoritative. One device is the sync master; every other device adopts the schedule from the beacon and does not accept local writes to those fields (parameters 0x72–0x76, 0x7B, 0x7D). Nothing has to be provisioned per device — everything needed to take a place in the schedule arrives on the beacon.
| Parameter | Setting |
|---|---|
0x71 | TDMA enable |
0x72 | Sync master (exactly one device) |
0x73 | Superframe period, microseconds |
0x74 | Slot count |
0x75 | CAP slots |
0x76 | Sensor slots — 0 disables scheduled telemetry |
0x7A | Ranging technology (UWB / UWB+BLE / BLE) |
0x7B | Slots allocated to BLE ranging |
Two parameters set the capacity of a deployment, and they are the ones worth getting right before anything else.
The superframe period (0x73) is the per-tag update interval — a device gets one slot per superframe, so the period is the reporting rate:
update rate = 1 ÷ superframe period
tags per second = slot count (0x74) ÷ superframe period (0x73)
slot duration = superframe period ÷ slot count
A slot must hold every exchange a tag performs in its turn, plus a guard:
slot = 2 × frame + 2 × PollResponseDelay + anchors × response window + guard
A TWR position needs a range to at least three anchors — a single distance is not a position. The poll and final are broadcast once and shared, so each additional anchor adds only its response window. The number is capped by the runtime parameter max_anchor_num_twr (default 3): a tag ranges until it reaches the cap, then stops looking.
Because it is a cap rather than a count, the schedule is sized once and serves areas of differing anchor density unchanged. A tag in a two-anchor area ranges twice and leaves the rest of its slot idle; a tag in a six-anchor area stops at the cap. Nothing is reconfigured as tags roam.
| PHY | Frame | Position — 3 anchors | Slot | Locations/s |
|---|---|---|---|---|
| 110 kbps, preamble 2048 | ≈ 3.74 ms | ≈ 22.1 ms | 24 ms | ≈ 34 |
| 850 kbps, preamble 2048 — default | ≈ 2.26 ms | ≈ 14.6 ms | 17 ms | ≈ 52 |
| 850 kbps, preamble 512 | ≈ 0.73 ms | ≈ 7.1 ms | 8 ms | ≈ 118 |
| 6.8 Mbps, preamble 256 | ≈ 0.31 ms | ≈ 5.0 ms | 6 ms | ≈ 160 |
Tabulated at the default cap of three. Raising the cap adds one response window per anchor rather than a whole exchange — figures on the UWB TWR page.
The guard is roughly 10%. It covers clock drift between a device and the schedule (about 20 µs over a 500 ms superframe), receiver enable margin, and inter-slot processing on the MCU.
TDoA has no per-anchor term at all. One blink reaches every anchor at once and nothing is sent back, so its slot holds a single frame no matter how many anchors are listening — where a TWR slot still grows by one response window for each anchor in the cap.
The superframe reserves slots for the beacon and for contention access, so the ranging count is lower than the slot count:
ranging slots = slot count − 1 (SYNC) − CAP slots − sensor slots
| Region | Default |
|---|---|
| SYNC — the beacon | 1 slot, always |
| CAP — contention access for unsynced devices | 2 slots |
| Sensor telemetry | 0 — opt-in |
| BLE distance measurement | 0 — opt-in |
Sensor slots cost nothing unless enabled. They default to zero deliberately — reserving airtime for telemetry nobody is sending would shrink ranging capacity for no benefit. Enabling them takes slots directly from ranging, so a deployment that turns telemetry on gives up tags to get it.
At the default configuration that leaves 26 ranging slots of 29 — the beacon and contention window cost three slots whatever the PHY, so the overhead matters most where slots are few. Every figure on the TWR and TDoA pages already accounts for it.
| PHY | Slot | Slots in 500 ms | Ranging slots | Tags at 2 Hz |
|---|---|---|---|---|
| 110 kbps, preamble 2048 | 24 ms | 20 | 17 | 17 |
| 850 kbps, preamble 2048 — default | 17 ms | 29 | 26 | 26 |
| 850 kbps, preamble 512 | 8 ms | 62 | 59 | 59 |
| 6.8 Mbps, preamble 256 | 6 ms | 83 | 80 | 80 |
| PHY | default — 850 kbps, preamble 2048 |
| Position — 3 anchors | ≈ 14.6 ms |
| Slot duration | 17 ms — a 10% guard |
| Superframe period | 500 ms |
| Slot count | 29 — 1 SYNC, 26 ranging, 2 CAP |
| Per-tag update rate | 2 Hz |
| Throughput | 26 tags at 2 Hz |
Raising the slot count raises throughput but shortens each slot; lengthening the superframe lengthens the slots but slows every tag. The two move against each other, which is why capacity and update rate cannot be chosen independently.
An undersized slot is worse than no schedule at all. Exchanges that do not fit overrun into the next device's slot — so TDMA would cause the collisions it exists to prevent, and do it deterministically rather than occasionally. Devices publish their measured exchange duration so the scheduler can verify a slot is large enough before it begins gating ranging on slots.
Confirm the position duration on a bench unit before committing a schedule to a site — devices log their measured frame and delay figures at start-up, and the slot column above assumes a 10% guard on top of them.
Per-PHY throughput and the range each setting costs are tabulated on the UWB TWR and UWB TDoA pages.
| Value | Frame |
|---|---|
0x10 | Blink / poll response / ranging confirm |
0x16, 0x17, 0x19 | Config request / response / error |
0x21, 0x23 | Poll, final |
0x24 | TDMA sync beacon |
0x25 | Sensor data |
0x61–0x66 | Firmware upgrade, button event, reboot |
On devices that carry both a UWB radio and a GNSS receiver, the TDMA beacon is also the indoor coverage signal. Site arbitration uses the schedule directly:
The two radios are therefore never operated simultaneously, and the schedule is what decides between them. Behaviour is set by site mode (parameter 0x83): auto, force indoor, or force outdoor.