bluetooth beacon

Most BLE Tag designs are either pure broadcasters (a locator that never listens) or continuous scanners (a tag that must hear a gateway ping). The broadcaster is invisible to centralized commands; the scanner drains a coin cell in weeks. This article covers the middle ground: making a tag reachable on demand while keeping average current in the single-digit microamps.

The reachability problem

A BLE tag that only advertises cannot be paged. If you want to “find this specific asset now” or push a config change, the gateway has nothing to talk to. The naive fix is to have the tag scan continuously:

  • RX current on a typical SoC (nRF52840, nRF5340): 4-8 mA
  • A CR2032 with ~220 mAh usable: 220 / 8 approx 27 hours

That is unacceptable. Continuous listening turns a multi-year tag into a day-trip tag.

Three listening strategies

Strategy Listen current Reach latency Annual battery cost*
Continuous scan 5-8 mA ~10 ms drains in days
Periodic (duty-cycled) scan 200-400 uA avg one interval (e.g. 2 s) months
Wake-up radio (WuR) 50-200 nA wake symbol + boot (~5-50 ms) years

*Assuming CR2032, idle broadcast 5 uA baseline added on top.

The duty-cycled scan trades latency for current: open an RX window of W ms every T ms. Average listen current approx I_rx * W / T. With W=100 ms, T=2000 ms, I_rx=5 mA: avg approx 250 uA. Add baseline and you are at ~300 uA – months of life, but far from the years a pure broadcaster gets.

Wake-up receivers

A wake-up radio is a second, ultra-low-power receiver tuned to a dedicated wake symbol. It listens almost continuously at 50-200 nA and, on detecting a valid wake pattern, powers the main BLE radio. Because the main radio only runs after a wake event, its 5 mA RX current is amortized over rare events.

WuR implementations for BLE-class tags:

  • Sub-GHz OOK/ASK WuR (e.g. 433 MHz, 868 MHz): long range, cheap, proprietary PHY. A gateway blast wakes all tags in range; each validates a token before booting BLE.
  • Inductive 125 kHz: very short range (cm-m), good for “tap to wake” readers, immune to 2.4 GHz congestion.
  • In-band preamble sniff: some SoCs run a low-power sniff of the BLE preamble; not a true WuR but cheaper than full RX.
  • Dedicated WuR IC: standalone chip on 2.4 GHz feeding an interrupt to the SoC; total listen ~100 nA.

There is no standard BLE wake-up; every vendor does it proprietarily. Plan for a gateway that speaks your WuR PHY.

Latency math

Connectionless paging: max latency = T_wake_window_period. If the gateway transmits the wake symbol for L ms and the WuR samples every S ms, a tag responds within S + boot. With S=100 ms and BLE boot 20 ms, worst case ~120 ms.

Connection-oriented (gateway then connects): add connection establishment (~30-80 ms) and GATT discovery if not cached. Budget ~150-250 ms end to end.

A periodic-scan tag has worse worst case: it may just miss the gateway’s paging window and wait a full interval T. With T=2 s that is up to 2 s latency – fine for “locate asset” but poor for interactive use.

Power budget example

A tag paged 10 times/day, each wake booting BLE for 200 ms at 5 mA:

  • WuR listen: 100 nA * 86400 s = 8.64 mC/day
  • 10 wakes * 200 ms * 5 mA = 10 mC/day
  • Baseline broadcast 5 uA * 86400 = 432 mC/day
  • Total approx 451 mC/day -> CR2032 (220 mAh = 792000 mC) -> ~4.8 years

The WuR listen current is rounding error. That is the whole point.

Implementation sketch

<h1>pseudo: nRF-style wake on interrupt from WuR IC</h1>

def on_wake_interrupt():
ble.power_on()
ble.advertise_wake_token(signed_token)   # prove it is a real page
if gateway.connected:
handle_command()
ble.power_off()

<h1>RTC schedules a fall-back periodic scan if WuR fails</h1>

rtc.every(3600s, short_scan, window_ms=50)

The signed wake token matters: without it, an attacker with a WuR transmitter can wake every tag in range continuously and drain the fleet (a denial-of-sleep attack).

Security note

An unauthenticated wake symbol is a battery-DoS primitive. Require an authenticated, replay-protected token (e.g. HMAC with a per-tag key + rolling counter). A tag that cannot verify the token must stay asleep. Also rate-limit: ignore a second wake within N seconds to blunt a jam-and-drain loop.

When to use a WuR tag

  • You must page specific assets (“show me where pallet X is right now”).
  • Tags sleep years between contacts (cold-chain, static assets).
  • Gateway density is low and you cannot afford per-tag continuous coverage.

Skip it if the tag is a pure broadcaster already covered by fixed gateways, or if latency under ~100 ms is mandatory (then keep a small periodic scan).

Bottom line

A BLE Tag does not have to choose between “never reachable” and “battery dead in a week.” A wake-up receiver moves the listening cost from milliamps to nanoamps, and a duty-cycled scan is the pragmatic middle ground when a WuR PHY is not available. Size the wake window and interval against your latency budget, authenticate the wake, and the tag stays reachable for years.