HerdTag

Source: docs/firmware.md

Firmware

The full guide is in firmware/README.md. This page summarises it.

Layout

Path What
firmware/core/ Portable C99 port of the controller, geometry and protocol (ht_core.h/.c). No malloc, fixed buffers
firmware/core/test/ Golden-vector test. vectors.h is generated from Python
firmware/tag/ Arduino sketch for the RAK4631 (tag.ino), pin map (pins.h), GNSS interface (gnss_hal.h plus the RAK12500 implementation), secrets.example.h, and copies of the core

Build and test on a laptop

cd ~/herdtag
make -C firmware/core test      # float + double builds; fails if tag/ copies of the core are stale
make -C firmware/core vectors   # regenerate test/vectors.h (automatic when the Python sources change)
make -C firmware/core sync      # copy core into the sketch after editing it

Expected output ends with 3630 checks, 0 failures.

Golden-vector workflow

Python (src/herdtag/controller.py, geo.py, protocol.py) is the specification.

  1. Change the behaviour in Python, and update the Python tests (uv run pytest).
  2. Regenerate the vectors. scripts/gen_vectors.py runs 11 scenarios through the Python controller and records every decision: approach, walk-away, degraded fix, breach/return, breach through a degraded fix, both caps, sampling, motion gate, fence swap, and a 400-step noisy walk. It also records uplink bytes and fence fragments.
  3. Change firmware/core/ht_core.c until make -C firmware/core test passes.
  4. make -C firmware/core sync to update the sketch's copies.

Intentional differences from Python are bounded buffers, double time with float geometry, integer-first lat/lon conversion, and events as bit flags. They're listed in the firmware README.

Flashing a tag

The sketch has never been compiled for the board or flashed. Expect library-version fixes during the first bring-up session.

  1. In the Arduino IDE, add the RAKwireless board index and install RAKwireless nRF Boards, then select WisBlock RAK4631.
  2. Install the libraries SX126x-Arduino, SparkFun u-blox GNSS v2 and SparkFun LIS3DH.
  3. cp firmware/tag/secrets.example.h firmware/tag/secrets.h and fill in DevEUI, JoinEUI and AppKey from The Things Stack. secrets.h is gitignored.
  4. Upload tag.ino, open Serial at 115200, and check the I2C scan shows 0x42 (GNSS) plus 0x18 or 0x19 (accelerometer). Then expect joined and one line per fix.

The pin map in pins.h comes from hardware/BUILD.md §3.

What the tag does

Known gaps: