Skip to content

06 ‐ DTE commands

gfo974 edited this page May 27, 2026 · 15 revisions

The DTE (Data Terminal Equipment) protocol is the primary interface for configuring and querying the tracker. It is used by pylinkit, the LinkIt GUI tool, and any BLE/UART terminal to communicate with the firmware.

Protocol Framing

Request Format

$COMMAND#LEN;PAYLOAD\r
Field Description
$ Start delimiter
COMMAND Command name (4-6 uppercase characters)
# Length separator
LEN Payload length in hexadecimal (3 digits)
; Payload separator
PAYLOAD Command-specific payload (comma-separated)
\r Carriage return terminator

Response Format

Success:

$O;COMMAND#LEN;PAYLOAD\r

Error:

$N;COMMAND#LEN;ERROR_CODE\r

Error Codes

Code Name Description
0 OK Success
1 INCORRECT_COMMAND Unknown command
2 INCORRECT_DATA Invalid data
3 MISSING_ARGUMENT Required argument missing
4 VALUE_OUT_OF_RANGE Value exceeds allowed range
5 MESSAGE_TOO_LARGE Payload exceeds max length (0xFFF)
6 PARAM_KEY_UNRECOGNISED Unknown parameter key
7 BAD_FORMAT Malformed request
8 DATA_LENGTH_MISMATCH Payload length doesn't match #LEN
9 UNEXPECTED_ARGUMENT Too many arguments
10 INVALID_ACCESS_CODE Wrong SECUR access code

Command Summary

Command Description
Parameter Commands
PARML List all parameter keys
PARMR Read parameters by key
PARMW Write parameters by key
STATR Read status/telemetry parameters
Device Commands
PROFR Read profile name
PROFW Write profile name
FACTW Factory reset
RSTBW Reboot device
RSTVW Reset variable (TX/RX counters)
SECUR Security access authentication
RTCW Set device RTC
DUMPM Dump raw memory region
DUMPD Dump sensor log data (CSV)
ERASE Erase sensor log data
Argos/Satellite Commands
PASPW Write pass prediction (AOP) data
SATTX Manual Argos satellite transmission
SATDP Start periodic Doppler TX calibration
SMDDFU SMD module firmware update
SMDTST SMD SPI connectivity test
SATVF Verify comm module credentials (Argos or LoRa)
Sensor Commands
SENSR Read live sensor values
SCALW Write sensor calibration
SCALR Read sensor calibration
PWRON Power on/off components
SWSST Read SWS calibration status
SWSTST Start/stop SWS test mode
SWSCAL Start/cancel LED-assisted SWS air/water calibration
SWSSTATS Read (or read+clear) persistent SWS diagnostic counters
GNSSI Read GNSS module info
GNSSA Read GNSS almanac status
GNSSBCKP Trigger / stop the V_BCKP coin-cell charge mode
RF Test Commands
COMCW Start/stop CW RF emission (SMD / LoRa) for certification / antenna test
LoRa/Bridge Commands
LORATX Manual LoRa test TX
GNSSBR GNSS bridge mode (USB ↔ u-blox M10Q UART)
KIMBR KIM2 bridge mode (USB ↔ CLS KIM2 AT passthrough)
LORABR LoRa bridge mode (USB ↔ RAK3172 AT passthrough)

Parameter Key Naming Convention

Parameter keys are 5 characters: 3-letter prefix + 2-digit number. The third character indicates the type:

  • P -- Configurable parameter (read/write). Returned by PARMR with no arguments.
  • T -- Telemetry / status value (read-only). Returned by STATR with no arguments.
Prefix Group Description
ARP Argos Params Argos TX configuration
ART Argos Telemetry Argos counters and timestamps
GNP GNSS Params GNSS acquisition and filtering
UNP Underwater Params Underwater detection and sampling
LBP Low Battery Params Low battery mode configuration
ZOP Zone Params Geofencing zone configuration
PPP Pass Predict Params Prepass algorithm settings
PRP Pressure Params Pressure sensor configuration
AXP Accelerometer Params Accelerometer configuration
THP Thermistor Params Thermistor sensor configuration
STP Sea Temp Params Sea temperature sensor
PHP pH Params pH sensor configuration
LTP Light Params Ambient light sensor
CDP CDT Params Conductivity-Depth-Temperature
CAP Camera Params Camera trigger configuration
CTP Certification Params TX certification test mode
LDP LED Params LED mode configuration
PWP Power Params TPL5111 wakeup management
DBP Debug Params Debug output configuration
IDT Identity Telemetry Device model, HW/FW version
IDP Identity Params Device IDs, profile name
POT Power Telemetry Battery SOC, voltage
SYT System Telemetry System status (RTC, etc.)
LRP LoRa Params LoRa RAK3172 configuration
LRT LoRa Telemetry LoRa counters and status

Parameter Commands

PARML -- List All Parameter Keys

$PARML#000;\r
→ $O;PARML#LEN;IDP12,IDT06,IDT02,IDT03,ART01,ART02,...\r

Returns all implemented DTE keys. The exact set depends on the build configuration.

PARMR -- Read Parameters

Read one or more values by key, or all "P"-type parameters when called empty.

$PARMR#000;\r                      # Read all configurable parameters
$PARMR#00F;GNP01,ARP05,ARP01\r     # Read specific parameters
→ $O;PARMR#01B;GNP01=1,ARP05=60,ARP01=2\r

PARMW -- Write Parameters

Write one or more key=value pairs. Read-only parameters are silently skipped. Triggers CONFIG_UPDATED after saving.

$PARMW#011;GNP01=1,ARP05=120\r
→ $O;PARMW#000;\r

Error 4 (VALUE_OUT_OF_RANGE) if a value exceeds the parameter's allowed range.

Round-trip safety on permitted_values enums (fix c28ca4a3)

Previously, a permitted_values={0U} enum (e.g. SMD_DEGRADED_MODE accepting only 0) made the DTE decoder throw DTE_PROTOCOL_VALUE_OUT_OF_RANGE during PARMW decoding whenever the GUI wrote the slot back at its current value (autofallback engages SAFE by setting it to 1; later PARMW with SMP00=1 would throw). The throw escapes the per-slot try/catch in PARMW_REQ because the decoder runs BEFORE that loop, and was only caught at the top-level handler which cleared the response. GUI then saw a timeout and "lost" the whole config read/write session.

Fix: rejection now happens via the explicit check in PARMW_REQ (rejected via rejected_keys without throwing). Non-zero writes are reported and every other slot in the batch still applies. The permitted_values field is kept for declarative documentation.

Operator-clear path for SMP00 (commit 29af5362)

SMD_DEGRADED_MODE (SMP00) flipped from read-only to writable. PARMW SMP00=0 is now accepted (clears SAFE mode immediately, next TX uses FAST). PARMW SMP00=1 is rejected — manual SAFE engagement remains under exclusive autofallback control (3 consecutive cascade errors). Lazy sync of the runtime flag at the top of SmdSat::send() makes the change take effect on the next TX without requiring a reboot.

Commonly Used Parameters

Key Name Type Range Description
IDP12 ARGOS_DECID UINT 0-4294967295 Argos decimal ID
IDT06 ARGOS_HEXID HEX 0-FFFFFFFF Argos hex ID
IDP11 PROFILE_NAME TEXT - Profile name
ARP05 TR_NOM UINT 30-1200 TX repetition (seconds)
ARP01 ARGOS_MODE ENUM 0-4 Argos operating mode
GNP01 GNSS_EN BOOL 0/1 GNSS enable
GNP05 GNSS_ACQ_TIMEOUT UINT 10-600 GNSS acquisition timeout (s)
UNP01 UNDERWATER_EN BOOL 0/1 Underwater detection enable
LBP01 LB_EN BOOL 0/1 Low battery mode enable
LBP02 LB_THRESHOLD UINT 0-100 Low battery threshold (%)
DBP01 DEBUG_OUTPUT_MODE ENUM 0-3 0=UART, 1=USB_CDC, 2=BLE_NUS, 3=NONE

STATR -- Read Status/Telemetry

Identical to PARMR but filters for "T"-type keys when called empty.

$STATR#000;\r                  # Read all telemetry
$STATR#00A;ART02,IDT03\r       # Read specific keys
→ $O;STATR#013;ART02=0,IDT03=V0.1\r

Default Telemetry Keys

Key Name Description
IDT02 DEVICE_MODEL Device model
IDT03 FW_APP_VERSION Firmware version
IDT04 HW_VERSION Hardware version
IDT10 DEVICE_DECID Device decimal ID
ART01 LAST_TX Last transmission timestamp
ART02 TX_COUNTER Transmit counter
ART03 ARGOS_AOP_DATE AOP bulletin date
POT03 BATT_SOC Battery state of charge (%)
POT06 BATT_VOLTAGE Battery voltage (V)
SYT01 RTC_CURRENT_TIME Live RTC value (Unix timestamp)

Device Commands

PROFR -- Read Profile Name

$PROFR#000;\r
→ $O;PROFR#018;Profile Name For Tracker\r

PROFW -- Write Profile Name

Max 128 characters.

$PROFW#018;Profile Name For Tracker\r
→ $O;PROFW#000;\r

FACTW -- Factory Reset

Restore all parameters to factory defaults. Device reboots after response.

$FACTW#000;\r
→ $O;FACTW#000;\r

RSTBW -- Reboot Device

$RSTBW#000;\r
→ $O;RSTBW#000;\r

RSTVW -- Reset Variable

Reset a runtime counter to zero.

Index Variable
1 TX_COUNTER
2 BOOT_COUNTER (EXTERNAL_WAKEUP builds only)
3 ARGOS_RX_COUNTER
4 ARGOS_RX_TIME
$RSTVW#001;1\r
→ $O;RSTVW#000;\r

SECUR -- Security Access

Authenticate for privileged operations (OTA, etc.). Accepts code 0x12345678 or the device's ARGOS_DECID.

$SECUR#008;12345678\r
→ $O;SECUR#000;\r

RTCW -- Set RTC

Set the device RTC to a Unix timestamp. Also updates LAST_KNOWN_RTC (PWP06) on all boards for RTC persistence across power cycles.

$RTCW#00A;1708444800\r
→ $O;RTCW#000;\r

Read back via: $STATR#005;SYT01\r

DUMPM -- Dump Memory

Read raw memory as base64. Max length: 0x500.

$DUMPM#007;100,200\r
→ $O;DUMPM#LEN;<base64_data>\r

DUMPD -- Dump Log Data

Paginated CSV dump of sensor logs. Call repeatedly until mmm == MMM.

d_type Log Type
0 System (system.log)
1 GNSS
2 ALS
3 PH
4 RTD
5 CDT
6 Camera
7 AXL (Accelerometer)
8 Pressure
9 Thermistor
A TSYS01
B SWS (saltwater switch log)
C Mortality (RSPB)
$DUMPD#001;1\r
→ $O;DUMPD#LEN;000,002,<base64_csv_data>\r

Response: mmm (page index), MMM (max page index), data (base64 CSV). Max 8 entries per page.

ERASE -- Erase Log Data

log_type Target
1 GNSS
2 System
3 ALL
4-12 ALS, PH, RTD, CDT, Camera, AXL, Pressure, Thermistor, TSYS01
13 SWS
14 Mortality
$ERASE#001;3\r
→ $O;ERASE#000;\r

Argos/Satellite Commands

PASPW -- Write Pass Prediction Data

Upload base64-encoded AOP satellite pass prediction data. Updates ARGOS_AOP_DATE (ART03).

$PASPW#LEN;<base64_encoded_prepass_data>\r
→ $O;PASPW#000;\r

Verify: $PARMR#005;ART03\r

SATTX -- Manual Argos Transmit

Trigger a test satellite transmission. The response is asynchronous (sent after TX completes via KineisEventTxComplete).

Two modes are supported:

Mode 1: Stored Radio Configuration

Uses the radioconf already saved in the device config (ARP51=LDK, ARP52=LDA2, ARP53=VLDA4).

SATTX,<modulation>,<size>[,<tcxo>]
Arg Type Description
modulation UINT 0=LDK, 1=LDA2, 2=VLDA4
size UINT Payload size in bytes
tcxo UINT TCXO warmup time in seconds (optional, default 0)

Example:

$SATTX#004;1,10\r          # LDA2, 10 bytes, stored radioconf
$SATTX#006;0,16,5\r        # LDK, 16 bytes, TCXO warmup 5s

Mode 2: Custom Radio Configuration

Pass a radioconf hex string directly (same format as ARP51/ARP52/ARP53).

SATTX,<modulation>,<radioconf>,<size>[,<tcxo>]
Arg Type Description
modulation UINT 0=LDK, 1=LDA2, 2=VLDA4
radioconf TEXT 32-character hex radioconf string
size UINT Payload size in bytes
tcxo UINT TCXO warmup time in seconds (optional, default 0)

Example:

$SATTX#025;1,0123456789ABCDEF0123456789ABCDEF,10\r
$SATTX#027;2,FEDCBA9876543210FEDCBA9876543210,20,3\r

Mode Detection

The firmware auto-detects the mode by the length of the second argument: if it is longer than 2 characters it is treated as a custom radioconf string, otherwise it is parsed as the packet size (stored radioconf mode).

Packet Size Validation

Modulation ID Max Size
LDK 0 16 bytes (128 bits)
LDA2 1 24 bytes (192 bits) — last byte is firmware-embedded CRC8
VLDA4 2 3 bytes (24 bits)

Size must be between 1 and the maximum for the selected modulation.

Errors

Condition Error Code
Missing arguments (< 2) 8 (MISSING_ARGUMENT)
Invalid modulation (> 2) 5 (INCORRECT_DATA)
Size = 0 or exceeds max 5 (INCORRECT_DATA)
Empty radioconf (stored not configured, or custom empty) 5 (INCORRECT_DATA)
No satellite device available 5 (INCORRECT_DATA)

Response

$O;SATTX#000;\r

SATDP -- Satellite Doppler Calibration

Start periodic Doppler TX at TR_NOM interval. Runs until device reset.

$SATDP#000;\r
→ $O;SATDP#000;\r

LED feedback (commit 143aedc9): SATDP bypasses ArgosTxService and calls smd_sat_instance->send() directly, so the operational FSM never emits SERVICE_ACTIVE for ARGOS_TX and the MAGENTA-on-TX LED dispatch in gentracker.cpp is skipped. The DTE handler now dispatches SetLEDArgosTX / SetLEDArgosTXComplete at every Doppler send and KineisEvent so the bench operator sees the same visual cue as a deployed Argos transmission. cert_tx_active() short-circuits the LED_MODE_GUARD, so the flash happens regardless of LED_MODE.

SMDDFU -- SMD Satellite DFU

Manage SMD module firmware updates over SPI. Only on ARGOS_SMD=ON builds.

Action Value Description
ENTER 0 Enter DFU (bootloader) mode
EXIT 1 Exit DFU mode
STATUS 2 Query DFU mode state
UPDATE 3 Trigger firmware update
INFO 4 Get bootloader info (DFU mode only)
VERSION 5 Get firmware version (app mode only)
$SMDDFU#001;5\r
→ $O;SMDDFU#LEN;0,0,0,v1.2.3\r

Response: status (0=OK), dfu_mode (0/1), progress (0-100%), info (text).

SMDTST -- SMD SPI Test

Run full SPI diagnostic against the SMD module.

$SMDTST#000;\r
→ $O;SMDTST#LEN;<test_results_text>\r

SATVF -- Communications Credentials Verify

Read credentials back from the communication module hardware and compare with config store values. Auto-detects the module type (Argos satellite or LoRa).

Optional force re-write: $SATVF#001;1\r → if hardware differs from config store, re-writes credentials and returns the post-write state (field forced=1).

$SATVF#000;\r                  # read-only verify
$SATVF#001;1\r                 # verify + force re-write if mismatch
→ $O;SATVF#LEN;id,addr,seckey,radioconf,match,forced\r

Argos Satellite (SMD / KIM2)

Field Type Description
id uint DEC_ID read from satellite module hardware
addr uint ADDRESS read from satellite module hardware
seckey text Security key read from satellite module hardware (hex)
radioconf text Radio config read from satellite module hardware (hex)
match uint 1 = hardware matches config store, 0 = mismatch

Compares: ARGOS_DECID (IDP12) and ARGOS_HEXID (IDT06).

If match=0, credentials will be synced to hardware automatically at the next TX (dirty flag mechanism).

LoRa (RAK3172)

Field Type Description
id uint 0 (not applicable for LoRa)
addr uint NJM mode (0=ABP, 1=OTAA)
seckey text Credential summary: NJM=x DEVEUI=xxx APPEUI=xxx APPKEY=xxx (OTAA) or NJM=x DEVEUI=xxx DEVADDR=xxx (ABP)
radioconf text OTAA or ABP
match uint 1 = module matches config store, 0 = mismatch

Compares (case-insensitive hex):

  • OTAA (NJM=1): DEVEUI + APPEUI + APPKEY
  • ABP (NJM=0): DEVEUI + DEVADDR (session keys NWKSKEY/APPSKEY are write-only on RAK3172, cannot be read back)

Auto-wake (LoRa only): since firmware commit 21f89ee9, SATVF automatically boots the RAK3172 if it is powered off (e.g. LORA_LP_MODE=0 shutdown mode or underwater power-off). Boot takes ~1.5 s + ~500 ms AT ping → response returns in under 3.5 s worst case even from a cold start. After the read, the module is powered off again to preserve idle consumption.

No need to issue LORATX first to wake the module — SATVF handles it.

This also applies to SMDDFU 5 (version query) and COMCW start.

SMD/KIM2: the module must already be powered on (e.g. during a TX cycle) or use $PWRON#001;3\r to bring it up first.


Sensor Commands

SENSR -- Read Sensor Values

Live sensor reading. Bitmask selects which sensors to read.

Args: sensors_bitmask (UINT), timeout_s (UINT, reserved for future GNSS acquisition).

Bit Value Sensor Fields
0 0x01 Battery voltage (mV), SOC (%)
1 0x02 Pressure pressure (bar), temperature (°C), altitude (m)
2 0x04 GNSS lat, lon, HDOP, num_sv (cached last fix)
3 0x08 Accelerometer X, Y, Z (g), temperature (°C), activity (0-255)
4 0x10 Thermistor temperature (°C)
5 0x20 Sea Temperature temperature (°C)
6 0x40 ALS (Light) lux
7 0x80 pH pH value

Use 255 (0xFF) for all sensors.

$SENSR#004;255,10\r
→ $O;SENSR#LEN;3700,80,1.013,22.5,45.2,48.8566,-2.3522,1.2,8,0.01,-0.02,0.98,23.1,42,36.5,0.0,0.0,0.0,31\r

Response fields (19 total):

# Field Type Unit Description
1 batt_mv UINT mV Battery voltage
2 batt_soc UINT % Battery state of charge
3 pressure FLOAT bar Barometric pressure
4 temperature FLOAT °C Pressure sensor temperature
5 altitude FLOAT m Barometric altitude
6 lat FLOAT ° Latitude (cached GPS)
7 lon FLOAT ° Longitude (cached GPS)
8 hdop FLOAT - Horizontal DOP (99.9 = no fix)
9 num_sv UINT - Number of satellites
10 accel_x FLOAT g Accelerometer X axis
11 accel_y FLOAT g Accelerometer Y axis
12 accel_z FLOAT g Accelerometer Z axis
13 accel_temp FLOAT °C Accelerometer temperature
14 activity UINT 0-255 BMA400 activity score
15 thermistor_temp FLOAT °C Thermistor body temperature
16 sea_temp FLOAT °C Sea temperature (RTD/TSYS01)
17 als_lux FLOAT lux Ambient light
18 ph FLOAT - pH value
19 sensor_status UINT bitmask Status: bit set = sensor OK

sensor_status bitmask: Each bit corresponds to the same sensor as the request bitmask. A bit is set (1) if the sensor was read successfully, clear (0) if it failed (not compiled, not enabled, or hardware error).

Example: requested 0xFF (all), got sensor_status=0x1F (31) → bits 0-4 set = battery, pressure, GNSS, accel, thermistor OK. Bits 5-7 clear = sea temp, ALS, pH not available (not compiled in this build).

Backward compatibility: The first 15 fields are identical to the previous format. Fields 16-19 are appended. Old parsers that only read 15 fields will continue to work.

SCALW -- Write Sensor Calibration

Args: sensor_id (0-7), offset, value (float).

ID Sensor
0 AXL (Accelerometer)
1 PRS (Pressure)
2 ALS (Ambient Light)
3 PH
4 RTD (Sea Temperature)
5 CDT
6 MCP47X6 (DAC)
7 THERMISTOR
$SCALW#00D;1,0,1013.250000\r
→ $O;SCALW#000;\r

Calibration Offset Reference

AXL (sensor_id=0):

Offset SCALW (write) SCALR (read)
0 Set X offset (g)
1 Set Y offset (g) Read calibrated X (g)
2 Set Z offset (g) Read calibrated Y (g)
3 Auto-calibrate (value ignored, measures 200 samples) Read calibrated Z (g)
5 Read saved X offset (g)
6 Save offsets to flash (value ignored) Read saved Y offset (g)
7 Read saved Z offset (g)

Auto-calibrate (offset=3): device must be on a flat, level surface. Firmware measures 200 samples, computes average X/Y/Z, and stores as offsets. Z targets 1.0g at rest.

PRS (sensor_id=1):

Offset SCALW (write) SCALR (read)
0 Sea level pressure in hPa (default 1013.25) Current sea level pressure (hPa)
1 Temperature offset in °C (default 0.0) Current temperature offset (°C)

THERMISTOR (sensor_id=7):

Offset SCALW (write) SCALR (read)
0 Reset calibration (value ignored) Current calibration offset (°C)
1 Calibrate at known temperature in °C (firmware measures 10 samples, computes offset) Current live temperature (°C)

Example: thermistor reads 22.3°C but the reference thermometer shows 24.0°C. Send $SCALW#009;7,1,24.0\r → firmware computes offset = +1.7°C and saves.

SCALR -- Read Sensor Calibration

Args: sensor_id (0-7), offset.

$SCALR#003;1,0\r
→ $O;SCALR#00A;1013.250000\r

If a sensor or offset is not implemented, SCALR returns 0.0 (not an error).

PWRON -- Power On/Off Components

Value Component
0 ALL (GNSS + sensors + satellite)
1 GNSS (also enables sensor power rail)
2 SENSORS (power rail only)
3 SATELLITE (also enables sensor power rail)
4 OFF (all components)
$PWRON#001;3\r
→ $O;PWRON#000;\r

SWSST -- SWS Calibration Status

Read the Salt Water Switch analog state. Only on builds with SWS_ADC.

$SWSST#000;\r
→ $O;SWSST#LEN;2048,3500,2800,50,2750,2760,1,0,300\r

Response fields (9): air, water, threshold, hysteresis, raw_adc, filtered_adc, calibrated, underwater, time_in_state.

SWSTST -- SWS Test Mode

Start (1) or stop (0) SWS test with LED feedback (Blue=underwater, Yellow=surface).

$SWSTST#001;1\r
→ $O;SWSTST#001;1\r

SWSCAL -- SWS Guided Calibration

LED-assisted air/water baseline calibration. Used at deployment time to teach the device the correct air/water ADC thresholds for the actual mounting + electrode geometry. Only on builds with ENABLE_SWS_ANALOG=1.

Workflow

  1. Device must be in ConfigurationState (reed-switch 3 s or BLE connected).
  2. Hold the tracker in air (electrode dry).
  3. Issue $SWSCAL#001;1\r to start. The synchronous response carries the current snapshot (status=0 initially).
  4. The firmware samples air for ~5 s while flashing LED.
  5. Submerge the tracker in saltwater (or in the deployment water) when LED indicates.
  6. Firmware samples water for ~5 s.
  7. When done, an async response is emitted with status=1 (success) or status=2 (failure). The GUI must listen for this second frame.
  8. The new calibration is persisted to flash (SWS.CAL) and is effective immediately.

Request

$SWSCAL#001;1\r              # Start guided calibration
$SWSCAL#001;0\r              # Cancel an in-progress calibration
Arg Type Description
action UINT 1 = start, 0 = cancel

Synchronous response (immediate snapshot)

$O;SWSCAL#LEN;<status>,<air>,<water>\r
Field Type Description
status UINT 0 = pending / in progress, 1 = completed OK, 2 = failed/cancelled
air UINT Air baseline ADC (0-16383). 0 if not yet sampled.
water UINT Water baseline ADC (0-16383). 0 if not yet sampled.

Async response (calibration completed, ~10 s later)

Same envelope, with status=1 and final air/water values.

Errors

  • PARAM_KEY_UNRECOGNISED (6) — build has ENABLE_SWS_ANALOG=0 (LoRa builds typically)
  • MISSING_ARGUMENT (3) — no action argument

Notes

  • Calling SWSCAL,1 automatically stops any running SWSTST test mode first.
  • If BLE flaps mid-calibration, the async response is routed through whichever channel is current when calibration completes (BLE or USB) — the GUI should handle either.
  • LED behavior during calibration is independent of LED_MODE.

SWSSTATS -- SWS Diagnostic Counters

Read (or read + clear) the persistent SWS safety-mechanism counters introduced by the 2026-05 audit (R-MON-02). Each counter tracks how many times a specific recovery / safety path has fired since the last clear — used to detect sensor drift, biofouling, or hardware issues from field-recovered devices. Only on builds with ENABLE_SWS_ANALOG=1.

Request

$SWSSTATS#001;0\r            # Read counters
$SWSSTATS#001;1\r            # Clear AND read (atomic)
Arg Type Description
action UINT 0 = read-only, 1 = clear then read (returns post-clear values, all zeroes)

Response

$O;SWSSTATS#LEN;<stuck_rec>,<coh_recalib>,<dive_to>,<force_surf>,<spike_rej>,<peak_inc>,<saadc_retry>\r
# Field Triggered by
1 stuck_rec Air-baseline collapse + surface state ⇒ proactive recovery (M6 in 13 — Underwater & Behavioral Modes § Safety mechanisms)
2 coh_recalib Coherence recalibration after baseline drift
3 dive_to UW_MAX_DIVE_TIME exceeded (water baseline recalibrated up)
4 force_surf Cascade level 3 fired — surface forced after 3 consecutive UW_MAX_DIVE_TIME events
5 spike_rej Single-sample spike rejection
6 peak_inc Peak ADC marked incoherent (decayed below water/2) and reset
7 saadc_retry SAADC re-init retry after NRFX_ERROR_INVALID_STATE

Interpretation guide for field-recovered devices

Pattern Likely cause
dive_to > 0 Sensor stuck UW longer than UW_MAX_DIVE_TIME — likely sensor drift, biofouling, or hyper-saline pocket. Investigate.
force_surf > 0 Cascade level 3 fired — definite sensor anomaly. Check electrode physically.
stuck_rec > 0 Dry-electrode death spiral detected and recovered. Possible water seal compromise.
spike_rej > N/day Noisy environment (vibration, RF interference?). Not a defect by itself.
saadc_retry > 0 SAADC silicon needing re-init. Below the M1 threshold = fine; if > 60 in a row, force-surface kicks in.

Errors

  • PARAM_KEY_UNRECOGNISED (6) — build has ENABLE_SWS_ANALOG=0
  • MISSING_ARGUMENT (3) — no action argument

Persistence

Counters live in SWSAnalogService static state, persisted to flash on save. Survive reboots. Use action=1 to reset (for tests or before a fresh deployment).

GNSSI -- GNSS Device Info

Query u-blox M10Q hardware ID and firmware version. Powers on GNSS automatically if not cached.

$GNSSI#000;\r
→ $O;GNSSI#02B;01A2B3C4D5,SPG 4.04 (7b202e),00190000\r

Response: unique_id, sw_version, hw_version.

GNSSA -- GNSS Almanac Status

Check AssistNow Offline almanac file status.

$GNSSA#000;\r
→ $O;GNSSA#00D;1,32768,35,28,0\r

Response: present, file_size, total_records, valid_records, stale.


LoRa/Bridge Commands

LORATX -- LoRa Test Transmission

Manual LoRa test transmission. Only on LORA_RAK3172=ON builds.

Arg Type Description
size UINT Payload size in bytes
$LORATX#001;8\r
→ $O;LORATX#000;\r

Bridge Commands — General Behavior

The tracker exposes 3 UART bridges that turn the USB CDC port into a transparent pipe to the target module. Used for direct configuration / debug / firmware update of the connected module.

Common requirements for all bridges:

  • Tracker must be in ConfigurationState (enter via reed switch 3s or BLE auto-enter).
  • Activation via DTE command $<CMD>#001;1\r; deactivation via $<CMD>#001;0\r or by sending +++.
  • While a bridge is active, debug logs are automatically suppressed on USB CDC to prevent pollution of the passthrough stream. Logs resume when the bridge is stopped.
  • All 3 bridges are auto-stopped when ConfigurationState exits (reed exit, BLE inactivity timeout, error). No [BRIDGE OFF] confirmation is sent in those cases — the GUI should handle silence with a re-handshake.

Exit sequence +++:

Bridge Exit format Why
GNSSBR Exactly 3 bytes +++ (or +++\r / +++\n) Byte-stream mode (UBX binary)
KIMBR Line +++\r\n Line-based AT framing
LORABR Line +++\r\n Line-based AT framing

Confirmation from tracker: \r\n[BRIDGE OFF]\r\n.

GNSSBCKP -- GNSS Backup-Cell Charge Mode

Energises the GNSS power rail and parks the u-blox M10Q in UBX-RXM-PMREQ backup sleep (~15 µA) so the on-board V_BCKP coin-cell / supercap charging circuit can top up the cell without running a normal GNSS acquisition (~25 mA). When the session ends the rail is powered off; on the next normal power_on the M10 hits the BBR fast-path → faster TTFF.

Two ways to drive the mode:

  • Manual: this command (one-shot, overrides any scheduled session in flight).
  • Periodic: the GPS service reads GNSS_BCKP_CHARGE_INT / _DUR / _UW_ONLY and arms its own scheduler — no DTE command required.

Request

$GNSSBCKP#003;<duration_s>\r
Arg Type Range Description
duration_s UINT 0–86400 Session length in seconds. 0 = stop the currently active charge session immediately.

Response

$O;GNSSBCKP#000;\r

Errors:

  • INCORRECT_DATA (2) — GPS device unavailable (M10 not detected at boot)
  • MISSING_ARGUMENT (3) — duration_s not supplied
  • VALUE_OUT_OF_RANGE (4) — outside 0..86400

Behaviour & interactions

  • Refused while a GNSS acquisition is in progress — wait for the fix (or PWRON 4 to stop GNSS) before issuing.
  • Calling GNSSBCKP <new_dur> while already charging — extends/replaces the auto-exit timer; does not re-cold-boot the M10.
  • A scheduled GNSS acquisition (service_initiate) takes priority — if the GPS service decides to fire a fix during the session, the backup mode is aborted synchronously and the normal acquisition starts.
  • Saltwater-switch surface event with GNSS_BCKP_CHARGE_UW_ONLY=true also aborts the session immediately so the GNSS_TRIGGER_ON_SURFACED flow runs unimpeded.

Example

$GNSSBCKP#003;600\r      → charge for 10 minutes
$GNSSBCKP#001;0\r        → stop now

GNSSBR -- GNSS Bridge Mode

USB-to-GNSS UART passthrough for u-blox M10Q configuration via u-center or manual AssistNow loading. Raw byte-stream — UBX binary and NMEA ASCII both supported.

  • Module UART baudrate: forced to 9600 by tracker (u-center default)
  • Framing: none, raw bytes bidirectional
  • ISR buffer: 1024 bytes (handles bulky UBX dumps)
Arg Value Description
action 1 Start bridge
action 0 Stop bridge
$GNSSBR#001;1\r              # Start bridge
→ $O;GNSSBR#000;\r
<UBX bytes / NMEA lines bidirectional>
+++                           # Exit (3 raw bytes)
→ \r\n[BRIDGE OFF]\r\n

KIMBR -- KIM2 Bridge Mode

USB-to-KIM2 UART passthrough for direct CLS KIM2 AT command access. Only available on KIM builds (neither ARGOS_SMD=1 nor LORA_RAK3172=1).

  • Module UART baudrate: BSP default (configured at build time)
  • Framing: line-based — the tracker appends \r\n to each USB line before forwarding to KIM2, and forwards each KIM2 line back with CRLF restored
  • If the KIM2 is powered off at start, the tracker powers it on automatically (500 ms boot delay)
Arg Value Description
action 1 Start bridge
action 0 Stop bridge
$KIMBR#001;1\r               # Start bridge
→ $O;KIMBR#000;\r
AT+ID=?                       # GUI sends this line (CRLF appended automatically)
+ID=123456                    # KIM2 response
+OK                           # KIM2 OK
+++                           # Exit (line with CRLF)
→ \r\n[BRIDGE OFF]\r\n

Common AT commands: AT+PING=?, AT+ID=?, AT+ADDR=?, AT+RCONF=<hex>, AT+SAVE_RCONF, AT+KMAC=1, AT+LPM=0x0F, AT+TX=<hex>.

Note: send() is rejected with KineisEventDeviceError while the bridge is active — stop the bridge before triggering a TX via $SATTX or normal service operation.

LORABR -- LoRa Bridge Mode

USB-to-RAK3172 UART passthrough for direct RUI3 AT command access. Only available on LoRa builds (LORA_RAK3172=1). Useful for manual module configuration, diagnostics, and firmware updates.

  • Module UART baudrate: 115200 (RAK3172 default)
  • Framing: line-based — same as KIMBR, tracker appends \r\n automatically
Arg Value Description
action 1 Start bridge
action 0 Stop bridge
$LORABR#001;1\r              # Start bridge
→ $O;LORABR#000;\r
AT+DEVEUI=?                  # Direct AT command to RAK3172
0011223344556677              # Response from RAK3172
+++                           # Exit (line with CRLF)
→ \r\n[BRIDGE OFF]\r\n

Common RUI3 commands: AT+VER=?, AT+BAND=?, AT+DEVEUI=?, AT+JOIN=1:0:10:8. Async events +EVT:JOINED, +EVT:TX_DONE, +EVT:RX_... are forwarded to the GUI as they arrive.


RF Test Commands

COMCW -- Continuous Wave RF Test

Trigger a Continuous Wave (CW) RF emission on the satellite or LoRa module. Used for regulatory certification (FCC, CE, etc.), antenna tuning measurements, and end-of-line production tests.

Module support:

Build Behavior
ARGOS_SMD=1 Forwards to SMD cw_start() / cw_stop() STM32WL commands
LORA_RAK3172=1 Forwards to RAK3172 cw_start() / cw_stop() AT commands (auto-wakes module if powered off)
KIM2 build (no SMD, no LoRa) Returns status=0, info="CW not supported on this module"

Request

$COMCW#001;0\r                              # Stop CW emission
$COMCW#011;1,401650000,22,30\r              # Start CW: 401.65 MHz, 22 dBm, 30 s
Arg Type Range Required Description
mode UINT 0 or 1 yes 0 = stop, 1 = start
freq_hz UINT module-specific yes (mode=1) Carrier frequency in Hz. SMD: ~401.6 MHz Argos band. LoRa: 863-928 MHz band-dependent.
power_dbm UINT 0-30 yes (mode=1) TX power in dBm. SMD typical 22 dBm at antenna. LoRa max 14 dBm in EU868.
duration_s UINT 0-3600 optional Max emission duration in seconds. 0 = no auto-stop, must call mode=0 to stop. Safe default: 30-60 s.

Response

$O;COMCW#LEN;<error_code>,<status>,<info>\r
Field Type Description
error_code UINT Always 0 (frame-level OK). Real status is in next field.
status UINT 0 = success, 1 = failure
info TEXT Human-readable status: "CW start OK", "CW stop OK", "CW start failed", "CW not supported on this module", "SMD not available", "LoRa not available"

Errors

  • MISSING_ARGUMENT (3) — mode missing, or mode=1 and freq_hz/power_dbm missing
  • Status field = 1 if module rejects (out-of-band frequency, hardware fault, module not detected)

Safety / regulatory notes

  • CW emission is illegal outside test environments. Only use in screened RF chambers or with regulator authorization.
  • Always set a duration_s ≤ 60 s for protection — a stuck-on CW emission drains the battery in minutes and may violate spectrum rules.
  • After successful cw_start, the module is in a non-normal state. mode=0 (stop) must be issued before normal TX can resume. A reboot also recovers.
  • For LoRa: cw_stop resets the RAK3172 module (clean state restore).

Example sequences

SMD certification (~60 s burst at 401.65 MHz, 22 dBm):

$COMCW#011;1,401650000,22,60\r
→ $O;COMCW#011;0,0,CW start OK
... (60 s emission, auto-stop) ...

Manual start/stop:

$COMCW#015;1,401650000,22,0\r              # Start, no auto-stop
→ $O;COMCW#011;0,0,CW start OK
... (measurement) ...
$COMCW#001;0\r                              # Stop
→ $O;COMCW#012;0,0,CW stop OK

LoRa CW test (EU868 channel, 14 dBm):

$COMCW#011;1,868100000,14,30\r
→ $O;COMCW#011;0,0,CW start OK

Parameter Reference

For the complete table of all configurable parameters (keys, types, ranges, defaults, and detailed descriptions), see Parameters Definition.

Clone this wiki locally