TS-2102B

A plain advertising beacon only answers one question: “where is this tag?” Add a sensor — temperature, humidity, acceleration, light — and the same hardware becomes a distributed measurement node answering “what is the condition here, and did anything change?” This article covers the engineering decisions behind sensor beacons: how to interface sensors, how to pack readings into the 31-byte advertising payload, how sampling cadence drives battery life, and how on-device threshold logic turns a dumb broadcaster into an edge detector.

1. Why Sensor Beacons Are Different

A location-only beacon transmits a fixed payload at a fixed interval. Its power draw is deterministic and its firmware is trivial. A sensor beacon must:

1. Wake the sensor from sleep (or keep it in a low-power sampling mode)

2. Acquire a reading over I2C/SPI, which takes milliseconds and draws sensor quiescent current

3. Process the value (filtering, calibration, threshold check)

4. Decide what to send — the raw value, a delta, or nothing

5. Encode and advertise the result

Each step adds latency and current. The design problem is balancing measurement fidelity against battery life, because the sensor subsystem — not the radio — usually dominates the budget once you sample more than a few times per hour.

2. Sensor Interfaces and Current Draw

Most beacon sensors hang off a digital bus. The two common choices:

Interface Speed Typical sensor current Wake latency Notes
I2C 100-400 kHz 1-15 µA idle, 100-500 µA active 1-5 ms 2 wires, address-limited, easy to share
SPI 1-8 MHz 2-20 µA idle, 200-800 µA active 0.1-1 ms 4 wires, faster, lower latency

For a coin-cell beacon, the dominant cost is not the active current but the energy per sample = (wake_latency + conversion_time) × average_current. A humidity sensor that takes 10 ms at 300 µA costs 3 µC per reading. At 1 sample/hour that is 3 µC/h ≈ 0.83 µA average — negligible. At 1 sample/minute it is 50 µA average — now competing with the radio.

2.1 Common sensors and their footprints

Sensor Typical part Bus Active current Conversion time Output range
Temperature TMP117 I2C 3.5 µA 15.5 ms (avg) -0.1 to 0.2 °C
Humidity HDC2080 I2C 300 µA 1.2 ms ±2 % RH
3-axis accel LIS2DH12 I2C/SPI 4 µA (low-power) 1 ms ±2/4/8/16 g
Ambient light OPT3001 I2C 1.8 µA 100-800 ms 0.01-83k lux
Pressure LPS22HB I2C/SPI 25 µA 13 µs (ODR) ±0.025 hPa
CO2 (NDIR) SCD40 I2C 18 mA (pulse) 0.5-5 s 0-40000 ppm

The CO2 sensor stands out: at 18 mA it is 1000× the radio’s sleep current and cannot run on a coin cell continuously. It is the canonical example of why sensor choice constrains the power architecture — a CO2 beacon needs a larger cell or wired power.

3. Encoding Sensor Data in 31 Bytes

A BLE advertising packet carries a 31-byte payload (legacy) split into AD structures: a 1-byte length, 1-byte type, then data. iBeacon uses 25 bytes of manufacturer data; Eddystone-URL uses ~20. That leaves little room for sensors.

3.1 The “append, don’t replace” rule

Keep the identity frame (iBeacon / Eddystone-UID) intact for location systems, and add a secondary advertising frame carrying sensor data. BLE lets a beacon cycle between multiple advertising frames (alternating on each advertising event). A gateway scanning all three channels over a few seconds captures both.

3.2 Eddystone-TLM: the built-in sensor channel

Eddystone-TLM is the standards-based way to carry telemetry:

Field Bytes Content
Version 1 0x00
Battery voltage 2 1 mV units, 0-65535
Beacon temperature 2 8.8 fixed point, °C
PDU count 4 Lifetime packet count
Uptime 4 0.1 s units

TLM is clean but limited: one temperature value, battery only, no humidity/accel. For richer data you need a custom manufacturer-specific data (MSD) frame.

3.3 Custom MSD encoding example

A compact packed layout for a multi-sensor beacon (little-endian):

Byte 0:    Company ID LSB (0x4C for Apple, or your assigned CID)

Byte 1: Company ID MSB

Byte 2: Frame type = 0x50 (vendor sensor frame)

Byte 3: Sensor bitmap (bit0 temp, bit1 hum, bit2 accel, bit3 light, bit4 batt)

Byte 4-5: Temperature, 8.8 fixed point, signed (×256)

Byte 6-7: Humidity, 8.8 fixed point (×256)

Byte 8-9: Light, 10-bit log scale (0-1023 → 0.01-100k lux log)

Byte 10-11:Battery mV (0-65535)

Byte 12-13:Accel magnitude, 8.8 fixed (g × 256)

Byte 14: Status / flags (motion detected, threshold tripped)

Byte 15: Sequence number (wraps 0-255)

This 16-byte frame fits alongside an iBeacon identity frame with room to spare. The bitmap lets a beacon omit absent sensors, shrinking the payload. A temp-only beacon sends bytes 0-7 (8 bytes); a full sensor node sends all 16.

3.4 Compression tricks

  • Delta encoding: advertise the change since last reading, not the absolute. A temperature drifting 0.1 °C/hour fits in a signed 8-bit delta (±127 × 0.01 °C) instead of a 16-bit absolute.
  • Fixed-point over float: 8.8 fixed point costs 2 bytes for ±127.99 with 0.004 °C resolution — plenty for environment monitoring.
  • Log-scale light: `encoded = round(1023 × log10(lux/0.01) / log10(100000/0.01))` packs 5 decades into 10 bits.
  • Run-length skip: if nothing changed beyond noise floor, send a heartbeat frame every N cycles instead of every cycle.

4. Sampling Strategy and the Power Budget

The single biggest lever on battery life is how often you sample. Three strategies:

4.1 Fixed periodic sampling

Simplest: sample every T seconds, advertise every reading.

Average current ≈ I_radio_adv × duty_adv + I_sensor_avg × (t_sample / T)

For T = 60 s, t_sample = 5 ms, I_sensor_avg = 200 µA: sensor contribution = 200 µA × 5ms/60s = 0.017 µA — negligible. The radio (e.g. 1 µA sleep, 15 mA for 3 ms every 1 s) dominates at ~45 µA. So at 1/min sampling, the sensor is free; push to 1/s and sensor cost rises to ~1 µA — still small but no longer negligible.

4.2 Adaptive / on-demand sampling

Sample slow (e.g. every 5 min) for the identity frame, but let the accelerometer’s interrupt wake the MCU on motion. The accel in wake-on-motion mode draws ~1-4 µA continuously but eliminates radio activity until something happens. For asset tracking where motion is rare, this cuts average current by 10-100×.

4.3 Threshold-triggered burst

The beacon sits silent (deep sleep, <1 µA) until a value crosses a limit — freezer above 0 °C, vibration above 2 g, door opened. On trigger it:

1. Wakes fully

2. Captures a burst of N samples at high rate (to characterize the event)

3. Advertises an alert frame with the peak value + timestamp

4. Returns to deep sleep

This is the edge intelligence pattern: the beacon decides *whether* to speak, not just *what* to say. Average current collapses to the sleep floor plus rare burst energy.

4.4 Power budget worked example

Coin cell CR2032 = 225 mAh = 810 C. Target life 2 years = 17.5 k hours.

Component Current Duty Average
nRF52 sleep 0.6 µA 99.9% 0.6 µA
Radio adv (3 ms @ 15 mA, 1/2 s) 15 mA 0.6% 90 µA*
Sensor sampling (5 ms @ 200 µA, 1/min) 200 µA 0.0008% 0.017 µA
Accel wake-on-motion 2 µA 100% 2 µA
Total (periodic) ~92.6 µA
Total (threshold, silent 99%) ~2.6 µA

*The radio dominates periodic mode. Switching to threshold-triggered drops total current 35×, extending life from ~2.5 years to decades (cell self-discharge becomes the limit).

5. On-Device Filtering and Trigger Logic

Sending every raw reading wastes bandwidth and battery. The beacon should filter:

  • Deadband: only advertise if |value − last_sent| > Δ (e.g. 0.3 °C). Suppresses noise-driven chatter.
  • Moving average: average 4-8 samples to kill single-sample spikes before comparing to deadband.
  • Rate-of-change: trigger if d(value)/dt exceeds a slope (e.g. temp dropping 5 °C/min = failing compressor).
  • Hysteresis: use separate enter/exit thresholds (e.g. alert at >0 °C, clear at <−0.5 °C) to avoid alert flapping at the boundary.

A minimal state machine:

state: IDLE

on timer tick:

v = read_sensor()

v_f = lowpass(v)

if |v_f - last_sent| > deadband:

advertise(v_f); last_sent = v_f

if v_f > high_thr and state == IDLE:

state = ALERT; advertise_alert(v_f, reason=HIGH)

if state == ALERT and v_f < low_thr:

state = IDLE; advertise_clear()

This logic runs in <1 ms on the nRF52 and costs negligible current versus the radio.

6. Real Deployment Patterns

6.1 Cold chain monitoring

A temp+humidity beacon in a vaccine cooler. Sample every 5 min, advertise on deadband (0.2 °C) or threshold (>8 °C alert, <-0.5 °C clear with hysteresis). The gateway logs the time series; a breach triggers a push notification. Battery: CR2477 (1000 mAh) lasting 3+ years at 5-min sampling.

6.2 Predictive maintenance vibration

An accel beacon bolted to a motor. In wake-on-motion, it captures 1 kHz vibration bursts only when the motor runs. RMS acceleration over a window indicates bearing wear. Comparing week-over-week RMS trends (computed at the gateway) predicts failure before breakdown. Power: the accel’s 2 µA idle dominates; a CR2032 lasts 1-2 years.

6.3 Smart building occupancy

A light+PIR (or mmWave) beacon in each room. Light level + passive IR gives presence without cameras. The beacon advertises occupancy state changes only (enter/leave), not continuous lux. Average current dominated by the PIR’s ~5 µA quiescent — a AA pack lasts years.

7. Gateway-Side Considerations

The gateway must understand the custom MSD frame. Practical points:

  • Scan all 3 channels: sensor frames alternate with identity frames; catching both needs multi-channel dwell of ≥2-3 advertising intervals.
  • Parse the bitmap: decode only the sensors present; ignore unknown frame types gracefully.
  • Handle sequence numbers: detect dropped frames (gap in seq) to flag unreliable links.
  • Time-series store: write to InfluxDB/TimescaleDB; the beacon itself keeps no history.
  • Calibration offset: apply per-device calibration constants server-side (each sensor has a bias).

8. Pitfalls

  • I2C bus lockup: a sensor that misses a clock can hold SDA low and freeze the bus. Add a recovery sequence (toggle SCL 9×, send STOP) on every wake.
  • Cold-start offset: TMP117 needs 15.5 ms average conversion; sampling too fast returns stale data. Respect t_conv.
  • Battery voltage as temperature proxy: many beacons report V_batt, but under load the voltage sags — measure battery only after a rest period for accuracy.
  • RH condensation: HDC2080 reads 100 % RH if condensation forms; the gateway should flag sustained 100 % RH as a fault, not a valid reading.
  • Advertising collision: adding a sensor frame doubles airtime; at high beacon density this raises collision probability (see ad collision article). Keep the sensor frame short and on a separate advertising interval if possible.

9. Design Checklist

  • [ ] Pick sensors whose current fits the cell (avoid 18 mA CO2 on coin cell)
  • [ ] Use a secondary advertising frame; keep the identity frame for location
  • [ ] Pack with fixed-point + bitmap; delta-encode slow drift
  • [ ] Set deadband + hysteresis to suppress chatter
  • [ ] Prefer threshold/wake-on-motion over fixed fast sampling
  • [ ] Add I2C bus recovery on every wake
  • [ ] Document the MSD layout so the gateway can parse it
  • [ ] Verify battery model against measured sleep current, not datasheet typ

10. Conclusion

A sensor beacon is an edge device, not just a transmitter. The engineering value is in the decisions made on-device: when to sample, when to stay silent, and what minimal bytes to send. With fixed-point packing, a bitmap-driven payload, deadband filtering, and threshold-triggered bursts, a coin-cell Beacon can report environmental condition for years while speaking only when it matters.

The radio was never the bottleneck — the sensor current and the sampling cadence are. Design the wake logic first; the advertising encoder is the easy part.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *