======= Telemetry decoding ====== Describes how to decode data from [[telemetry_receiving|recieved telemetry]]. This includes evaluation of temperature, pressure and humidity from measured values or GPS coordinates. ===== FRAME_PAYLOAD_DATA structure ===== Each frame contains payload consisting of subframes with varying length. ===== SUBFRAME structure ===== ^ offset (B) ^ lenght (B) ^ name ^ content ^ | 0 | 1 | SUBFRAME_TYPE | Type of subframe ? | | 1 | 1 | SUBFRAME_LEN | Length of subframe payload | | 2 | 2*SUBFRAME_LEN | SUBFRAME_PAYLOAD | subframe payload | | 2*SUBFRAME_LEN+2 | 2 | SUBFRAME_CRC | CRC 16 of subframe payload, polynom = 0x11021 (0x1021 withought leadeing 1) | ==== Known subframe types ==== ^ SUBFRAME_TYPE ^ description ^ | 0x65 | Calibration and Configuration fragment | | 0x69 | Measurement data | | 0x67 | GPS data | | 0x68 | RADAC (radiation measurement) / O3 (ozone) | | 0xff | padding ? | ===== Calibration subframe payload (0x65) ===== expected payload length: 32 ^ offset (B) ^ lenght (B) ^ name ^ content ^ description ^ | 0 | 2 | CALIB_FR_NUM | uint16 | frame number, (starts from 1) | | 2 | 10 | CALIB_ID | string | 0x20 0x20 + sonde ID (same as on cover) | | 12 | 1 | CALIB_STATE_0 | uint8 | 0 - OK; 0x08/0x0A - battery low / battery low, powe off countdown running? | | 13 | 1 | CALIB_STATE_1 | uint8 | see table bellow | | 14 | 1 | CALIB_UNKNOWN_0 | 0x00 | ??? | | 15 | 1 | CALIB_FRAG_NUM | unit8 | callibration and configuration fragment number | | 16 | 16 | CALIB_FRAG_DATA | bytes | calibration and configuration data fragment | ==== STATE_1 ==== TODO: verification needed, possible documentation bug ^ bit offset ^ description ^ | (LSB) 0 | start detected (set at the same time as bit 5) | | 1 | ??? | | 2 | humidity sensor heating: 0 = off, 1 = on | | 3 | humidity sensor for measurement: 0 = U1 (CH2), 1 = U2 (CH3) | | 4 | set to 1 when current drown from battery is increased by 50mA | | 5 | start detected (set at the same time as bit 1) | | 6 | ??? | | (MSB) 7 | ??? | ===== Measurement subframe payload (0x69) ===== expected payload length: 24 ^ offset (B) ^ lenght (B) ^ content ^ name ^ description ^ | 0 | 3 | int24 | MEAS_T | Temperature sensor (wire at end of stick) | | 3 | 3 | int24 | MEAS_U1 | Humidity (remoter to sonde) | | 6 | 3 | int24 | MEAS_U2 | Humidity (closer to sonde) | | 9 | 3 | int24 | MEAS_REF1 | reference upper bound, increase with temperature (or vice versa, TODO) | | 12 | 3 | int24 | MEAS_REF2 | reference upper bound, decrease with temperature (or vice versa, TODO) | | 15 | 3 | int24 | MEAS_P | Pressure | | 18 | 3 | int24 | MEAS_REF3 | reference lower bound | | 21 | 3 | int24 | MEAS_REF4 | reference lower bound | ref = (MEAS_REF3 + MEAS_REF4) / 2; p_rel = 1.0 / ((MEAS_P - ref) / (MEAS_REF1 - ref) - 0.0655) * 0.9053 + 0.08778; # pressure in hPa P = p_rel * ((((CALIB_COEFF[15] * p_rel + CALIB_COEFF[14]) * p_rel + CALIB_COEFF[13]) * p_rel + CALIB_COEFF[12]) * p_rel + CALIB_COEFF[11]) + CALIB_COEFF[10]; ref4 = MEAS_REF2 - ref; u1_rel = 1.0 / ((MEAS_U1 - ref) / ref4); u2_rel = 1.0 / ((MEAS_U2 - ref) / ref4); # humidity U1 = ( (u1_rel * CALIB_COEFF[43] + CALIB_COEFF[42]) * \ u1_rel + CALIB_COEFF[41]) * u1_rel + ALIB_COEFF[40]; U2 = ( (u2_rel * CALIB_COEFF[53] + CALIB_COEFF[52]) * \ u2_rel + CALIB_COEFF[51]) * u2_rel + CALIB_COEFF[50]; U = max(U1, U2) rt = (1.0 / (CALIB_COEFF[37] - 1.0) + 17.99418) * \ 0.079298 / (((MEAS_T - ref) / ref4) - 0.15791); # temperature °C T = (((( rt * CALIB_COEFF[35] + \ CALIB_COEFF[34]) * rt + \ CALIB_COEFF[33]) * rt + \ CALIB_COEFF[32]) * rt + \ CALIB_COEFF[31]) * rt + \ CALIB_COEFF[30]; ===== GPS subframe payload (0x67) ===== expected payload length: 122 ^ offset (B) ^ lenght (B) ^ content ^ description ^ | 0 | 4 | GPS_TIME (int32) | GPS time - ms from week start | | 4 | 2 | GPS_BLOB_0 | ???, 4*4 bits | | 6 | 8 | GPS_PRN | PRN for each tracked satelite | | 14 | 12 | GPS_STAT_1 | signal strength, fix status ... | | 26 | 96 | GPS_DATA_1 | doppler, pseudorange, ... | === GPS_PRN === List of pseudorange sequence number for each recieving satelite, 0 == no satelite. 12*5 bit - PRN number (x - unused ?) 11100000 x2222211 44433333 x5555544 77766666 x8888877 AAA99999 xBBBBBAA === GPS_STAT_1 === GPS satelite channel state. ^ offset (b) ^ length (b) ^ description ^ | 0 | 4 (int4) | signal strength or fix quallity, 0xf == NaN / no signal | | 4 | 1 | time fix - set to 1 when time is succesfully obtained from subframe | | 5 | 1 | pseudorange fix ??? - pseudorange fix is correlated to time ? | | 6 | 1 | pseudorange fix ??? (not corelated to time ?) | | 7 | 1 | signal tracking - some signal found at certain frequency | === GPS_DATA_1 === ^ offset (B) ^ length (B) ^ type ^ description ^ | 0 | 4 | int32/fract32 ? | value in range < -2e6, 0x1400000 ), pseudorange in metters?, 0x7FFFxxxx == NAN | | 4 | 3 | int24/fract24 ? | some number, might be signed, not sure, doppler shift? | | 7 | 1 | ??? | number, min/max: < -38, 39 > usually -5..10 | ===== RADAC / O3 (radiation and ozone measurement) (0x68) ===== expected payload length: 10 No usefull values available to decipher this frame, have someone something? ^ offset (B) ^ length (B) ^ description ^ | 0 | 10 | ??? | ussual content: 0x03 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 ===== Padding subframe (0xff) ===== expected payload length: 4 This type of frame probably identifies only padding * no CRC? * constant pattern of repeating (0x02 0x00) ? ===== Configuration and calibration ===== Calibration data are composed from fragments send in first subframe. Calibration data block is 512B long. Content is identical with data from EEPROM. - there should be somewhere date/time (GPS send only seconds offset from start of week) ^ offset (B) ^ lenght (B) ^ content ^ description ^ | 0 | 2 | ??? | ??? (checksum?) | | 2 | 2 | unit16 | downlik frequency: f = (400E6 + 10E3*value) Hz\\ upper limit is around 423MHz (value = 0x08FC) | | 4 | 2 | uint16 | always 0xffff - kill timmer ? | | 6 | 2 | int16 | always 0x0100 - set transmit power to full ? | | ??? | | 22 | 10 | string | probe ID (same as printed on conver, starts with 0x20 0x20) | | ??? | | 64 | 5*x | CALIB_COEFF | calibration coefficients table | ==== CALIB_COEFF ==== Consist of sequence of repeated fields with following structure: ^ offset (B) ^ lenght (B) ^ context ^ description ^ | 0 | 1 | uint8 | calibration constant index | | 4 | 4 | float32 | calibration constant value | Example of calibration data ^ coefficient index row/col (x) ^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ ^ 1x | -366.026 | -43.9063 | 393.234 | -131.314 | 25.6268 | -2.02341 | | 0.96 | ^ 2x | -803.34 | 363.815 | 317.784 | 127.429 | | | | 0.96 | ^ 3x | -187.802 | 89.6416 | -26.9122 | 9.15022 | -1.45707 | 0.0868068 | | 0.849488 | ^ 4x (humidity 1) | -1223.17 | 3548.18 | -2646.42 | 588.217 | | | | 0.96 | ^ 5x (humidity 2) | -1198.04 | 3497.31 | -2611.15 | 580.153 | | | | 0.96 | ^ 6x | 0.0318379 | 0.0374458 | -0.0433925 0.00630527 | ^ 7x | -0.000132316 | 0.000414854 | -0.000402439 6.31402e-05 | ^ 8x | -2.04505e-06 | 1.5662e-067.05777e-07 | ^ 11x | 0.5227 | -0.0284 | 0.000286 | 8.97e-07 | -1.26e-09 | ^ 12x | 1.07573 | -0.204 | 0.009009 | -5.83e-05 | -1.04e-06 | ^ 13x | 0.5227 | -0.0284 | 0.000286 | 8.97e-07 | -1.26e-09 | ^ 14x | 1.07573 | -0.204 | 0.009009 | -5.83e-05 | -1.04e-06 | ^ 15x | | 4.75029e-06-5.47494e-08 4.851e-10 -1.736e-12 | | | | | | 0.7 | ^ 16x | | | | | | | | 0.7 | * Coefficients at rows 1Nx are never chenge. ==== related links ==== * [[http://ams.confex.com/ams/pdfpapers/69226.pdf]]