Building a Shake-to-Stream Motion Sensor Device

I wanted to create a device that could be activated by shaking it and then stream motion data efficiently to a smartphone. The goal was to make something useful for motion tracking applications while keeping power consumption reasonable and data transmission efficient.

The Hardware Choice

I went with the Seeed Studio Xiao nRF52840 Sense because it combines the Nordic nRF52840 Bluetooth SoC with an onboard LSM6DSL 6-axis IMU sensor. This gave me everything I needed in a tiny package - Bluetooth connectivity, motion sensing, and enough processing power to handle the data efficiently.

The Core Challenge: Efficient Data Streaming

The main technical challenge was streaming high-frequency motion data over Bluetooth efficiently. I needed to balance several competing requirements:

  • High enough sampling rates to capture meaningful motion (up to 416Hz from the LSM6DSL)

  • Efficient use of Bluetooth bandwidth

  • Reasonable power consumption

  • Configurable parameters for different use cases

Data Batching Implementation

Instead of sending individual sensor readings, I implemented a batching system that groups multiple samples together before transmission. The device collects up to 18 samples (each containing 6-axis data: 3-axis accelerometer + 3-axis gyroscope) into a single packet.

The batching logic works on two triggers:

  1. Count-based: Send when the batch reaches 18 samples

  2. Time-based: Send after 500ms timeout, even with fewer samples

I used a binary format to maximize efficiency - each sample is packed into just 12 bytes using 16-bit integers with appropriate scaling factors. This gives me good resolution while keeping packet sizes manageable for Bluetooth's MTU limitations.

Motion-Based Adaptive Sampling

To improve power efficiency, I implemented adaptive sampling rates based on motion detection. The device runs at two different frequencies:

  • Idle mode: 12Hz when no motion is detected

  • Active mode: 52Hz when motion is ongoing

The motion detection uses variance analysis across a sliding window of accelerometer samples. When the variance exceeds a threshold (configurable, default 0.5G), the device switches to active mode. It stays in active mode for a timeout period (default 1 second) after the last detected motion.

This approach significantly reduces power consumption during idle periods while ensuring high-quality data capture during actual motion events.

Shake Detection for Device Activation

The shake detection works by calculating the sum of absolute differences between consecutive accelerometer readings across all three axes. When this sum exceeds a threshold (default 20G total change), it triggers a shake event.

I use shake detection to automatically start Bluetooth advertising when the device is disconnected. This creates an intuitive user experience - shake the device to make it discoverable again.

Bluetooth Range Issues and Power Boost

During testing, I encountered range limitations that made the device impractical for some use cases. The solution was to increase the Bluetooth transmit power to +8dBm (the maximum supported by the nRF52840) and use Coded PHY S=8 mode.

Coded PHY S=8 trades data rate for range - it runs at 125 kbps instead of the standard 1 Mbps, but provides significantly better range and reliability. The device automatically requests this mode when connecting to ensure maximum range performance.

Configuration Management

I wanted the device to be configurable without reflashing firmware, so I implemented a comprehensive configuration system accessible via Bluetooth commands. Users can adjust:

  • Motion detection thresholds and timeouts

  • Sampling rates for both idle and active modes

  • Shake detection sensitivity

  • Advertising timeouts

  • Data transmission settings

All configuration changes are stored in non-volatile storage and persist across power cycles.

Interrupt-Driven Architecture

The IMU sensor supports data-ready interrupts, which I use to minimize CPU usage and improve timing accuracy. When new sensor data is available, the LSM6DSL triggers an interrupt that immediately reads the data and queues it for processing.

This approach is much more efficient than polling and ensures I don't miss samples even at higher sampling rates.

Results

The final implementation successfully meets the original goals:

  • Shake-to-activate functionality works reliably

  • Motion data streams at up to 52Hz during active periods

  • Data batching reduces Bluetooth overhead significantly

  • Adaptive sampling provides good power efficiency

  • Extended range through higher transmit power and Coded PHY

  • Fully configurable via Bluetooth commands

The device has proven useful for motion tracking applications where you need responsive activation, efficient data collection, and reasonable battery life. The configurable nature means it can be adapted to different use cases without firmware changes.

The most satisfying aspect was solving the efficiency puzzle - balancing sample rates, batch sizes, transmission timing, and power management to create something that actually works well in practice rather than just meeting the basic requirements.