Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/compile-sketch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ jobs:
# SensorEgg POC and the NeoPixel strip exactly as beta.yml does, so
# the flag-on build is compile-checked on the PR rather than first
# failing on the publish workflow. Everything else builds the
# master/release defaults (off).
# project.h defaults — which since 4.1.0 means the NeoPixel strip is
# ON (it is a core feature now; the flag defaults to 1) and only the
# SensorEgg POC is off. So the difference between the two arms is
# now just SensorEgg and the DovesLapTimer ref.
FEATURE_FLAGS: ${{ (github.base_ref == 'BETA' || github.head_ref == 'BETA' || github.ref_name == 'BETA') && '-DBIRDSEYE_ENABLE_SENSOREGG=1 -DBIRDSEYE_ENABLE_NEOPIXEL=1' || '' }}
# Build both XIAO nRF52840 variants. The Sense board has the onboard
# LSM6DS3 IMU; the plain board does not (accelerometer logging degrades
Expand Down
6 changes: 4 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,10 @@ to the matching `*_LOOP()`.
`led_brightness` by day, `led_brightness_night` after dark (see
*Local time* below). The strip's 5 V boost
converter has its EN pin driven low in sleep, so System OFF really
powers the LEDs down. Gated on `BIRDSEYE_ENABLE_NEOPIXEL`: on in
beta, off (fully compiled out, no UICR write) in master/release.
powers the LEDs down. `BIRDSEYE_ENABLE_NEOPIXEL` is on in **every**
channel as of 4.1.0, which is what makes the strip a core feature — at
the price of a one-way, fleet-wide UICR NFC→GPIO conversion on the
first boot after updating.
- **Course creator** (`course_creator` + `track_json` pure units, glued
into the menu/pages/SD modules) — authors a track course on the device
by walking to each cone and holding for a 3 s GPS average. Autocross
Expand Down
6 changes: 4 additions & 2 deletions BirdsEye/BirdsEye.ino
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,10 @@ void setup() {
// beta channel): the one-time UICR NFC->GPIO write needs direct NVMC
// access, which is illegal once the SoftDevice is up. Also before
// wdtSetup() so the one-time self-reset can't race the watchdog. Needs
// SETTINGS_SETUP (led_brightness) — a no-op unless
// BIRDSEYE_ENABLE_NEOPIXEL is set (beta channel only).
// SETTINGS_SETUP (led_brightness). Since 4.1.0 this runs on EVERY
// channel — BIRDSEYE_ENABLE_NEOPIXEL defaults to 1 — so the first boot
// of any 4.1.0+ image is the one that spends the NFC pads and resets
// once. See project.h.
NEOPIXEL_SETUP();

// Camera auto-record: load the persisted Insta360 serial + init the FSM
Expand Down
40 changes: 25 additions & 15 deletions BirdsEye/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@
#ifdef FIRMWARE_VERSION_OVERRIDE
#define FIRMWARE_VERSION _BE_TOSTRING(FIRMWARE_VERSION_OVERRIDE)
#else
// The 4.0.0 release cut (matches the v4.0.0 tag). The webapp still keys
// The 4.1.0 release cut (matches the v4.1.0 tag). The webapp still keys
// the track JSON budget off this — 8 KB at or above 3.2.0 — so never
// stamp a build below that line again.
#define FIRMWARE_VERSION "4.0.0"
#define FIRMWARE_VERSION "4.1.0"
#endif

///////////////////////////////////////////
Expand Down Expand Up @@ -84,21 +84,31 @@

// ---- NeoPixel strip (11 px: 2 status + 9-px pace/RPM strip) ----
//
// 0 (default — master and release): the whole subsystem is compiled out.
// The module's entry points become no-ops and, critically, the firmware
// NEVER writes UICR->NFCPINS and never drives pins 30/31 (P0.09/P0.10,
// the NFC pads) — a flag-off build leaves the pads exactly as it found
// them.
// 1 (default — master, beta and release all ship this as of 4.1.0): the
// strip is a CORE feature, present in every image so a logger works the
// moment someone wires LEDs to it. On first boot NEOPIXEL_SETUP()
// converts the NFC pads to GPIO by programming UICR->NFCPINS and
// self-resets once so the pin latch takes effect. After that: pin 30 =
// boost converter EN, pin 31 = WS2812 data. See plan 0006 and neopixel.h.
//
// 1 (the beta channel passes -DBIRDSEYE_ENABLE_NEOPIXEL=1): on first
// boot NEOPIXEL_SETUP() converts the NFC pads to GPIO by programming
// UICR->NFCPINS (a ONE-WAY change — undoing it needs a full chip erase,
// i.e. a bootloader reflash; accepted, NFC is never used on this
// hardware) and self-resets once so the pin latch takes effect. After
// that: pin 30 = boost converter EN, pin 31 = WS2812 data. See plan
// 0006 and neopixel.h.
// KNOW WHAT THIS COSTS, because it is charged to every unit in the field,
// not just the ones with LEDs on them. The UICR write is ONE-WAY — undoing
// it needs a full chip erase, i.e. a bootloader reflash over USB — so the
// first boot after updating to 4.1.0 permanently spends the NFC pads and
// reboots itself once, on every device, wired for LEDs or not. That was the
// deliberate 4.1.0 decision (NFC is not used on this hardware and the pads
// are otherwise idle); it is recorded here rather than in a commit message
// because nothing about a later build can undo it.
//
// 0 (no shipped channel sets this; -DBIRDSEYE_ENABLE_NEOPIXEL=0 forces it):
// the subsystem is compiled out — no Adafruit_NeoPixel dependency, and on a
// board that has NOT already been converted the firmware never writes UICR
// and never drives pins 30/31. On one that HAS (it ran a flag-on build
// before), the stubs still hold the boost EN pin low, because a floating EN
// leaves the 5 V rail up through System OFF — see the #else block in
// neopixel.ino.
#ifndef BIRDSEYE_ENABLE_NEOPIXEL
#define BIRDSEYE_ENABLE_NEOPIXEL 0
#define BIRDSEYE_ENABLE_NEOPIXEL 1
#endif

///////////////////////////////////////////
Expand Down
6 changes: 3 additions & 3 deletions BirdsEye/settings.ino
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ static void ensureDefaultSettings() {
// starts the rotation at the speed page — end users never see the
// diagnostic counters; "show" restores them for development/tuning.
{ "debug_pages", "hide" },
// NeoPixel strip (plan 0006). Written on every channel so
// SETTINGS.json has a uniform shape (SensorEgg DOVEX-column
// precedent); only a BIRDSEYE_ENABLE_NEOPIXEL build reads them.
// NeoPixel strip (plan 0006). Read on every channel since 4.1.0 —
// BIRDSEYE_ENABLE_NEOPIXEL defaults to 1, so these are live
// settings on a stock logger, not beta-only bookkeeping.
{ "led_brightness", "64" }, // global cap 0-255; 0 = LEDs disabled
{ "rev_limit", "15000" }, // true RPM: LED scale ceiling + rev flasher + OVER REV header
// Plan 0007: the PROBLEM limit (0 = disabled) — whole LED chain
Expand Down
85 changes: 58 additions & 27 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,45 @@ and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2

## [Unreleased]

Slated to release as **4.1.0** (minor — new NeoPixel subsystem on the
beta channel, plus the fixes below).
Nothing yet.

## [4.1.0] - 2026-08-22

MINOR — new settings and device behaviour, all backwards compatible. Track
files, the DOVEX log format, the log filenames and the BLE command protocol
are byte-for-byte unchanged from 4.0.0, so 4.0.0 logs, tracks and companion
apps keep working.

> ### Read this before updating
>
> **This release permanently converts the two NFC pads to GPIO, on every
> device, and reboots once while doing it.**
>
> The LED strip stops being a beta-only experiment in 4.1.0 and ships in the
> normal firmware, so a logger lights up the moment someone wires a strip to
> it — no special build. Making those two pads usable as GPIO means writing
> the chip's UICR, and **that write cannot be undone by any later firmware**;
> reversing it needs a full chip erase and a bootloader reflash over USB.
> Your logger does the write the first time it boots after updating, then
> resets itself once so the change takes effect. That single extra reboot
> during the update is expected — nothing is wrong.
>
> This happens whether or not you have LEDs attached, because the firmware
> cannot know. The trade was made deliberately: this hardware does not use
> NFC for anything, the pads are otherwise idle, and requiring a separate
> build to use a headline feature had kept it out of everyone's hands. If you
> have some future use for the NFC pads on your device, **do not install
> 4.1.0.**
>
> With no strip wired, nothing else changes — the pins simply sit there.

The SensorEgg wireless-EGT proof of concept remains beta-only
(`BIRDSEYE_ENABLE_SENSOREGG`, off in the published images), but it gained
nothing this release — so every entry below is live for every user.

### Added
- **NeoPixel LED strip subsystem** (beta channel only,
`BIRDSEYE_ENABLE_NEOPIXEL`, plan 0006): 11 WS2812 pixels on the NFC
- **NeoPixel LED strip subsystem** (plan 0006) — **now in every build**,
see the upgrade note above: 11 WS2812 pixels on the NFC
pads converted to GPIO — 2 status indicators + a 9-px strip with a
centerline. A global brightness cap (`led_brightness` setting, 0
disables the LEDs entirely) that no LED can ever exceed; a pace pip
Expand All @@ -30,8 +63,7 @@ beta channel, plus the fixes below).
sleep truly powers the LEDs off. **First boot of a flag-on build
performs a one-way NFC-pads-to-GPIO conversion (UICR write) and
resets once.**
- **LED day/night brightness + a device timezone** (beta channel, plan
0010): new `utc_offset_min` setting (minutes east of UTC, default 0)
- **LED day/night brightness + a device timezone** (plan 0010): new `utc_offset_min` setting (minutes east of UTC, default 0)
gives the device a local wall clock, and the LED strip swaps to
`led_brightness_night` (default 16) between `led_night_start_hour`
(19) and `led_day_start_hour` (7) — local hours, so 7am is the
Expand All @@ -41,12 +73,14 @@ beta channel, plus the fixes below).
every filename stay exactly as they were, and timezone presentation
remains the viewing app's job.
- **Overrev alert** (plan 0007): new `overrev_limit` setting (default 0
= disabled) — past it the whole LED chain flashes red until RPM falls
back below the normal `rev_limit`. The rev limit warns the engine is
at its ceiling; the overrev limit says it's broken.
= disabled) — past it the whole LED chain flashes red and the tach
page's `*OVER REV*` header trips, both until RPM falls back below the
normal `rev_limit`. The rev limit warns the engine is at its ceiling;
the overrev limit says it's broken.
- **Temp1 alert threshold setting** (`temp1_alert_c`, default 650 °C):
the right status LED is now a tri-state — flashing red at/above the
limit, off when good, solid blue when there is no probe signal.
the right status LED is now a tri-state — flashing red
at/above the limit, off when good, solid blue when there is no probe
signal.
- **`tach_filter` setting** (default `smooth`, plan 0009): picks the RPM
estimator, so the tach can be A/B'd against a live engine at the track
instead of argued about from a plotted log. `smooth` is the new filter
Expand All @@ -60,9 +94,13 @@ beta channel, plus the fixes below).
thrown away this power-cycle. A count that climbs with RPM is ignition
ringing or missed sparks reaching the ISR, i.e. the pickup rather than
the filter.
- **GPS-search pip**: in race mode without a full GPS lock the strip
shows a green pixel bouncing end-to-end instead of the RPM scale, so
a not-yet-timing session is visibly "searching".
- **GPS-search pip**: in race mode without a full GPS lock the strip shows a green pixel bouncing end-to-end instead of the
RPM scale, so a not-yet-timing session is visibly "searching".
- **The browser-sim harness can fake a GPS fix.** A "GPS fix" toggle (plus
an mph field) streams a deterministic synthetic 25 Hz fix parked on the
bundled OKC track's start line, so fix-gated flows — most usefully the
on-device course creator, including its 3 s point-averaging hold — can be
exercised in the simulator without loading a log file.

### Changed
- **Settings file and JSON document buffers raised 512 -> 1024 bytes**
Expand Down Expand Up @@ -100,16 +138,14 @@ beta channel, plus the fixes below).
a flat ~20 RPM (worst case under 300) from 1500 to 14 000 RPM. The cost
is ~90 ms more lag on a 5500 RPM/s pull. Set `tach_filter` to `legacy`
to get the old behaviour back.
- **Engine dies mid-session** (tach-proven sessions): the LED bar goes
dark and the pace page shows `STOPPED` instead of a still-counting
pace — status LEDs (temp alert) stay live. Clears on restart.
- **Engine dies mid-session** (tach-proven sessions): the pace page shows
`STOPPED` instead of a still-counting pace, and the LED bar goes dark
while the status LEDs (temp alert) stay live. Clears on restart.
- **Tach page `*OVER REV*` header** now means actual overrev: it shows
only when `overrev_limit` is enabled and RPM reaches it (was a
hardcoded 9999 RPM). The `rev_limit` warning stays on the LED only.
- **Temp status LED flashes red** (was orange), matching the rev
flasher's alert language.

### Changed
- **Bluetooth downloads are faster, and now say why when they are not**
(plan 0008). A 3.3 MB session downloading at 28.8 KB/s on an iPad
prompted a look at the whole transfer path. Three things were capping
Expand Down Expand Up @@ -179,13 +215,6 @@ beta channel, plus the fixes below).
(16 columns after the `Temp1`/`Junction1`/`Temp2` additions) injected
nothing. It now accepts 13+ and reads the stable first 13.

### Added
- **The browser-sim harness can fake a GPS fix.** A "GPS fix" toggle (plus
an mph field) streams a deterministic synthetic 25 Hz fix parked on the
bundled OKC track's start line, so fix-gated flows — most usefully the
on-device course creator, including its 3 s point-averaging hold — can be
exercised in the simulator without loading a log file.

## [4.0.0] - 2026-08-10

### Added
Expand Down Expand Up @@ -1419,7 +1448,9 @@ Initial tagged release. Core capabilities:
- 8+ OLED display pages, Bluetooth LE file download / settings / track
sync, and a low-power sleep mode.

[Unreleased]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v3.1.0...HEAD
[Unreleased]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v4.1.0...HEAD
[4.1.0]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v4.0.0...v4.1.0
[4.0.0]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v3.1.0...v4.0.0
[3.1.0]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v3.0.2...v3.1.0
[3.0.2]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v3.0.1...v3.0.2
[3.0.1]: https://github.com/TheAngryRaven/DovesDataLogger/compare/v3.0.0...v3.0.1
Expand Down
Loading
Loading