Skip to content

Nicla Sense ME: raw registers (firmware rev 6), viewer-side math, persistent calibration - #152

Open
VBMart wants to merge 3 commits into
norma-core:devfrom
VBMart:feat/nicla-raw-registers
Open

VBMart wants to merge 3 commits into
norma-core:devfrom
VBMart:feat/nicla-raw-registers

Conversation

@VBMart

@VBMart VBMart commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Why

The firmware computed euler, gravity and linear acceleration on the board with a
frame convention that turned out wrong for the mounted board (#151 had to undo it),
and scaled sensor counts with hard-coded ranges. Recorded data could not be
reinterpreted. The magnetometer also started uncalibrated on every power cycle.

Firmware (rev 6, 124-byte map, no rev-5 compatibility)

  • Publishes only measured data plus interpretation metadata: raw int16
    accel/gyro/mag counts with the full-scale ranges read back from the hub
    (accel ±16 g, gyro ±2000 dps), quaternion + accuracy, raw environment, BSEC,
    counters, per-sensor fresh-sample flags. No derived values, no validity bits.
  • Calibration persistence: the hub's accel/gyro/mag BSX profiles are stored in
    nRF52 flash (KVStore), restored before the sensors start, and auto-saved after
    30 s of heading accuracy under 0.6 rad (max once per 10 min). Status in 0x69/0x6A.

Driver

  • Accepts the 124-byte frame only. Deploy station and firmware together:
    a rev-5 board connects but yields no data until reflashed.

Viewer

  • One rev-6 decoder and a new attitude.ts own all derived math: scaling,
    gravity, linear acceleration, REP-103 roll/pitch/yaw via the hub→rover mount,
    compass heading (matches the hardware-calibrated heading from Correct rover compass and motion vector axes #151, regression-tested).
  • Rover HUD shows the hub's heading-error estimate as ±N° and
    NO HEADING · CALIBRATING while the magnetometer is uncalibrated.
  • History panel shows raw counts, ranges, computed attitude and calibration-store state.

VBMart and others added 3 commits September 18, 2026 06:11
…sistent calibration

Firmware revision 6 publishes only what the BHI260AP measured plus the
metadata needed to interpret it later: raw int16 accel/gyro/mag counts with
the full-scale ranges read back from the hub (accel ±16 g, gyro ±2000 dps,
mag 16 LSB/µT), the rotation vector with its accuracy, raw environment values,
the BSEC outputs, counters and per-sensor fresh-sample flags. The euler,
gravity and linear-acceleration registers and the on-device validity bits are
gone; the 124-byte map replaces the 168-byte one and there is no rev-5
compatibility in the driver or the viewer.

Station viewer: a revision-6 decoder and a new attitude module own all
derived math (unit scaling, gravity, linear acceleration, REP-103
roll/pitch/yaw via the hub→rover mount rotation, compass heading). The rover
HUD, the Nicla widget and the history panel all use it; the HUD compass
matches the hardware-calibrated heading from norma-core#151 and now shows the hub's
heading-error estimate as ±N°, or "NO HEADING · CALIBRATING" while the
magnetometer is uncalibrated.

Calibration persistence: the firmware stores the hub's accel/gyro/mag BSX
profiles in nRF52 flash (Mbed KVStore) and restores them before the sensors
are enabled, saving automatically after 30 s of heading accuracy under
0.6 rad, at most every 10 minutes. Status is in registers 0x69/0x6A. The
module reaches the library's private hub handle through an
explicit-instantiation accessor and drains stale status-FIFO entries, which
the stock Arduino_BHY2 parameter read does not (that also caused the bogus
range read-back; ranges are now refreshed every second).

Bench-verified on the Nicla: 100 Hz, 0 discarded frames, ranges 16/2000,
|a| = 1.004 g at rest, save fires 30 s after calibration, restore is
byte-identical with offsets active from the first frame, accuracy confirmed
by the first small motion after a warm start.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Viewer:
- Compass accuracy tiers follow the hub's quantized levels (green < 35°,
  amber < 70°, red above); a calibrated magnetometer at 30° no longer
  renders as "poor".
- RoverMotion carries an explicit headingUncalibrated flag so a vertical
  forward axis is not labelled CALIBRATING.
- ME_STATUS and ME_HEADING_UNCALIBRATED_RAD are shared from values.ts
  instead of being duplicated in rover-motion.ts and the history panel.
- History panel guards the accuracy row against non-finite values and no
  longer tells users to reflash for an old recording.
- Live view uses the shared layout constants for its unsupported-image
  message.

Firmware:
- readBsxState rejects a BSX block whose length byte exceeds the 64-byte
  block, instead of over-reading the stack buffer.
- README: trimmed bench notes, restored the rationale for sending
  STREAM_STOP on open.

Driver README: calibration is now persisted; describe how the rover HUD
uses the accuracy register.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The live widget shows the rotation-vector accuracy as ±N° under the
heading, tiered green/amber/red like the rover HUD, and reads
"calibrating" instead of a meaningless bearing while the magnetometer
is uncalibrated.

headingAccuracy() in values.ts is the single interpretation of the
register (degrees, tier, uncalibrated flag); the rover motion reader
and HUD use it too so the thresholds cannot drift apart.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant