Under the Hood

Advanced settings, protocol details. — updated May 06, 2026 for version VB008

Advanced Settings

id_method — Address Type

Declares the transmitted 6-hex-digit ID type:

ValueMeaning
0Random (changes every few minutes)
1ICAO ID
2Device ID (starts with "8")
3Anonymous (random but fixed for flight)
7Override (transmits entered ID, marked as device ID)

ignore_id — Aircraft ID to Ignore

Enter a 6-hex-digit ID to exclude from traffic reports and collision warnings. E.g., your towplane. Leave as 000000 to disable.

follow_id — Aircraft ID to Follow

Prioritize a specific aircraft in traffic reports, e.g., your flying buddy. Leave as 000000 to disable.

tx_power — Transmit Power

ValuePowerUse Case
0Off (receive only)Ground station, second device in same aircraft
12 mW (low)Short-range testing
2Full (≤100 mW)Normal operation (default)

altprotocol — Alternate Protocol

Set to 1 (OGNTP), 6 (Legacy), 7 (Latest) or 8 (ADS-L) to transmit in an alternative protocol once every 4 seconds. Can mix Latest/ADS-L with FANET or P3I using time-slicing.

flr_adsl — Dual Protocol Reception

If set to 1, enables simultaneous Latest+ADS-L reception in compatible dual-protocol modes.

NMEA Output Settings

Output destinations (nmea_out, nmea_out2):

CodeDestination
0Off
1Main serial
2UDP (WiFi)
3TCP (WiFi)
4USB
5Bluetooth
6Aux serial

Sentence type bitfields (nmea_g, nmea_s, nmea_t, nmea_e):

  • nmea_g: 1=basic(GGA+RMC), 2=GSA, 4=GST, 8=GSV, F=all
  • nmea_s: 1=Basic (PGRMZ), 2=LK8EX1, 8=Wind ($PSWSD) — bits are independent and combinable
  • nmea_t: 1=PFLAU+PFLAA, 8=PFLAJ, 9=both
  • nmea_e: 1=tunnel from connected devices, 2=generated (strobe, alarm)

Flight Logging Settings

SettingDescription
logflight0=off, 1=always, 2=airborne, 3=airborne+traffic
logintervalSeconds between fixes (1-155)
compflash0=uncompressed, 1=compressed IGZ format
alarmlog0=off, 1=log alarm events to alarmlog.txt

Other Settings

SettingDescription
hrangeHorizontal reporting range (km)
vrangeVertical reporting range (hundreds of meters)
relay0=off, 1=landed-out, 2=all traffic, 3=relay-only
expireSeconds to keep reporting lost traffic (1-30, default=5)
baud_rate1=4800, 2=9600, 3=19200, 4=38400, 5=57600, 6=115200

debug_flags — Debug Bitmask

A 24-bit hex value. Each bit enables a specific category of serial console output. Bits can be combined; e.g. 000018 = DEEPER + LEGACY.

HexNameWhat it enables
000001WINDWind calculation serial output
000002PROJECTIONWind projection / track extrapolation output
000004ALARMAlarm calculation detail (requires nmea_d=1)
000008LEGACYRaw FLARM/Latest packet hex dump on RX & TX
000010DEEPERRF slot timing, RX/TX sizes, LR1110 packet detail
000020DEEPER2Traffic helper internals, GNS5892 ADS-B detail
000040BLE_TXLog every BLE NUS sentence sent (serial console)
000800RELAYForce relay of all traffic (ignores no_track flag, testing only)
800000SIMULATEReplay SIM file instead of live GNSS — see Flight Simulator

Common combinations:

ValueWhat you get
000010RF slot timing only
000017RF timing + Legacy packet dump + Alarm + Wind
000040BLE TX log only
000050BLE TX log + RF timing
800000Flight simulator

T-Echo Only Settings

SettingDescription
epd_units0=metric, 1=imperial, 2=mixed
epd_zoomDefault zoom level
epd_rotateDisplay direction
epd_orientTrack up or North up
epd_vmodeDefault view: 0=status, 1=radar, 2=text

Protocol Choices

Single Protocols

  • Latest — compatible with new FLARM (2024+), recommended
  • Legacy — old FLARM, not recommended
  • ADS-L — e-conspicuity
  • OGNTP — OGN tracking
  • FANET — paraglider network
  • P3I — PilotAware

Mixed Protocols (examples)

CombinationBehavior
Latest + ADS-LTX/RX Latest, TX ADSL every 4s in slot 0
Latest + OGNTPTX/RX Latest, TX OGNTP every 4s
Latest + FANETTime-sliced: slot 0 = Latest, slot 1 = FANET
Latest + P3ITime-sliced: slot 0 = Latest, slot 1 = P3I
FANET + ADS-LTime-sliced: slot 0 = ADS-L, slot 1 = FANET

With flr_adsl=1, slot 0 uses simultaneous FLR+ADSL dual reception in most modes.

Settings via NMEA

Settings can be changed via NMEA commands through USB or Bluetooth terminal:

  • $PSRFS,?*57 — list all settings
  • $PSRFS,0,label,? — query one setting
  • $PSRFS,0,label,value — change one setting
  • $PSRFC,SAV*3C — save and reboot

Details of Operation

SoftRF is embedded software running in real time. The main loop order:

  1. Baro_loop() — compute vertical speed if sensor available
  2. GNSS_loop() — get new GPS fix
  3. Compute timestamps, discretize fixes into ~2s intervals
  4. Estimate_Wind() — wind estimation and path projection
  5. RF_Transmit() — encode and transmit at preset intervals
  6. RF_Receive() — check for received data
  7. ParseData() — decode received packets, update traffic
  8. Traffic_loop() — collision checking at 2s intervals
  9. Sound_loop() — process audio
  10. NMEA_Export() — output data

Major Changes in This Version

Key changes from mainline SoftRF:

  • Wind estimation — new Wind.cpp module estimates wind from circling drift and speed variation
  • "Latest" collision prediction — predicts curved paths for circling aircraft, accounting for wind
  • ApproxMath — fast trig functions optimized for collision calculations
  • Audio alarms — 3-level buzzer and voice warnings
  • Improved FLARM compatibility — correct time slots, frequency hopping, path projections
  • Vertical separation — taken into account in alarm calculations
  • Hysteresis — prevents alarm oscillation at threshold boundaries
  • Settings file — text-based settings.txt replaces binary EEPROM
  • Dual-protocol — simultaneous FLARM + FANET operation

NMEA Sentence Reference

SoftRF outputs several proprietary NMEA sentences in addition to the standard FLARM set. This section documents them for app developers integrating with SoftRF over serial, USB, or Bluetooth.

$PSWSD — Wind Speed and Direction

Output when the wind estimator has a confident result. Enabled by setting bit 8 (0x08) of nmea_s or nmea2_s. Rate-limited to one sentence every 123 seconds to avoid flooding slow-baud connections.

Sentence format

$PSWSD,SPD,DIR*CS<CR><LF>
FieldTypeUnitDescription
SPDfloat, 1 decimalknotsEstimated wind speed
DIRinteger (0–359)degrees trueWind direction the wind is coming from
*CS2-digit hex—Standard NMEA XOR checksum

Example

$PSWSD,12.3,270*3A

Wind of 12.3 kt coming from the west (270° true).

Notes for app developers

  • The sentence is only emitted when the device is airborne and circling — wind estimation requires thermalling flight to converge.
  • The 123-second interval means your app should not timeout or discard the data if it does not arrive every few seconds. Treat the last received value as valid until a new one arrives or the connection is lost.
  • The wind direction follows the meteorological convention: 270 means wind blowing from the west (i.e., a westerly wind).
  • Speed is in knots, not m/s. Convert with 1 kt = 0.5144 m/s if needed.
  • Enable on the Bluetooth output channel by setting nmea_s bit 8 (nmea_s,08 for wind only, or nmea_s,0b for Basic + LK8EX1 + Wind combined).
  • The sentence is gated: it is only output when at least one of nmea_s or nmea2_s has bit 8 set and the wind estimator has produced a new result within the last circle.

Related debug sentences

When debug output (nmea_d) is enabled, the wind estimator also outputs lower-level sentences ($PSWGS, $PSWNS, $PSWEW) containing raw circle fit data. These are for developer diagnostics only and their format may change between firmware versions.

Known Issues

  • Dual mode FLARM/ADS-L not operational

Flight Simulator Mode

Simulator mode lets you replay a recorded flight on the device without needing GPS reception or real radio traffic. The device reads your own-ship position from a file, and optionally reads nearby traffic from a second file, then runs the full collision-alarm pipeline — buzzer, voice, NMEA output — exactly as it would in the air. This is useful for:

  • Testing alarm thresholds and buzzer/voice response on the ground
  • Verifying a new firmware build behaves correctly
  • Demonstrating SoftRF to new users with realistic traffic scenarios
  • Debugging alarm logic with a known, repeatable scenario
Radio disabled in simulator mode The device does not transmit RF packets and does not relay traffic while the simulator flag is active. It also disables the ADS-B receiver input. The radio hardware stays quiet.

Enabling Simulator Mode

Simulator mode is activated by setting bit 0x00800000 in debug_flags in Advanced Tab of Configurator App. Or update in settings.txt:

debug_flags,00800000

The simulator starts replaying the file approximately 40 seconds after boot, giving the system time to initialise. It will then advance one simulated second at a time, paced by the device clock.

To return to normal operation, remove the flag (set debug_flags,00000000 or delete the line) and reboot.

Simulation Files

Two plain-text files drive the simulator. Both go in the logs/ folder of the storage medium:

FileLocationPurpose
simulate.txt logs/simulate.txt Own-ship position — standard NMEA GGA/RMC sentences for each second of the flight
target.txt logs/target.txt Nearby traffic — one $PFSIM sentence per target per second (optional)

On hardware with an SD card (T-Beam with SD adapter), the files are read from the SD card. On hardware with an internal flash filesystem (T-Echo / T1000E Card), they are read from the internal /logs/ folder, accessible over USB.

If simulate.txt is absent or empty, the simulator still runs but uses the live GNSS receiver or serial input for own-ship position. If target.txt is absent, no simulated traffic is injected.

simulate.txt — Own-Ship Position File

The file contains standard NMEA sentences, one per line, exactly as a GPS receiver would output them. At minimum, each simulated second needs a $GPGGA (or $GNGGA) and a $GPRMC (or $GNRMC) sentence with the same timestamp.

Timing control

The simulator advances one second each time it sees a separator between bursts of sentences. A separator is:

  • A line starting with . (dot) — causes a one-second pause. Use .. for two seconds, ... for three, etc.
  • A blank line — same effect as a single dot.
  • Two consecutive blank lines — two-second pause (each extra blank adds another second).

Example simulate.txt

$GPGGA,102301.00,4712.34567,N,00823.45678,E,1,08,1.0,650.0,M,47.0,M,,*XX
$GPRMC,102301.00,A,4712.34567,N,00823.45678,E,45.0,270.0,130125,,,A*XX
.
$GPGGA,102302.00,4712.33000,N,00823.46000,E,1,08,1.0,651.0,M,47.0,M,,*XX
$GPRMC,102302.00,A,4712.33000,N,00823.46000,E,45.0,270.0,130125,,,A*XX
.
Tip: use your own IGC flight logs You can convert an existing IGC flight log into NMEA sentences using tools such as XCSoar's IGC-to-NMEA converter or any GPX/IGC converter. This gives you a realistic own-ship trajectory to test against.

target.txt — Traffic File

Each line is a proprietary NMEA sentence in the format $PFSIM that describes one traffic aircraft at one moment in time. The simulator injects each sentence as traffic data at the matching UTC time.

$PFSIM sentence format

$PFSIM,HHMMSS,ADDR,ADDRTYPE,ACTYPE,LAT,LON,ALT,SPEED,COURSE,VS,TURNRATE*CS
FieldUnit / FormatDescription
HHMMSSUTC hhmmssTime this target position should be injected (must match the own-ship time)
ADDR6-digit hexFLARM/ICAO address of the traffic aircraft (e.g. 3D1234)
ADDRTYPEintegerAddress type: 0 = ICAO, 1 = FLARM, 2 = OGN, 3 = random
ACTYPEintegerAircraft type: 1 = glider, 2 = towplane, 7 = paraglider, 8 = powered, etc.
LATdecimal degreesLatitude (positive = North)
LONdecimal degreesLongitude (positive = East)
ALTmetres (MSL)Altitude above mean sea level
SPEEDm/sGround speed
COURSEdegrees trueTrack over ground (0–360)
VSm/sVertical speed (positive = climbing)
TURNRATEdeg/sTurn rate (positive = right turn, negative = left turn, 0 = straight)

The checksum *CS at the end is validated by the parser. You must compute a correct NMEA checksum (XOR of all bytes between $ and *). Many NMEA utilities and text editors with NMEA plugins can compute this for you.

Each $PFSIM sentence describes a single aircraft at a single point in time. To simulate continuous traffic, add one sentence per target per second, matching the timestamps in simulate.txt.

Example target.txt

# Glider approaching head-on, 200 m above, closing at ~80 km/h combined
$PFSIM,102301,3D1234,1,1,47.2200,8.3950,850,22.0,90.0,0.0,0.0*XX
$PFSIM,102302,3D1234,1,1,47.2200,8.3920,850,22.0,90.0,0.0,0.0*XX
$PFSIM,102303,3D1234,1,1,47.2200,8.3890,850,22.0,90.0,0.0,0.0*XX
Timing must match A $PFSIM sentence is only injected when the own-ship simulator clock (from simulate.txt) reaches the same UTC second. Sentences with timestamps in the past are discarded. Make sure own-ship and traffic timestamps are aligned.