You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Verified against real NA500 hardware (fw 0.4.9, serial 0007) and Net
Station 6.0.0.60960. NA400 behavior is unchanged: model-specific logic is
gated on the amplifier type reported by cmd_GetAmpDetails.
Protocol fixes (benefit all models):
- Send each command in a single TCP write. The NA500's AmpServer parses
every TCP segment as a complete message, so commands split across
segments (which multiple stream insertions could produce) desynced its
request/response handling. Also resync by skipping stale non-response
lines, and bound the response wait at 10 s so a hung AmpServer can no
longer freeze the client forever.
- GUI links on a background thread with progress via queued signals; the
UI stays responsive through the NA500's ~10 s cold power-on wait and
shows a clean error if the server is unresponsive.
NA500-specific handling:
- Identify NA500 from amp_type; scaling factor 0.044703 uV/bit
(0.75 V / 2^24), confirmed by the GES 500 datasheet, Net Station 6's
NA500ScaleFactor(), and a square-wave calibration measurement.
- Wait for ntn_AmpPowerOn before configuring: the NA500 silently drops
commands issued during power-up.
- Keep one persistent listening data connection per session and never
send cmd_StopListeningToAmp: the NA500's AmpServer stops serving new
listeners after any listener drop (until amp restart) and wedges the
session outright on StopListening.
- Poll the data port for passive recovery: the NA500 emits no
ntn_AmpStarted notification.
- Rate tables: decimated 250-2000 Hz, native 250-16000 Hz, no duplicate
packets at low rates (all verified streaming). Rate detection and
rate-change snapping extended to 16 kHz; detection bounded by measured
duration and robust to stale buffered samples.
- Zero anti-alias filter delay compensation, matching Net Station 6
(its calculateShift() applies no shift for the NA500).
GUI:
- Sample-rate dropdown now offers the NA400+NA500 union (adds 250 Hz
low-latency, 2000 Hz decimated/low-latency split, 16000 Hz) with
"NA500 only" labels; selections are validated against the identified
model at link time (supportsSampleRate) and refused with a clear error
before any command touches the amp.
- LSL stream names derive from the address's last octet (.51/.52 keep
their historic names).
Mock server emulates NA500 rate validation and details response.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+34-15Lines changed: 34 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ The CLI provides a lightweight alternative to the GUI:
33
33
-`--cmd-port <port>` - Command port (default: 9877)
34
34
-`--data-port <port>` - Data port (default: 9879)
35
35
-`--amp-id <id>` - Amplifier ID (default: 0)
36
-
-`--sample-rate <hz>` - Sample rate in Hz (default: 1000). Forces amplifier to this rate if already running at a different rate. Valid rates: 250, 500, 1000 (decimated) or 500, 1000, 2000, 4000, 8000 (native).
36
+
-`--sample-rate <hz>` - Sample rate in Hz (default: 1000). Forces amplifier to this rate if already running at a different rate. Valid rates depend on the amplifier model — see [Sample Rate Modes](#sample-rate-modes). Unsupported combinations are rejected with an error before the amplifier is touched.
37
37
-`--fast-recovery` - Use native rate mode (no FPGA anti-alias filter) for lower latency. See [Sample Rate Modes](#sample-rate-modes).
38
38
-`--impedance` - Enable impedance testing mode
39
39
-`--native-format` - Transmit raw int32 ADC counts instead of float microvolts
@@ -92,15 +92,15 @@ If the amplifier is stopped or restarted externally while the CLI is streaming:
92
92
93
93
## Sample Rate Modes
94
94
95
-
The NA400/NA410 amplifiers support two operating modes that affect anti-aliasing and latency:
95
+
The NA400/NA410/NA500 amplifiers support two operating modes that affect anti-aliasing and latency:
96
96
97
97
### Decimated Mode (Default)
98
98
99
99
Uses the FPGA's digital anti-aliasing filter to downsample from the ADC's native rate. This provides:
100
100
- Better frequency response (~400 Hz bandwidth at 1000 Hz sample rate)
101
-
-Higher latency due to the filter group delay (36-111 ms depending on rate), which the app compensates for automatically — see [Timestamp Compensation](#timestamp-compensation)
101
+
-On the NA400, higher latency due to the filter group delay (36-111 ms depending on rate), which the app compensates for automatically — see [Timestamp Compensation](#timestamp-compensation)
Use `--fast-recovery` to enable native mode for rates that support both modes (500, 1000 Hz).
114
+
Use `--fast-recovery` (or a "Low Latency" dropdown entry) to select native mode for rates where the model offers both.
115
+
116
+
The GUI dropdown shows the union of both models' rates; the client validates the selection against the amplifier's actual model right after it identifies itself and refuses unsupported combinations with a clear error.
115
117
116
118
### Filter Delay by Sample Rate
117
119
118
-
DIN→EEG group delay of the FPGA anti-alias filter (decimated mode only), measured with `scripts/delay_capture_sweep.py`:
120
+
DIN→EEG group delay of the FPGA anti-alias filter (decimated mode only). NA400 values measured with `scripts/delay_capture_sweep.py`:
The NA500 rows are zero deliberately: Net Station 6 applies no anti-alias alignment shift for the NA500 (verified against Net Station 6.0.0.60960), so this app matches that behavior. If a real NA500 filter delay is ever measured, update `resources/sampling_rates.json`.
NA500 support was verified against real hardware (firmware 0.4.9). Differences from the NA400 that this app handles automatically:
135
+
136
+
-**Scaling**: 0.044703 µV/bit (±375 mV over 24 bits, matching the GES 500 datasheet and Net Station 6).
137
+
-**Rates**: decimated up to 2000 Hz; native from 250 Hz up to 16000 Hz. No duplicate packets are sent at low rates (the NA400 duplicates samples below 1000 Hz).
138
+
-**Initialization**: the NA500 silently ignores commands sent while it is powering up (~10 s from cold), so the app waits for the power-on notification before configuring it.
139
+
-**Data connection handling**: the NA500's AmpServer stops serving data to new listeners once any listener disconnects (until the amp restarts), so the app maintains one persistent data connection per session and never issues `cmd_StopListeningToAmp`.
140
+
-**Single client**: while Net Station (or any other client) is linked to the NA500, this app's connections are accepted but not serviced — and vice versa. Unlink Net Station before using this app; concurrent monitoring is not possible on the NA500 (unlike the NA400).
141
+
-**Recovery**: the NA500 emits no `ntn_AmpStarted` notification, so external-restart recovery uses data-port polling instead.
142
+
-**Robustness**: the NA500's embedded AmpServer (fw 0.4.9) can crash or stop responding after abrupt client disconnects; commands now time out after 10 s instead of hanging, and the GUI performs linking on a background thread so the UI never freezes. A crashed AmpServer requires power-cycling the amplifier.
126
143
127
144
## Timestamp Compensation
128
145
@@ -381,7 +398,9 @@ The amplifier's internal DIN ADC samples at a fixed 1 kHz rate, regardless of th
381
398
382
399
The NA400/NA410 amplifiers have a 16-bit digital I/O port with active-low inputs (internal pull-ups). When no trigger device is connected, all lines are pulled high and the DIN stream reports `0` (idle). Grounding a line activates the corresponding bit.
383
400
384
-
The `cmd_SetDigitalInOutDirection` command can configure specific bits for output if needed (consult EGI documentation).
401
+
The NA500's DIN register idles at raw `0` (the NA400 idles at raw `0xFFFF`); its input polarity has not yet been verified with a working trigger source. Its BNC "sync in" connector expects TTL-level pulses (a line-level audio output is not sufficient to drive it).
402
+
403
+
The `cmd_SetDigitalInOutDirection` command can configure specific bits for output if needed on the NA400 (consult EGI documentation). Do **not** send it to an NA500 — firmware 0.4.9 crashed when it was issued during testing.
385
404
386
405
# Acknowledgements
387
406
This application was written to behave near-identically to the BCI2000 AmpServer module that was originally created by EGI.
@@ -466,4 +485,4 @@ After Net Station shuts down the amplifier (via "Shutdown" command), immediately
466
485
467
486
## Sample Rate Auto-Detection
468
487
469
-
The app automatically detects the sample rate when connecting to an already-running amplifier by measuring packet timing. This detection snaps to standard rates (250, 500, or 1000 Hz). If the amplifier is idle when connecting, the app uses the sample rate configured in the UI/config file.
488
+
The app automatically detects the sample rate when connecting to an already-running amplifier by measuring packet timing. This detection snaps to standard rates (250 Hz up to 16000 Hz). If the amplifier is idle when connecting, the app uses the sample rate configured in the UI/config file.
Copy file name to clipboardExpand all lines: resources/amplifier_scaling.json
+4Lines changed: 4 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -14,6 +14,10 @@
14
14
"microvolt_scale": 0.00009636188,
15
15
"description": "Net Amps 410 series"
16
16
},
17
+
"NA500": {
18
+
"microvolt_scale": 0.04470348358154297,
19
+
"description": "Net Amps 500 series — 0.75 V total input range / 2^24 codes, in µV. Extracted 2026-08-31 from Net Station 6.0.0.60960 libEgiDataSource.dll PhysicalAmp::NA500ScaleFactor() (computes rangeVolts 0.75 / 2^24 * 1e6; a Software\\Magstim\\AmpScaleFactor registry value can override it in Net Station)."
Copy file name to clipboardExpand all lines: resources/sampling_rates.json
+46Lines changed: 46 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -57,6 +57,52 @@
57
57
"8000": 0
58
58
}
59
59
},
60
+
"NA500": {
61
+
"_note": "Rates verified against hardware on 2026-08-31 (serial 0007, system_version 0.4.9, fpga_version 0.6.1.f0). Unlike the NA400, the NA500 sends no duplicate packets at sub-1000 Hz decimated rates, and its native mode extends down to 250 Hz and up to 16000 Hz.",
62
+
"_delay_note": "All shifts 0 = no timestamp compensation in decimated mode. This matches Net Station 6.0.0.60960: libEgiDataSource.dll PhysicalAmp::calculateShift() applies anti-alias shifts only for NA400 (112/66/36 ms eeg, 80/28/3 ms pns) and NA410 (76/34/13, 64/24/3) and leaves the NA500 at zero (verified by decompilation 2026-08-31). If a real DIN->EEG delay is ever measured for NA500 decimated mode (scripts/delay_capture_sweep.py), update these values.",
0 commit comments