Why Motion Sensing Belongs on Every Asset Tag

Most BLE tag deployments track location, but location alone doesn’t tell you whether a pallet was dropped, a crate tipped over, or a high-value instrument sat vibrating on a truck bed for six hours. Adding an accelerometer to a tag transforms it from a passive beacon into an active sensor node—one that can detect impact events, classify motion patterns, and wake the MCU only when something actually happens.

The engineering challenge isn’t picking an accelerometer IC (that’s a spreadsheet exercise). It’s designing the interrupt chain, impact threshold logic, power budget, and false-positive filter so the tag reports real events without draining its battery or flooding your gateway with noise.

This article walks through the full signal path: from silicon selection through detection algorithms, interrupt architecture, data encoding, and calibration—with real numbers at every step.

Accelerometer IC Selection: What Actually Matters

Low-power asset tags don’t need 16-bit 20 kHz IMUs. They need 8–12-bit accelerometers that sleep at <1 µA and wake on programmable thresholds. Here's the field narrowed to the ICs that matter:

Parameter ST LIS2DH12 ADI ADXL362 Bosch BMI270 TDK ICM-42670-P
Resolution 8/10/12-bit 12-bit 16-bit 16-bit
Range (g) ±2/4/8/16 ±2/4/8 ±2/4/8/16 ±2/4/8/16
Current (active) 5–11 µA 0.2 µA (motion) 4.8 µA 6.6 µA
Current (sleep) 0.5 µA 10 nA 3 µA 2 µA
Built-in activity detect Yes (INT1/INT2) Yes (awake/inact) Yes (any-motion) Yes (wake-on-motion)
Interface SPI / I²C SPI SPI / I²C SPI / I²C
Package LGA 2×2×1 LGA 3×3×1.05 LGA 2.5×3×0.83 LGA 2.5×3×0.76
Price (1K) $0.58 $3.85 $1.20 $1.55

For asset tags, ST LIS2DH12 is the pragmatic default: programmable 8/10/12-bit modes, two interrupt pins, built-in click/double-click detection, and 0.5 µA standby. At $0.58 in quantity it barely affects the BOM. The ADXL362’s 10 nA sleep is impressive, but its SPI-only interface and $3.85 price tag make it a niche choice for ultra-low-power designs where the MCU itself sleeps at sub-µA and you can’t tolerate even 0.5 µA from the accelerometer.

Key selection criteria that most datasheets don’t emphasize:

  • Threshold granularity: LIS2DH12 activity threshold is 1 LSB = 16 mg at ±2 g / 12-bit. ADXL362 is 3.9 mg/LSB. For impact detection at 1–2 g, both are sufficient.
  • Interrupt latency: Built-in activity detection fires in 1–3 sample periods. If you sample at 1 Hz for inactivity, that’s 1–3 seconds—not fast enough for impact. You need a separate high-rate path.
  • FIFO depth: LIS2DH12 has a 32-sample FIFO. BMI270 has a 128-sample FIFO. Larger FIFOs let the MCU burst-read impact waveforms without keeping SPI active during the event.

Motion Detection Modes and What They’re Good For

BLE tag firmware typically runs three detection modes simultaneously on different threshold axes:

1. Activity / Inactivity (Presence Detection)

Purpose: Detect whether the tagged asset is stationary or in transit. This drives mode-switching—advertising interval drops from 1000 ms to 100 ms when the asset is moving.

Configuration (LIS2DH12):

  • Activity threshold: 0.5 g (32 mg/LSB × 16 = ~512 mg)
  • Activity duration: 1 sample at 1 Hz (immediate trigger)
  • Inactivity threshold: 0.08 g
  • Inactivity duration: 30 samples at 1 Hz (30 seconds of stillness)

Power impact: The accelerometer runs at 1 Hz (5 µA) while the MCU sleeps. When activity fires, the MCU wakes and switches the BLE radio to fast advertising.

2. Free-Fall Detection

Purpose: Detect drops—pallets lifted by crane and released, instruments knocked off benches.

The signature is all three axes near zero simultaneously. LIS2DH12 free-fall threshold: set activity to ≤0.2 g on all axes, duration ≥2 samples at 200 Hz (10 ms). At 200 Hz the accelerometer draws ~11 µA—acceptable only if you keep free-fall detection active during known handling windows.

Practical complication: A tag mounted on a box corner experiences 0.6 g resting gravity on one axis during normal orientation. When the box tips, that axis shifts but doesn’t go to zero. Free-fall only works for objects that truly become airborne. For most logistics scenarios, impact detection (next section) is more reliable.

3. Single / Double Click (Tap Detection)

Purpose: User interaction—double-tap to confirm asset handoff, single-tap to request a location ping.

LIS2DH12 built-in click detection handles this without firmware involvement:

  • Click threshold: 1.2 g (higher than activity to avoid false triggers from truck vibration)
  • Click time limit: 80 ms (window for a tap)
  • Double-click latency: 400 ms (time between first and second tap)
  • Interrupt on INT1 for single click, INT2 for double click

This mode runs at 400 Hz (~11 µA) only during a configurable time window (e.g., first 30 seconds after a button press or gateway proximity event). Otherwise the accelerometer stays at 1 Hz.

Impact Detection: The Real Engineering Problem

Impact events are the hardest to detect reliably because they share spectral characteristics with vibration, door slams, and forklift bumps. The signal processing is simple—exceed a threshold—but the threshold selection and confirmation logic are not.

Threshold Selection by Application

Scenario Typical Peak (g) Recommended Threshold Detection Window
Package drop (30 cm, hard floor) 15–30 8 g 5 ms
Pallet bump (forklift) 3–6 2.5 g 50 ms
Truck vibration (road) 0.5–1.5 1.5 g (with confirmation) 100 ms
Instrument shelf tip-over 2–4 2 g 20 ms
Laptop bag drop 10–20 6 g 10 ms

The key insight: threshold alone is insufficient. A forklift bump at 4 g looks like a package drop to a simple threshold detector. You need confirmation criteria:

  • Duration confirmation: Impact events shorter than the detection window are ignored. A 4 g peak lasting 2 ms is vibration; a 4 g peak lasting 40 ms is a bump.
  • Axis correlation: Real impacts produce correlated spikes on multiple axes. Random vibration typically peaks on one axis (the one aligned with the vibration direction). Compute mag = sqrt(x² + y² + z²) and require mag > threshold instead of testing per-axis.
  • Pre/post-quiet window: Before and after the event, require mag < 0.5 × threshold for at least 2 sample periods. This eliminates vibration trains where multiple peaks cross the threshold in quick succession.

Impact Detection Firmware Flow

State: ACCEL_IDLE (1 Hz, MCU sleeping)
  INT fires → ACCEL_ACTIVE
    → Switch to 200 Hz
    → Read FIFO for 50 ms (10 samples)
    → Compute magnitude per sample
    → If max_mag > IMPACT_THRESH:
        → Check duration (samples above threshold)
        → Check quiet window before/after
        → If confirmed:
            → Record peak magnitude, duration, axis distribution
            → Wake BLE, send impact event packet
            → Return to ACCEL_IDLE after 5 s
        → Else: false positive, return to ACCEL_IDLE
    → Else: activity trigger, resume fast advertising

The 200 Hz burst lasts only 50 ms. Current during burst: accelerometer 11 µA + MCU active 3 mA × 50 ms = 0.15 mAs per event. Even at 100 events/day, that's 15 mAs/day—negligible compared to BLE advertising.

Interrupt-Driven Architecture: The Power Budget Backbone

The tag's power budget is determined by how long the MCU and radio stay asleep. Interrupt-driven design means the accelerometer acts as a hardware watchdog:

Interrupt Routing (LIS2DH12)

INT Pin Function MCU Action Accel Rate
INT1 Activity / Click / Free-fall Wake MCU, read status 1 Hz (default) → 400 Hz (click window)
INT2 Inactivity / FIFO watermark None (inactivity) or burst-read (FIFO) 1 Hz

The MCU (e.g., nRF52832) sleeps at 1.2 µA (System OFF with RAM retention) or 0.6 µA (System OFF without retention). The LIS2DH12 draws 5 µA at 1 Hz. Total standby: ~6 µA.

Event-Triggered Power States

State Duration Current Energy (µC/event)
Deep sleep Continuous 6 µA
Activity INT → MCU wake + status read 5 ms 3 mA 15
Impact detection burst 50 ms 3 mA + 11 µA ~151
BLE advertising (fast, 100 ms interval) 5 s 8.5 mA avg 42,500
BLE advertising (slow, 1000 ms interval) Continuous ~12 µA avg

On a CR2032 (220 mAh, 2.9–3.0 V usable):

  • Slow advertising only (1000 ms): ~2.4 years
  • Motion-triggered fast advertising (100 events/day, 5 s each): ~2.1 years
  • Impact detection + reporting (20 impacts/day): ~2.0 years

The motion sensing overhead is under 5% of total battery life. The BLE radio is still the dominant consumer.

Data Encoding: Packing Impact Data into Advertising Packets

A BLE tag that detects an impact needs to report: event type, peak magnitude, duration, and optionally axis distribution. Standard BLE advertising packets have 31 bytes of usable payload (after flags and length headers). Here's how to encode impact events efficiently:

Custom Manufacturer-Specific Data Format

Byte 0-1: Company ID (0xFFFF for testing, register for production)
Byte 2:   Data type flag
          0x01 = Motion status (activity/inactivity)
          0x02 = Impact event
          0x03 = Free-fall event
Byte 3:   Event sub-type / severity
          Impact: 0x01=minor (2-4g), 0x02=moderate (4-8g), 0x03=severe (>8g)
Byte 4-5: Peak magnitude (0.01 g units, uint16)
          Example: 4.56 g → 0x01C8 (456)
Byte 6-7: Event duration (0.5 ms units, uint16)
          Example: 38 ms → 0x004C (76)
Byte 8:   Axis distribution bitmap
          Bit 0: X-axis dominant
          Bit 1: Y-axis dominant
          Bit 2: Z-axis dominant
          Bit 3: Multi-axis (correlated)
          Bit 4-7: reserved
Byte 9:   Temperature at event (°C, signed, 0.5°C resolution)
Byte 10:  Battery level (0-100%)

11 bytes total for a full impact report. With 2-byte flags and 2-byte length header, that's 15 bytes—well within the 31-byte limit. The remaining space can carry the standard UUID/major/minor for location context.

Multi-Event Buffering

If impacts happen in bursts (e.g., a pallet being loaded), the tag buffers up to 8 events in RAM and rotates them through successive advertising packets. Each packet carries one event; the BLE radio cycles through the buffer at 100 ms intervals for 5 seconds after the last event.

False Positive Reduction: The Difference Between Useful and Useless

Every deployment engineer has seen the same problem: a tag mounted on a warehouse doorframe reports 300 "impacts" per day because the door vibrates when trucks pass. Here's a layered filter stack:

Layer 1: Magnitude + Duration Gate

As described above: require mag > threshold AND duration > min_window. This eliminates 80% of false positives from vibration peaks that cross the threshold but don't sustain.

Layer 2: Axis Correlation

Compute the ratio r = min(x, y, z) / max(x, y, z) at the peak. Real impacts produce r > 0.3 (energy distributed across axes). Directional vibration produces r < 0.15 (one dominant axis). Apply this filter only for thresholds below 4 g—above 4 g, any peak is almost certainly real.

Layer 3: Temporal Debounce

After a confirmed impact, suppress further detections for a configurable cooldown period (default: 60 seconds). This prevents one physical impact from generating 5 reports as the object bounces. Adjust cooldown by application:

  • Delicate instruments: 5 seconds (catch each bounce)
  • Industrial pallets: 120 seconds (one report per handling event)

Layer 4: Context Gate

Only enable impact detection when context conditions are met:

  • Tag is in transit (activity detection = moving)
  • Tag is near a loading zone (gateway RSSI > -60 dBm)
  • Time window (impact detection only during business hours)

Layer 4 is application-specific but powerful. A tag on a stationary shelf doesn't need impact detection at all—disable it and save the 200 Hz burst overhead.

False Positive Rate Comparison

Filter Stack True Positive Rate False Positive Rate (warehouse env)
Threshold only 95% 30/day
+ Duration gate 93% 8/day
+ Axis correlation 90% 2/day
+ Temporal debounce 88% 0.5/day
+ Context gate 85% <0.1/day

The 10% true positive loss from the full stack comes mainly from the debounce filter missing rapid successive impacts (object bouncing). If your application needs every bounce, reduce debounce to 5 s and accept ~1 false positive/day.

Calibration: Making Thresholds Match Reality

Datasheet thresholds are theoretical. Every real tag needs per-unit calibration because:

  • Zero-g offset: LIS2DH12 spec allows ±40 mg per axis after PCB mount. On a CR2032-powered tag with the battery directly above the accelerometer, solder reflow and PCB flex can shift offsets to ±80 mg.
  • Sensitivity error: ±1.5% at ±2 g range. At a 4 g impact threshold, that's ±60 mg of uncertainty—not critical, but it affects severity classification accuracy.
  • Cross-axis sensitivity: Up to 1% (axis X responding to axis Y input). For magnitude-based detection, this is negligible. For per-axis analysis, it matters.

Two-Point Calibration Procedure

On the production line, calibrate each tag in two orientations:

  1. Level position (tag flat on granite plate): Read all three axes. Expected: X=0, Y=0, Z=+1 g (or −1 g depending on orientation). Compute offsets: offset_x = x_measured − 0, offset_y = y_measured − 0, offset_z = z_measured − 1.0.
  2. Inverted position (tag flipped): Read Z axis again. Expected: Z = −1 g. Compute sensitivity: sens_z = (z_level − z_inverted) / 2.0. The ratio 1.0 / sens_z gives the scale correction factor.

Store offsets and scale factors in flash. Runtime firmware applies: x_corrected = (x_raw − offset_x) × scale_factor. This takes 12 bytes of flash (3 offsets + 3 scale factors as float16) and reduces threshold uncertainty from ±80 mg to ±5 mg—enough to distinguish a 2 g bump from a 2.5 g one.

Field Recalibration

Tags in service drift over time (temperature cycling, mechanical stress). Add a self-calibration routine triggered by:

  • Temperature change > 15°C (zero-g offset drifts ~0.5 mg/°C)
  • Extended stationary period (> 30 minutes at inactivity)

During a stationary period, the MCU wakes once, reads 32 samples at 25 Hz, averages them, and updates offsets in flash. This costs ~8 mAs per recalibration event—negligible.

Deployment: Mounting, Orientation, and Environment

Mounting Orientation Matters

The accelerometer reads gravity as a constant 1 g vector. If the tag is mounted vertically on a box face, one axis reads ~1 g at rest. An impact along that axis starts from 1 g, not from 0. This means:

  • Magnitude-based detection (mag = sqrt(x²+y²+z²)) is orientation-independent—total acceleration always includes the gravity component correctly.
  • Per-axis threshold detection is orientation-dependent—you need to subtract the static gravity vector first, or set per-axis thresholds accounting for the resting offset.

Best practice: Always use magnitude-based thresholds. Per-axis data is useful for classification (was the impact vertical or horizontal?) but not for initial detection.

Environmental Vibration Levels

Different environments have vastly different background vibration:

Environment Typical Vibration (g RMS) Freq Range Recommended Impact Threshold
Office / lab 0.01 1–20 Hz 1.5 g
Retail store 0.05 5–50 Hz 2.0 g
Warehouse floor 0.1–0.3 10–100 Hz 2.5 g
Truck in transit 0.3–0.8 5–200 Hz 3.0 g + duration gate
Ship / rail 0.5–1.2 0.5–30 Hz 4.0 g + axis correlation
Construction site 1.0–2.0 2–500 Hz 5.0 g + full filter stack

If you deploy the same tag across environments, make the impact threshold configurable via BLE GATT write. A provisioning app scans the tag, reads the deployment context, and writes the appropriate threshold + filter configuration.

Sampling Rate vs. Detection Latency

Impact detection requires a minimum sample rate to capture the event peak. A 5 ms impact at 200 Hz gives you 1 sample on the peak—barely enough. At 400 Hz you get 2 samples. At 800 Hz you get 4 samples and can measure duration reliably.

The tradeoff: 200 Hz costs 11 µA, 400 Hz costs ~50 µA, 800 Hz costs ~150 µA. Since impact detection is burst-only (50 ms), the energy cost per event scales:

  • 200 Hz burst: 0.55 µC
  • 400 Hz burst: 2.5 µC
  • 800 Hz burst: 7.5 µC

For tags that see <20 impacts/day, even 800 Hz bursts are negligible. But if your tag is in a high-vibration environment where the burst trigger fires 200 times/day, 800 Hz becomes expensive (1500 µC/day = 0.42 mAh/day on a 220 mAh battery = ~1% per day). Stick with 200 Hz and accept slightly less precise duration measurement.

Impact Data Reporting: Gateway Integration

When the tag confirms an impact, it needs to deliver the data to the backend. Two approaches:

Approach 1: Advertising-Packet-Only (No Connection)

The tag embeds impact data in its advertising packet for 5 seconds after the event. Gateways scanning at < 100 ms interval will capture it. Pros: zero connection overhead, sub-second latency. Cons: no acknowledgment—if the gateway misses the packet, the data is lost. For critical assets, add a retransmit counter: broadcast the impact packet 3 times at 20 ms intervals (total 60 ms), then slow down to 100 ms for the remaining 4.9 seconds. This costs ~3 mAs per event but gives 3 chances for the gateway to catch it.

Approach 2: Connection-Based Reporting

The tag connects to the nearest gateway and writes impact data to a GATT characteristic. Pros: guaranteed delivery, can transfer larger data (e.g., full 32-sample waveform). Cons: connection overhead (~30 mAs per connection), 2–5 second latency, and requires the gateway to be connectable.

Hybrid: Send a lightweight impact notification via advertising (Approach 1), and if the backend requests detail, establish a connection for the waveform (Approach 2). This gives instant notification with optional deep data.

Real-World Implementation Checklist

Before deploying motion-sensing tags in production:

  • Validate thresholds on-site: Mount tags on real assets in the actual environment. Record 24 hours of raw data. Set thresholds at 2× the maximum background vibration peak.
  • Test mounting variability: Try 5 different mounting positions. Verify that magnitude-based detection is consistent regardless of orientation.
  • Profile false positive rate: Run for 7 days with detection logging but no reporting. Count false positives. Adjust filter stack until FP rate < 1/day.
  • Measure battery impact: Deploy 10 tags with motion sensing enabled and 10 without. Compare battery voltage after 30 days. Target: < 5% difference.
  • Plan firmware updates: Thresholds and filter parameters should be GATT-writable. Deploy with conservative defaults, then tune remotely based on collected data.
  • Document axis mapping: Record which accelerometer axis maps to which physical direction for each mounting configuration. This determines impact direction classification accuracy.

Motion sensing on BLE tags is not a feature you bolt on—it's a signal-processing pipeline that requires calibration, filtering, and power management from day one. But done correctly, it turns a location beacon into a condition-monitoring sensor with less than 5% battery impact, and that's a tradeoff every asset-tracking engineer should take.