# TRK1 Binary Telemetry — Version 1 The binary stream is the shared transport and storage representation for USB, BLE, and any later nonvolatile buffer. All multibyte integers and IEEE-754 float32 values are little-endian. Frames are self-identifying and may be split or combined by an underlying byte transport. ## Frame header (36 bytes) | Offset | Size | Field | | ---: | ---: | --- | | 0 | 4 | ASCII magic `TRK1` | | 4 | 1 | Wire version (`1`) | | 5 | 1 | Packet type: metadata `1`, samples `2` | | 6 | 1 | Header size (`36`) | | 7 | 1 | Record size (`0` or `20`) | | 8 | 1 | Record count (`0` or 1–8) | | 9 | 1 | Packet flags | | 10 | 2 | Payload size | | 12 | 4 | Monotonic packet sequence | | 16 | 8 | Base ESP timer timestamp in microseconds | | 24 | 4 | Cumulative samples lost to read failure, queue overflow, or output failure | | 28 | 4 | Cumulative acquisition-loop overruns | | 32 | 4 | IEEE CRC-32 | CRC uses polynomial `0xEDB88320`, initial value `0xFFFFFFFF`, and final XOR `0xFFFFFFFF`. It covers header bytes 4–31 followed by the complete payload. The magic and stored CRC field are excluded. Packet flag bit 0 means at least one sample timestamp delta saturated. ## Sample record (20 bytes) | Offset | Size | Field | | ---: | ---: | --- | | 0 | 4 | Sample sequence | | 4 | 2 | Timestamp delta from the preceding record, in 10 us units | | 6 | 2 | Enclosure accel X raw (`int16`) | | 8 | 2 | Enclosure accel Y raw (`int16`) | | 10 | 2 | Enclosure accel Z raw (`int16`) | | 12 | 2 | Enclosure gyro X raw (`int16`) | | 14 | 2 | Enclosure gyro Y raw (`int16`) | | 16 | 2 | Enclosure gyro Z raw (`int16`) | | 18 | 1 | Raw ADXL345 `INT_SOURCE` | | 19 | 1 | Raw L3G4200D `STATUS_REG` | The first record has delta zero and uses the frame's base timestamp. Each later timestamp is reconstructed by cumulatively adding its delta. A delta that cannot fit is stored as `0xFFFF` and sets packet flag bit 0. Sample sequence gaps remain detectable independently. Mapped raw counts are authoritative. The original sensor-native axes can be reconstructed because the mappings are lossless: ```text accel native = (-enclosure_y, enclosure_x, enclosure_z) gyro native = ( enclosure_x, enclosure_y, enclosure_z) ``` ## Metadata payload (48 bytes) Metadata frames repeat approximately every five seconds so a receiver may attach midstream. The payload contains: - Sample rate, accelerometer range, gyroscope range, and mapping/calibration flags - Three accel offset float32 values - Three accel counts/g float32 values - Three gyro bias float32 values - Nominal gyro mdps/LSB float32 value A byte-stream receiver may begin inside an incomplete frame. It discards bytes until a magic/header/CRC combination validates. Host tools report any rejection before that first valid frame separately from CRC failures after synchronization. ## Buffering Acquisition runs in a dedicated higher-priority task and writes complete samples to a 128-entry RAM queue. The lower-priority output task batches up to eight records per frame. At 100 Hz this queue represents about 1.28 seconds of decoupling from a blocked transport. Queue overflow never overwrites an older sample silently: sequence gaps and the cumulative lost-sample counter expose it.