Help Article
Bluetooth NMEA strings
Build a compatible Bluetooth device with example sentences, field order, units, scaling, and unavailable values for every NMEA format Gaggle recognises.
Bluetooth NMEA Strings
Profile > Equipment > Bluetooth Devices
This reference describes the sentence formats Gaggle currently recognises, including which fields become live readings. Each example includes a calculated checksum. Append an actual carriage return and line feed (\r\n, bytes 0x0D 0x0A) when transmitting it.
For a custom variometer, start with LK8EX1. For an engine monitor, EMS carries several readings in one sentence and provides explicit unavailable values. RPM and CHT also work with the exact prefixes and layouts below.
- Sending data over BLE
- Sentence formatting
- Engine and fuel: EMS, RPM, CHT, HFM, IBPPG
- Vario and pressure: LK8EX1, BFV, BFX, PDGFTL1, D, LXWP0, PLXVF, POV
- Position and altitude: GPRMC, GPGGA, GNGGA, GAGGA, GLGGA, PGRMZ, XCTRC
- Traffic: PFLAA, PFLAU
- Recognised metadata: GPGSA, LXWP1, LXWP2, LXWP3
- Legacy pressure messages: PRS, _PRS
- Troubleshooting
Sending data over BLE
Gaggle receives serial text through Bluetooth Low Energy (BLE) GATT notifications. For a custom peripheral, either of these profiles can carry the sentences below:
| Profile | Service UUID | Notify characteristic UUID |
|---|---|---|
| Nordic UART (NUS) | 6e400001-b5a3-f393-e0a9-e50e24dcca9e | 6e400003-b5a3-f393-e0a9-e50e24dcca9e |
| Generic BLE serial | 0000ffe0-0000-1000-8000-00805f9b34fb | 0000ffe1-0000-1000-8000-00805f9b34fb |
For Nordic UART, TX means the peripheral’s TX characteristic: the peripheral sends notifications and Gaggle subscribes. Include the notification subscription descriptor (CCCD, 0x2902). Nordic UART alone is sufficient; exposing both profiles is unnecessary for Gaggle. Bluetooth Classic SPP/RFCOMM alone does not provide either BLE service.
Start sending readings after Gaggle subscribes. A generic NUS device does not need a special first sentence or a command written to RX. A BLE connection by itself is insufficient to finish adding a device: Gaggle also waits for a supported reading. Send real telemetry during setup, not only device information or status sentences. See Bluetooth devices for the app setup steps.
Sentence formatting
- Send ASCII text (also valid UTF-8). Sentence identifiers and status letters are case-sensitive; use the spelling shown here.
- Start each NMEA sentence with
$, separate fields with commas, and end with*HHfollowed by CRLF.HHis the two-digit hexadecimal XOR of every byte between$and*, excluding both delimiters. Recalculate it whenever a value or its formatting changes. - Gaggle currently accepts missing or incorrect checksums, but devices should send correct checksums for interoperability. Every complete NMEA example below has a valid checksum.
- Notifications may contain multiple sentences or fragments of a sentence. Gaggle assembles them until a newline or the next
$; a notification boundary alone does not finish a sentence. - Field numbers below start at 1 after the sentence identifier. Keep the listed field positions, including unused slots. An empty field means two adjacent commas; keep trailing commas when final fields are empty.
- Use a dot as the decimal separator.
3100and3100.0are both valid numeric values. Scaling still applies: EMS needs310000for 3100 RPM, while RPM needs3100or3100.0. - An unavailable value is a special value meaning there is no reading. It is checked on the transmitted number before scaling. Do not substitute zero for missing data: zero is often a real reading. Where no unavailable value is supported, skip the sentence until its required measurements are available.
- Ignored means Gaggle recognises that field’s position but does not use it for a live reading. Metadata-only sentences cannot establish that a new device is providing usable telemetry.
The layouts below describe Gaggle’s current implementation. Compatibility notes identify differences from standard or manufacturer formats; they are not requirements of NMEA itself.
Engine and fuel
EMS
Engine monitor data. Include all 9 fields. Gaggle uses pressure, fuel remaining, ambient temperature, cylinder head temperature (CHT), exhaust gas temperature (EGT), and RPM.
$EMS,101325,450,1200,250,2200,18000,55000,8500,310000*70| # | Field | Example value and units | Unavailable |
|---|---|---|---|
| 1 | Pressure | 101325 Pa = 1013.25 hPa; transmit hPa x 100 | 999999 |
| 2 | Fuel flow | 450 = 4.50 litres/hour; transmit L/h x 100; ignored | 9999 |
| 3 | Fuel remaining | 1200 = 12.00 litres; transmit litres x 100 | 9999 |
| 4 | Total fuel used | 250 = 2.50 litres; transmit litres x 100; ignored | 9999 |
| 5 | Ambient temperature | 2200 = 22.00 C; transmit C x 100 | 99 |
| 6 | Cylinder head temperature | 18000 = 180.00 C; transmit C x 100 | 99 |
| 7 | Exhaust gas temperature | 55000 = 550.00 C; transmit C x 100 | 99 |
| 8 | Water temperature | 8500 = 85.00 C; transmit C x 100; ignored | 99 |
| 9 | Engine speed | 310000 = 3100.00 RPM; transmit RPM x 100 | 9999 |
The temperature sentinel is the raw number 99, not 99 C. A real 99 C reading is 9900. Negative temperatures are allowed. There is no status field. Unavailable readings are omitted individually; other valid readings in the sentence are still used. For ignored fields, the unavailable values above keep the same layout without inventing measurements.
If only CHT and RPM are available, this complete example reports 180 C and 3100 RPM:
$EMS,999999,9999,9999,9999,99,18000,99,99,310000*4CRPM
Engine speed. Include all 5 fields, with an empty propeller-pitch slot if unused.
$--RPM,E,1,3100.0,,A*4AWith an ER talker prefix, the same reading is:
$ERRPM,E,1,3100.0,,A*5D| # | Field | Example and meaning |
|---|---|---|
| 1 | Source | E = engine; S = shaft; ignored |
| 2 | Engine or shaft number | 1; integer identifier; ignored |
| 3 | Speed | 3100.0 RPM; no scaling |
| 4 | Propeller pitch | Empty; nominal percent of maximum pitch; ignored |
| 5 | Status | A = valid; any other value, such as V, suppresses the RPM reading |
RPM accepts a two-character NMEA talker prefix, such as $ERRPM, $IIRPM, or $GPRPM. The literal $--RPM identifier remains supported for compatibility. Older app versions require $--RPM; talker-prefixed identifiers require a release containing the talker-prefix fix. Bare $RPM is not supported. There is no numeric unavailable sentinel. An empty or invalid speed with status A becomes zero; use V or omit the sentence when the speed is unavailable.
CHT
Cylinder head temperature. Include exactly these 2 fields; there are no source or engine-number fields.
$--CHT,180.0,A*39With an ER talker prefix, the same reading is:
$ERCHT,180.0,A*2E| # | Field | Example and meaning |
|---|---|---|
| 1 | Cylinder head temperature | 180.0 C; no scaling; negative values are accepted |
| 2 | Status | A = valid; any other value, such as V, suppresses the temperature reading |
CHT accepts a two-character NMEA talker prefix, such as $ERCHT, $IICHT, or $GPCHT. The literal $--CHT identifier remains supported for compatibility. Older app versions require $--CHT; talker-prefixed identifiers require a release containing the talker-prefix fix. Bare $CHT is not supported. This is Gaggle’s custom two-field layout, not the RPM layout: adding E,1 before the temperature prevents a valid reading. There is no numeric unavailable sentinel. An empty or invalid temperature with status A becomes 0 C; use V or omit the sentence when unavailable.
HFM
Fuel level and ambient temperature. Include all 3 fields.
$HFM,12.5,23.0,25.0*71| # | Field | Example and meaning |
|---|---|---|
| 1 | Fuel remaining | 12.5 litres; no scaling |
| 2 | Tank temperature | 23.0; ignored, with no unit conversion applied |
| 3 | Air temperature | 25.0 C; no scaling |
No status or numeric unavailable sentinel is supported. Empty or invalid numbers become zero. Keep the tank-temperature slot even when unused. Use EMS if you need to mark individual readings unavailable.
IBPPG
Insight PPG telemetry. Include all 15 fields. Gaggle uses RPM, CHT, and ambient temperature.
$IBPPG,3100,6500,700,180,200,22,12.6,30,A,1,1,25,120,C,0*43| # | Field | Example and meaning |
|---|---|---|
| 1 | Engine speed | 3100 RPM; no scaling |
| 2 | Maximum engine speed | 6500 RPM; ignored |
| 3 | Lambda probe voltage | 700 millivolts; ignored |
| 4 | Cylinder head temperature | 180 degrees, using field 14 |
| 5 | Maximum temperature | 200 degrees, using field 14; ignored |
| 6 | Air temperature | 22 degrees, using field 14 |
| 7 | Battery voltage | 12.6 V; ignored |
| 8 | Carburettor needle position | 30 degrees; ignored |
| 9 | Needle mode | A automatic, M manual, 0 off; ignored |
| 10 | RPM limiter enabled | 1 enabled, 0 off; ignored |
| 11 | Engine running hours this session | 1 hour; ignored |
| 12 | Engine running minutes this session | 25 minutes; ignored |
| 13 | Total engine hours | 120 hours; ignored |
| 14 | Temperature unit | C for Celsius or F for Fahrenheit |
| 15 | Mark flag | 0 unmarked, 1 marked; ignored |
No numeric unavailable sentinel or validity flag is supported for the readings. Empty or invalid numbers become zero. Send uppercase C or F: the current parser treats every unit value other than C as Fahrenheit. Temperatures and RPM are not multiplied by 100 in this format.
Vario and pressure
LK8EX1
Pressure, climb/sink rate, and ambient temperature. Include all 5 fields, including altitude.
$LK8EX1,89875,1000,123,22,1085*39| # | Field | Example value and units | Unavailable |
|---|---|---|---|
| 1 | Raw pressure | 89875 Pa = 898.75 hPa; transmit hPa x 100 | 999999 |
| 2 | Pressure altitude | 1000 metres, referenced to 1013.25 hPa; ignored by Gaggle | 99999 |
| 3 | Variometer | 123 cm/s = +1.23 m/s; negative means sink | 9999 |
| 4 | Ambient temperature | 22 C; no scaling; may be negative | 99 |
| 5 | Battery | 1085 = 85%; send 1000 + integer percentage, or voltage such as 3.7 V; ignored | 999 |
Pressure is transmitted in Pa, and the altitude field must retain its position. Gaggle currently ignores altitude even when pressure is unavailable; it is not an altitude fallback. Pressure outside 100-3000 hPa after conversion is also ignored. Unavailable pressure, vario, or temperature does not suppress the other readings.
BFV
BlueFly pressure, vario, and ambient temperature. Use this 5-field layout.
$BFV,89875,123,22,85,0*48| # | Field | Example and meaning |
|---|---|---|
| 1 | Pressure | 89875 Pa; see the compatibility note below |
| 2 | Variometer | 123 cm/s = +1.23 m/s; negative means sink |
| 3 | Ambient temperature | 22 C; no scaling |
| 4 | Battery charge | 85 percent; 0 for hardware without a battery; ignored |
| 5 | Pitot differential pressure | 0 Pa; retain this slot when unused; ignored |
There is no unavailable sentinel for pressure, vario, or temperature; invalid or empty numbers become zero. Current limitation: Gaggle forwards BFV pressure without converting Pa to hPa, so its pressure reading can have the wrong scale. Use LK8EX1 for custom devices that need reliable pressure interpretation.
BFX
Extended BlueFly format. Use this 6-field layout; a trailing empty field after voltage is also accepted.
$BFX,89875,123,22,85,0,3.7*40| # | Field | Example and meaning |
|---|---|---|
| 1 | Pressure | 89875 Pa; same conversion limitation as BFV |
| 2 | Variometer | 123 cm/s = +1.23 m/s |
| 3 | Ambient temperature | 22 C |
| 4 | Battery charge | 85 percent; ignored |
| 5 | Pitot differential pressure | 0 Pa; ignored |
| 6 | Battery voltage | 3.7 V; ignored |
Only pressure, vario, and ambient temperature become readings. No unavailable sentinel is supported; invalid or empty numbers become zero. The BFV pressure-scale limitation also applies to BFX.
PDGFTL1
DigiFly AIR data. Gaggle uses only field 3, the variometer. Retain all 10 positions in this layout; unused fields may be empty.
$PDGFTL1,1000,1010,123,,40,85,12,270,370,*06| # | Field | Example and meaning |
|---|---|---|
| 1 | QNE altitude | 1000 metres at standard pressure; ignored |
| 2 | QNH altitude | 1010 metres at the configured QNH; ignored |
| 3 | Variometer | 123 cm/s = +1.23 m/s; negative means sink |
| 4 | Netto vario | Empty; ignored; Gaggle does not interpret its units |
| 5 | Indicated airspeed | 40 km/h; ignored |
| 6 | Ground glide ratio | 85 = 8.5; ratio x 10; ignored |
| 7 | Wind speed | 12 km/h; ignored |
| 8 | Wind direction | 270 degrees; ignored |
| 9 | Main battery voltage | 370 = 3.70 V in DigiFly’s hundredths-of-a-volt format; ignored |
| 10 | Backup battery voltage | Empty; legacy slot, ignored; Gaggle does not interpret its units |
An empty or nonnumeric vario produces no reading; there is no special numeric sentinel. Other fields do not produce altitude, airspeed, wind, or battery readings. Manufacturer field definitions can vary by firmware; see the DigiFly AIR manual.
D
Legacy DigiFly data. Use all 5 positions, leaving fields 3 and 4 empty.
$D,123,89875,,,22*63| # | Field | Example and meaning |
|---|---|---|
| 1 | Variometer | 123 cm/s = +1.23 m/s |
| 2 | Pressure | 89875 Pa = 898.75 hPa |
| 3 | Unused slot | Empty; no units or value interpreted |
| 4 | Unused slot | Empty; no units or value interpreted |
| 5 | Ambient temperature | 22 C |
Empty or nonnumeric measurements are omitted individually; there are no numeric unavailable sentinels. Keep the final temperature slot even if its value is empty.
LXWP0
LX flight data. Include all 12 fields. Gaggle currently uses only field 9, the sixth vario sample.
$LXWP0,Y,40,1000,1.10,1.12,1.15,1.18,1.20,1.23,180,270,12*7C| # | Field | Example and meaning |
|---|---|---|
| 1 | Logger stored flag | Y; ignored |
| 2 | Airspeed | 40 km/h in the LX format; ignored |
| 3 | Pressure altitude | 1000 metres; ignored |
| 4-8 | Vario samples 1-5 | 1.10, 1.12, 1.15, 1.18, 1.20 m/s; ignored |
| 9 | Vario sample 6 | 1.23 m/s; used without scaling |
| 10 | Heading | 180 degrees; ignored |
| 11 | Wind direction | 270 degrees; ignored |
| 12 | Wind speed | 12 km/h; ignored |
An empty or nonnumeric field 9 produces no vario reading. There is no numeric unavailable sentinel. Sending a value only in the first vario slot (field 4) does not currently supply vario to Gaggle. Unused slots may be empty. The LX parser reference describes the LX field conventions; Gaggle’s field selection above is more limited.
PLXVF
LX fast sensor data. Include all 7 fields. Gaggle uses only field 5, the variometer.
$PLXVF,100855.374,,,,1.23,40,1000*74| # | Field | Example and meaning |
|---|---|---|
| 1 | Time | 100855.374; ignored, no time format enforced by Gaggle |
| 2-4 | Accelerometer X, Y, Z | Empty; ignored, no units interpreted by Gaggle |
| 5 | Variometer | 1.23 m/s; no scaling |
| 6 | Indicated airspeed | 40; ignored, no unit conversion applied |
| 7 | Pressure altitude | 1000; ignored, no unit conversion applied |
An empty or nonnumeric vario produces no reading. There is no numeric unavailable sentinel. The other fields may be empty but must retain their positions.
POV
OpenVario key/value pairs. Include one or more complete pairs. Gaggle recognises keys P, E, and T.
$POV,P,898.75,E,1.23,T,22*03| Field positions | Key | Example and meaning |
|---|---|---|
| 1, 2 | P, pressure | 898.75 hPa; no scaling |
| 3, 4 | E, vario | 1.23 m/s; negative means sink |
| 5, 6 | T, temperature | 22 C; no scaling |
Pairs may appear in any order. Omit the entire pair if its reading is unavailable; do not send a key without a value slot. Empty or nonnumeric values produce no reading for that pair, and there is no numeric sentinel. Other keys are ignored. The identifier includes the proprietary P: use $POV, not $OV.
Position and altitude
GPRMC
Position, speed, course, and date/time. Use all 12 fields in this example.
$GPRMC,100855.374,A,2612.3456,S,02812.3456,E,12.3,140.5,100926,0.0,E,A*23| # | Field | Example and meaning |
|---|---|---|
| 1 | UTC time | 100855.374 = 10:08:55.374; use hhmmss.sss with exactly three fractional digits |
| 2 | Status | A valid, V void; currently not used to reject a fix |
| 3 | Latitude | 2612.3456 = 26 degrees 12.3456 minutes; not decimal degrees |
| 4 | Latitude hemisphere | S south, N north |
| 5 | Longitude | 02812.3456 = 28 degrees 12.3456 minutes |
| 6 | Longitude hemisphere | E east, W west |
| 7 | Speed over ground | 12.3 knots in standard NMEA; see limitation below |
| 8 | Course over ground | 140.5 degrees true |
| 9 | UTC date | 100926 = 10 September 2026; ddmmyy |
| 10 | Magnetic variation | 0.0 degrees; ignored; may be empty |
| 11 | Variation direction | E or W; ignored; may be empty |
| 12 | Mode | A autonomous; ignored; may be empty |
There are no numeric unavailable sentinels. Send only valid fixes: status V currently does not suppress the reading, and missing coordinates or malformed timestamps can fail parsing. Empty speed or course becomes zero. Use the full timestamp precision shown above.
Current limitations: speed is forwarded without converting standard knots to Gaggle’s metres-per-second readings, and the RMC timestamp is interpreted in the phone’s local time zone before conversion to UTC. Coordinates less than one degree south or west also have a sign-handling limitation. For custom devices, check the resulting values before relying on RMC for speed or time.
GPGGA, GNGGA, GAGGA, GLGGA
All four identifiers use the same 14-field layout and supply position and altitude. The examples show the same fix from GPS, combined GNSS, Galileo, and GLONASS respectively.
GPGGA (GPS):
$GPGGA,100855.374,2612.3456,S,02812.3456,E,1,08,1.0,1000.0,M,30.0,M,,*7DGNGGA (combined GNSS):
$GNGGA,100855.374,2612.3456,S,02812.3456,E,1,08,1.0,1000.0,M,30.0,M,,*63GAGGA (Galileo):
$GAGGA,100855.374,2612.3456,S,02812.3456,E,1,08,1.0,1000.0,M,30.0,M,,*6CGLGGA (GLONASS):
$GLGGA,100855.374,2612.3456,S,02812.3456,E,1,08,1.0,1000.0,M,30.0,M,,*61| # | Field | Example and meaning |
|---|---|---|
| 1 | UTC time | 100855.374 = 10:08:55.374; use hhmmss.sss |
| 2 | Latitude | 2612.3456, degrees and decimal minutes |
| 3 | Latitude hemisphere | S or N |
| 4 | Longitude | 02812.3456, degrees and decimal minutes |
| 5 | Longitude hemisphere | E or W |
| 6 | Fix quality | 1 GPS fix; 0 invalid; currently not used to reject a fix |
| 7 | Satellites used | 08; count; ignored |
| 8 | Horizontal dilution of precision | 1.0; dimensionless; ignored |
| 9 | Altitude above mean sea level | 1000.0 metres |
| 10 | Altitude unit | Use M for metres |
| 11 | Geoid separation | 30.0 metres; ignored |
| 12 | Geoid separation unit | M; ignored |
| 13 | Differential correction age | Empty when unavailable; seconds; ignored |
| 14 | Differential reference station ID | Empty when unavailable; ignored |
Use valid time and coordinates; no numeric unavailable sentinel is supported. Gaggle combines the time with the phone’s current UTC date. Invalid fix quality does not currently suppress a position, and missing altitude becomes zero. Use metres: the current feet conversion does not correctly convert incoming feet to metres. The coordinate sign limitation noted for GPRMC also applies here. Keep the two empty final fields when differential correction information is unavailable.
PGRMZ
Garmin altitude identifier, with a Gaggle-specific two-field layout in the current parser.
$PGRMZ,3280.84,3*4A| # | Field | Example and meaning |
|---|---|---|
| 1 | Altitude | 3280.84 feet, approximately 1000 metres |
| 2 | Fix mode | 3 required for an altitude reading; other values suppress it |
There is no numeric unavailable sentinel; an invalid or empty altitude with mode 3 becomes zero. Compatibility limitation: the standard Garmin layout has a feet unit field before fix mode (altitude,f,3). Gaggle currently reads field 2 as the fix mode, so that standard layout does not produce altitude. The example above describes the current compact layout. For custom devices, GGA with altitude in metres avoids this discrepancy.
XCTRC
XCTracer identifier. The current Gaggle parser reads this 17-field layout, providing position, altitude, speed, heading, and pressure.
$XCTRC,2026,9,10,10,8,55,37,-26.20576,28.20576,1000,12.3,140.5,1.23,,,898.75,85*65| # | Field | Example and meaning |
|---|---|---|
| 1 | Year | 2026, UTC |
| 2 | Month | 9, range 1-12 |
| 3 | Day | 10, valid day of month |
| 4 | Hour | 10, range 0-23 |
| 5 | Minute | 8, range 0-59 |
| 6 | Second | 55, range 0-59 |
| 7 | Centisecond | 37 = 370 milliseconds, range 0-99 |
| 8 | Latitude | -26.20576 signed decimal degrees; south negative |
| 9 | Longitude | 28.20576 signed decimal degrees; west negative |
| 10 | Altitude | 1000 metres |
| 11 | Speed over ground | 12.3 m/s; no scaling |
| 12 | Course | 140.5 degrees true |
| 13 | Climb rate | 1.23 m/s; currently ignored |
| 14-15 | Unused slots | Empty; ignored |
| 16 | Pressure as read by Gaggle | 898.75 hPa; no scaling |
| 17 | Battery as read by Gaggle | 85 percent; ignored |
No numeric unavailable sentinel is supported. Missing or invalid measurements become zero; missing or invalid date/time components fall back to the current time. Send a complete, valid fix rather than using these fallbacks.
Compatibility limitation: the XCTracer format documented in XCSoar has three reserved fields after climb rate, with pressure at field 17 and battery at field 18. Gaggle currently reads pressure one field earlier, as shown above. Standard output with an empty field 16 therefore gives Gaggle a zero pressure reading. For a custom device, GGA plus LK8EX1 avoids this field-position discrepancy.
Traffic
PFLAA
Relative aircraft traffic. Include all 11 field positions. Positions are relative to your own aircraft.
$PFLAA,0,300,-150,50,2,ABCDEF,180,,12,1.2,7*7C| # | Field | Example and meaning |
|---|---|---|
| 1 | Alarm level | 0 none; 1, 2, 3 increasing urgency; not used as a live alarm by this parser |
| 2 | Relative north | 300 metres north; negative means south |
| 3 | Relative east | -150 metres, meaning 150 metres west |
| 4 | Relative vertical | 50 metres above; negative means below |
| 5 | ID type | 1 ICAO, 2 stable FLARM, 3 anonymous; empty if unknown |
| 6 | Aircraft ID | ABCDEF; six hexadecimal digits; empty if unknown |
| 7 | True ground track | 180 degrees; empty if unavailable |
| 8 | Turn rate | Empty when unavailable; numeric values are passed through without conversion |
| 9 | Ground speed | 12 m/s; empty if unavailable |
| 10 | Climb rate | 1.2 m/s; negative means sink; empty if unavailable |
| 11 | Aircraft type | 7 paraglider; hexadecimal type code |
Aircraft types are 0 unknown, 1 glider/motor glider, 2 tow plane, 3 helicopter, 4 skydiver, 5 drop plane, 6 hang glider, 7 paraglider, 8 piston aircraft, 9 jet/turboprop, B balloon, C airship, D UAV, and F static object. Other codes become unknown.
There are no numeric unavailable sentinels. Empty track, turn rate, ground speed, and climb rate remain unavailable. Empty or invalid relative north/east/vertical becomes zero, so non-directional targets with an empty east field do not retain that distinction. For a stable identity, supply a valid six-hex-digit ID with type 1 or 2. A SoftRF !callsign suffix is accepted and removed from the ID.
PFLAU
FLARM receiver and alarm status. Gaggle recognises this sentence but does not publish a live reading or alarm from it. Send PFLAA for aircraft traffic.
$PFLAU,1,1,2,1,0,,0,,,*4D| # | Field | Example and meaning |
|---|---|---|
| 1 | Received devices | 1; count 0-99 |
| 2 | Transmission status | 1 OK, 0 not transmitting |
| 3 | GPS status | 0 no reception, 1 ground 3D fix, 2 airborne 3D fix |
| 4 | Power status | 1 OK, 0 voltage problem |
| 5 | Alarm level | 0 none; 1, 2, 3 increasing urgency |
| 6 | Relative bearing | Empty without a target; degrees -180 to 180, clockwise from own track |
| 7 | Alarm type | 0 none; 2 aircraft; 3 obstacle/zone; hexadecimal code |
| 8 | Relative vertical | Empty without a target; metres above own aircraft |
| 9 | Relative horizontal distance | Empty without a target; metres |
| 10 | Target ID | Empty without a target; otherwise six hexadecimal digits |
Retain all 10 positions, including empty target fields. All fields are ignored for live telemetry; no numeric unavailable sentinel is applied by Gaggle.
Recognised metadata
The following sentences are recognised but do not supply live flight or engine readings. They may accompany telemetry, but sending only these sentences will not finish adding a new device.
GPGSA
Satellite solution metadata. This example includes 18 fields: the usual 17 plus an optional GNSS system ID.
$GPGSA,A,3,01,02,03,04,05,06,07,08,,,,,1.5,0.9,1.2,1*29| # | Field | Example and meaning |
|---|---|---|
| 1 | Selection mode | A automatic, M manual |
| 2 | Fix type | 1 no fix, 2 2D, 3 3D |
| 3-14 | Satellite IDs | 01 through 08, then four empty slots; up to 12 IDs |
| 15 | Position dilution of precision | 1.5; dimensionless |
| 16 | Horizontal dilution of precision | 0.9; dimensionless |
| 17 | Vertical dilution of precision | 1.2; dimensionless |
| 18 | Optional GNSS system ID | 1 GPS |
Keep empty slots for unused satellites and unavailable DOP values. Gaggle does not turn any of these fields into telemetry or apply numeric unavailable sentinels. Only the GPGSA identifier is registered by Gaggle.
LXWP1
Instrument identity. Include these 5 positions; unknown values may be empty. All values are text, with no units or numeric unavailable sentinels, and are ignored for live telemetry.
$LXWP1,LX9000,12345,9.0,1.0,*2A| # | Field | Example |
|---|---|---|
| 1 | Instrument ID | LX9000 |
| 2 | Serial number | 12345 |
| 3 | Software version | 9.0 |
| 4 | Hardware version | 1.0 |
| 5 | Licence | Empty |
LXWP2
LX performance settings. Include these 7 positions. Gaggle treats all fields as unused text; it does not apply settings or convert units.
$LXWP2,1.5,1.0,0,,,,50*3D| # | Field | Example and convention |
|---|---|---|
| 1 | MacCready | 1.5 m/s |
| 2 | Ballast | 1.0 load factor; dimensionless |
| 3 | Bugs | 0 percent performance degradation in the usual LX convention |
| 4-6 | Polar coefficients A, B, C | Empty; device-specific coefficients, not interpreted by Gaggle |
| 7 | Audio volume | 50 percent |
Unknown values may be empty; no numeric unavailable sentinel is applied. Device conventions can vary, particularly for bugs and polar settings; see the LX field reference. These fields never change Gaggle’s instrument settings.
LXWP3
Extended LX settings. Include these 13 positions. This example supplies a glider name and leaves the unused settings empty.
$LXWP3,,,,,,,,,,,,ASW28,*43| # | Field | Example and interpretation |
|---|---|---|
| 1 | Altimeter offset | Empty |
| 2 | Speed-command mode | Empty |
| 3 | Vario filter | Empty |
| 4 | Total-energy filter | Empty |
| 5 | Total-energy compensation level | Empty |
| 6 | Vario averaging | Empty |
| 7 | Vario range | Empty |
| 8 | Speed-command tab | Empty |
| 9 | Speed-command low threshold | Empty |
| 10 | Speed-command speed | Empty |
| 11 | Smart difference | Empty |
| 12 | Glider name | ASW28 |
| 13 | Time offset | Empty |
Gaggle reads these as unused text: it defines no units, scaling, validity checks, or numeric unavailable sentinels for these settings. Use the originating instrument’s settings conventions if supplying values, or leave their slots empty. None of these fields changes Gaggle’s configuration.
Legacy pressure messages
Gaggle also contains parsers for PRS and _PRS. These are legacy text formats, not NMEA sentences: they have no $, commas, or checksum.
PRS
PRS 18BCDThe prefix PRS is followed by one space and exactly five hexadecimal digits. 18BCD is decimal 101325, conventionally 101325 Pa. There are no other fields or unavailable sentinels.
_PRS
_PRS 18BCDThe prefix _PRS is followed by one space and exactly five hexadecimal digits. The value has the same raw-number interpretation as PRS. There are no other fields or unavailable sentinels.
Current limitations: the BLE text stream assembler starts messages only at $, so standalone PRS/_PRS lines do not currently reach these legacy parsers. The parsers also forward the raw number without pressure scaling. Do not choose these formats for a new BLE device; use LK8EX1, EMS, or POV instead. They are listed here to distinguish legacy parser coverage from working BLE sentence support.
Troubleshooting
- Check both the BLE service UUID and the notification characteristic UUID. A visible scan result or an established BLE link does not prove Gaggle can subscribe to the data stream.
- With a BLE inspector, subscribe to the peripheral’s TX/Notify characteristic and confirm that complete ASCII sentences arrive after subscription. Send a newline after each sentence, including the first one.
- Use the identifiers and field positions above. For older app versions, use literal
$--RPMand$--CHT. Do not add source/engine fields to CHT, even when using a talker prefix. - Send at least one usable measurement during setup. Gaggle waits up to about 35 seconds for data when adding a device. Metadata-only messages, unsupported identifiers, or readings marked unavailable can leave setup waiting even while the BLE link is connected.
- After adding the device, tap it to inspect streamed readings and enable the measurements you want to use while recording. Sending data faster does not guarantee that every message becomes a displayed or recorded sample; downstream updates are throttled.
- If it still fails, send support the device name, phone model, Gaggle version, the attempt’s date/time and time zone, the service and characteristic UUIDs, and one exact transmitted sentence including its checksum and line ending.