Project Details

Design Goals:

AimTracer was designed around a few practical requirements:

The device deliberately evaluates the shooting process rather than predicting the hit. Target alignment, sight picture and the exact aiming point remain outside the scope of an IMU-only system.

Hardware

The complete sensor unit is built around a single Seeed Studio XIAO nRF52840 Sense:

Additionally:

No external sensor board, microphone module or additional signal wiring is required.

The current mounting profile places the XIAO with its component and sensor side facing down, PCB underside facing up and USB-C connector pointing toward the shooter. The mount must be rigid: movement between the sensor and pistol would appear as movement in the measurement.

Sensor Configuration

The firmware uses the following acquisition settings:

At startup, the device collects 256 stationary gyroscope samples and calculates the zero-rate bias for all three axes. A new calibration can also be requested from the app. The device must remain motionless during this process.

Shot Detection

AimTracer combines acoustic and motion information instead of relying on one sensor alone.

The firmware continuously monitors:

Three detection modes are available:

The combined mode is the default. It helps reject conversations and shots from neighbouring lanes while also avoiding triggers caused by ordinary pistol movement.

Current default values are:

These values are starting points. They can be changed from either app and sent to the running firmware over Bluetooth. Live fire and dry fire may require different threshold settings.

A manual test trigger is included for calibration, debugging and checking the complete capture pipeline without relying on automatic detection.

Ring Buffer and Shot Capture

Sensor acquisition runs continuously while the device is armed.

A circular buffer always retains the latest movement data. When a trigger is detected, AimTracer preserves the movement before the trigger and continues recording afterward.

Default capture window:

Detection remains active at 416 Hz. For transfer and storage, every fourth IMU sample is retained, producing a 104 Hz shot trace. A standard capture therefore contains approximately 78 samples instead of roughly 312.

Every stored sample contains:

Two independent shot slots allow one shot to be transferred while the next capture is prepared. Additional triggers are counted as dropped if both slots are occupied.

Bluetooth Protocol

AimTracer uses a custom, versioned Bluetooth Low Energy GATT protocol.

Current versions:

The custom service contains separate characteristics for:

A standard BLE Battery Service is advertised alongside the custom service.

Every custom protocol packet is exactly 20 bytes long, allowing operation with the minimum commonly available ATT payload. All multibyte values use little-endian encoding.

Live sensor values use BLE notifications. Complete shot data uses confirmed ATT indications so that the firmware does not send the next packet until the phone has acknowledged the current one.

A shot transfer consists of:

  1. Metadata packet
  2. One packet for every sample
  3. End packet

Transfers include:

The apps reject transfers with missing samples, incorrect IDs, unexpected packet counts or invalid checksums instead of silently storing incomplete shots.

Device Control

The apps can send commands to:

The device also publishes diagnostic information such as:

Battery and Charging

The attached single-cell LiPo is charged through the XIAO’s USB-C connector and onboard BQ25101 charger.

The firmware selects the conservative 50 mA charging mode. A 500 mAh battery therefore needs roughly ten hours plus the slower final charging phase when charged from empty.

Once per second, AimTracer reports:

Charging is only shown when both USB voltage and the charger’s active-low status output confirm an active charging cycle. If USB is connected but no active charge cycle is detected, the app displays “USB connected” instead.

The percentage is estimated from LiPo voltage and is intentionally treated as approximate. A firmware calibration factor is provided for comparison with a multimeter.

iPhone App

The iPhone app is written natively in Swift and SwiftUI and uses Core Bluetooth.

Requirements and features:

Background BLE operation is intentionally disabled in the MVP. The app should remain in the foreground during an active session.

Android App

The Android version is written in Kotlin with Jetpack Compose and the native Android BLE API.

Requirements and features:

Both apps decode the same protocol and apply equivalent motion-analysis calculations.

Motion Trace

The visible path is calculated by integrating gyroscope angular velocity over the short shot window.

For the fixed enclosure orientation:

The trace is re-centred so that the trigger sample is located at (0, 0).

This means:

Large movement on the graph does not automatically mean a poor hit, and a small trace does not guarantee a high score. Sight alignment and the location of the complete trace relative to the target remain unknown.

Motion Metrics

AimTracer currently calculates three values from the three-dimensional gyroscope magnitude:

RMS = sqrt(mean(gx² + gy² + gz²))

The result is expressed as angular velocity in degrees per second. Lower values indicate less angular movement within the evaluated window.

Hold Stability

The hold window begins with the captured pre-trigger data and ends approximately 167 ms before trigger detection.

It measures general pistol stability before the immediate release phase.

Trigger Behaviour

The trigger window covers approximately:

This window is intended to respond to movement associated with releasing the shot.

Follow-Through

The follow-through window covers the first 250 ms after the trigger.

It indicates whether the pistol remains stable or is moved immediately after the shot.

These metrics are engineering measurements, not validated sports-science scores. Their main purpose is to reveal patterns and compare repeated executions by the same shooter.

Ranking System

Shots are ranked separately for hold, trigger behaviour and follow-through.

For each metric:

The overall comparison index is currently calculated with equal weighting:

(hold score + trigger score + follow-through score) / 3

This index is relative to the shots inside the current session. A score of 90 in one session is not automatically equivalent to 90 in another session.

False detections can be deleted from the session so they do not distort averages and rankings.

Session Analysis

Supported training programs:

A completed session provides: