Skip to content
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ See the **[Parts List](docs/get-started/parts.md)** for everything you need with

### 2. Wire it up

Follow the **[Sound Trigger Wiring Guide](docs/build/sound-trigger.md)** to connect the SEN-14262 to the OPS243-A. The (deprecated) K-LD7 modules connect via USB — no wiring needed.
Follow the **[Sound Trigger Wiring Guide](docs/build/sound-trigger.md)** to connect the SEN-14262 to the OPS243-A. The (deprecated) K-LD7 modules connect via USB — no wiring needed. The OPS243 also has an opt-in internal speed-trigger path, which requires OPS243-A firmware v1.3.2 or newer in the 1.3 release train; see the **[Internal Hardware Trigger Guide](docs/hardware-trigger.md)**.

**Adding the IWR6843 angle radar?** The Pi cannot power both radars over USB, so
the OPS243 moves to the Pi's GPIO UART header while the TI board takes the USB
Expand Down
8 changes: 8 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
and a trigger-frame impact marker. MP4 conversion starts only after a manual
Replay selection, caches the result beside the raw capture, and reports
retryable preparation or playback failures without affecting shot results.
- **Opt-in OPS243 internal hardware trigger.** `--trigger hardware` configures
the radar's internal speed trigger with 25 mph, magnitude 25, and the tested
`S#6` split at 30 ksps. Captures are parsed and the radar is re-armed with
`GC` after each dump. The existing sound-trigger default and
`--sound-pre-trigger` behavior are unchanged. Hardware mode requires and
validates OPS243-A firmware v1.3.2 or newer in the 1.3 release train;
firmware v1.3.1 is rejected because of a vendor data-sequence bug. See
[OPS243 Internal Hardware Trigger](hardware-trigger.md).
- **Battery and external-power status for Raspberry Pi UPS boards.** OpenFlight
can now display charging state and battery percentage, issue dismissible 20%
and 10% warnings while discharging, and record throttled power telemetry in
Expand Down
8 changes: 4 additions & 4 deletions docs/get-started/parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Hardware components for building the OpenFlight golf launch monitor.

The sound trigger detects club impact to precisely time radar captures. Essential for spin detection via rolling buffer mode.

> **Optional path, not merged yet:** [PR #221](https://github.com/open-flight/openflight/pull/221) adds an opt-in `--trigger hardware` mode in which the OPS243 fires the rolling-buffer dump from its own internal speed trigger, with no SEN-14262 in the loop. It needs OPS243-A firmware 1.3.2, which every OPS243-A can run; whether getting there costs you anything depends on the firmware your radar arrived with, see [Internal Trigger Instead](#internal-trigger-instead-pr-221) below. Until the PR lands the sound trigger is the supported trigger and stays in the totals.
> **Optional internal-trigger path:** Hardware mode lets the OPS243 fire the rolling-buffer dump from its own internal speed trigger, with no SEN-14262 in the loop. It requires OPS243-A firmware 1.3.2 or newer in the 1.3 release train; firmware 1.3.1 is rejected because of a vendor data-sequence bug. See [Internal Hardware Trigger](#internal-hardware-trigger) below.

| Part | Description | Link | ~Price |
|------|-------------|------|--------|
Expand All @@ -49,11 +49,11 @@ SEN-14262 Raspberry Pi OPS243

See [sound-trigger-wiring.md](../build/sound-trigger.md) for detailed instructions and troubleshooting.

### Internal Trigger Instead (PR #221)
### Internal Hardware Trigger

[PR #221](https://github.com/open-flight/openflight/pull/221) lets the OPS243-A start the rolling-buffer capture from its own speed trigger, so the sound detector, its resistor and its wiring are not needed. The firmware that adds that trigger is OPS243-A 1.3.2, and any OPS243-A can be brought to it. What that costs you depends on what your radar arrived with, so check before buying anything: plug the radar into USB, open a serial terminal, send `?V`, and read the version it prints back.
Hardware mode lets the OPS243-A start the rolling-buffer capture from its own speed trigger, so the sound detector, its resistor and its wiring are not needed. The supported firmware is OPS243-A 1.3.2 or newer in the 1.3 release train. Check before buying anything: plug the radar into USB, open a serial terminal, send `?V`, and read the version it prints back.

- **It reports 1.3.2 or later.** Nothing to buy. OmniPreSense [told the project on 2026-09-10](https://github.com/open-flight/openflight/pull/221#issuecomment-5619646576) that 1.3.2 went onto the sensors shipping from that build on (1.3.1 had gone to some earlier customers with a late bug), so a new order should arrive like this. Once the PR lands, skip the Sound Trigger table above.
- **It reports 1.3.2 or later in the 1.3 train.** Nothing to buy; use `scripts/start-kiosk.sh --trigger hardware`. OmniPreSense [told the project on 2026-09-10](https://github.com/open-flight/openflight/pull/221#issuecomment-5619646576) that 1.3.2 went onto the sensors shipping from that build on (1.3.1 had gone to some earlier customers with a late bug), so a new order should arrive like this. Skip the Sound Trigger table above if you choose hardware mode.
- **It reports 1.3.1 or older.** You flash it yourself, which is where the debugger cost comes in. OmniPreSense's [AN-013 code-update note](https://omnipresense.com/wp-content/uploads/2019/06/AN-013-D_OPS241-Code-Update.pdf) is the procedure: a SEGGER J-Link on the radar's keyed `J2` JTAG header (a 10-pin 1.27 mm Cortex debug header, not the `J3` UART header OpenFlight wires to), Infineon's free XMCFlasher in Serial Wire Debug mode with the XMC4500-1024 target selected, and the 1.3.2 hex file, which is not a public download: email customerservice@omnipresense.com for it, and they will also confirm which J-Link model to get. Send `?P` first and pick the XMC4700 in XMCFlasher instead if the board reports that part ([note on the PR](https://github.com/open-flight/openflight/pull/221#issuecomment-5463503457)). Do not press Erase in XMCFlasher: it clears the factory settings some sensors carry and anything you saved to persistent memory. On Windows run the J-Link driver installer as administrator and tick the legacy J-Link USB driver, or XMCFlasher will not find the probe ([upgrade report](https://github.com/open-flight/openflight/pull/221#issuecomment-5756563718)).

| Part | Description | Link | ~Price |
Expand Down
82 changes: 82 additions & 0 deletions docs/hardware-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# OPS243 Internal Hardware Trigger

OpenFlight’s `hardware` trigger mode lets the OPS243-A decide when a rolling-buffer capture starts. It is opt-in; the kiosk default remains the existing SEN-14262 sound trigger.

## OPS243 firmware prerequisite

Hardware-trigger mode requires **OPS243-A firmware v1.3.2 or newer in the 1.3
release train**. Firmware v1.3.1 has a vendor data-sequence bug and is rejected.
The driver queries `?V` before sending the internal trigger setup commands and
fails fast if the reported version is from an older or different release train,
malformed, or unavailable. Update the physical OPS243 using the manufacturer’s
firmware procedure before running `--trigger hardware`; this application does
not flash the radar.

## Methodology

The host configures the radar once and then waits for the radar’s completed rolling-buffer dump. The host does not poll speed reports or send `S!` for each shot:

1. Put the radar in idle mode with `PI`.
2. Set a temporary outbound `ST-90` guard before entering rolling-buffer mode.
`GC` can restore the detector units to m/s before `US` is sent; 90 is below
the 30 ksps ceiling of 93.2 m/s and is still above ordinary startup motion
if the board retained mph units.
3. Enter rolling-buffer mode with `GC`, then resend the guard because `GC`
resets detector settings.
4. Restore the detector settings that `GC` resets: 30 ksps and MPH units first,
then raise the temporary guard to `ST-200` while the remaining settings are
written: 128 samples, `X=2`, outbound filtering, JSON plus magnitude output,
and the configured `S#n` split.
5. Restore the magnitude gate `SMn`, then restore the requested `ST-n` last and allow the 4,096-sample history to fill.
6. Wait for the board-triggered dump, parse the I/Q payload, and reject it if it has no outbound ball-speed reading at or above 35 mph.
7. Re-arm with the same temporary guard around `GC`, restore the cached settings, and wait for the buffer to fill again. A serial write timeout keeps the capture and reports a retryable re-arm failure instead of discarding the shot.

The implementation is intentionally limited to the OPS243 trigger path; the
experimental analysis and UI work remain outside this focused change.

## Defaults and command

| Setting | Hardware-mode default |
|---|---:|
| Trigger threshold | 25 mph |
| Trigger magnitude | 25 (`SM25`) |
| Pre-trigger split | 6 segments (`S#6`) |
| Sample rate | 30 ksps (required) |
| Minimum accepted outbound ball speed | 35 mph |

Run the mode directly with:

```bash
openflight-server \
--trigger hardware \
--trigger-threshold 25 \
--trigger-magnitude 25 \
--pre-trigger-segments 6 \
--sample-rate 30
```

The kiosk script forwards the same settings:

```bash
scripts/start-kiosk.sh --trigger hardware
```

Use `--trigger-threshold`, `--trigger-magnitude`, and `--pre-trigger-segments` to override the hardware path. `S#6` applies only to this new mode. The established sound path continues to use `--sound-pre-trigger` and keeps its existing default and behavior:

```bash
scripts/start-kiosk.sh --trigger sound --sound-pre-trigger 16
```

The internal trigger does not depend on the SEN-14262 sound edge. Existing sound-trigger wiring can remain installed, but selecting `hardware` is the software choice that activates the OPS243 internal trigger.

## Raspberry Pi retest checklist

Before treating a PR as ready for merge, run the hardware path on the target Pi and record the observations in the PR body:

Also run the unchanged sound path with the same representative shots:

```bash
scripts/start-kiosk.sh --trigger sound
```

I was unable to regression test the sound trigger.
8 changes: 8 additions & 0 deletions docs/how-it-works/rolling-buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ The runtime then starts in the persisted `GC` rolling-buffer mode without
re-entering it. See [Sound trigger wiring](../build/sound-trigger.md) for the
recommended direct hardware trigger.

The OPS243 internal speed trigger is available as a separate, opt-in capture
strategy. It requires OPS243-A firmware v1.3.2 or newer in the 1.3 release
train, uses the tested 30 ksps configuration, and defaults to `S#6`; see
the [Internal Hardware Trigger guide](../hardware-trigger.md) for its command
ordering, re-arm behavior, and Raspberry Pi validation checklist. The sound
path and its defaults remain unchanged.

## Current defaults

| Setting | Value |
Expand Down Expand Up @@ -70,4 +77,5 @@ in the session JSONL logs described in the

- [Raspberry Pi Setup](../setup/raspberry-pi.md)
- [Sound Trigger Wiring](../build/sound-trigger.md)
- [OPS243 Internal Hardware Trigger](../hardware-trigger.md)
- [Spin Replay and Diagnostics](../development/spin-replay.md)
5 changes: 4 additions & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ How a capture is initiated and framed.

| Flag | Type / default | Description |
| --- | --- | --- |
| `--trigger` | choices: `sound`, `speed`; default `sound` | Trigger strategy |
| `--trigger` | choices: `sound`, `speed`, `hardware`; default `sound` | Trigger strategy |
| `--trigger-threshold`, `--speed-trigger-threshold`, `--trigger-speed` | float | Internal or host speed-trigger threshold in mph; hardware default `25` |
| `--trigger-magnitude` | int; default `25` | OPS243 internal trigger magnitude (`SMn`) |
| `--pre-trigger-segments` | int; default `6` | Hardware-trigger pre-trigger segments (`S#n`) |
| `--sound-pre-trigger` | int; default `16` | Pre-trigger segments S#n, 0-32 (default: 16 = 50/50 split, each segment ~4.27ms at 30ksps) |

## IWR6843 angle radar
Expand Down
Loading
Loading