Spolehlivý přenos dat je v projektu CanSat klíčový. Pracujeme s omezeným výkonem a krátkým časem letu, proto jsme navrhli vlastní komunikační protokol postavený na UART, binárních packetách a 16bitové CRC kontrole.
V tomto článku se zaměříme na client side telemetrie, tedy část systému běžící na Raspberry Pi, která zajišťuje:
→ příjem telemetrických paketů z mikrokontroleru
→ kontrolu integrity přijatých dat
→ lokální ukládání telemetrie na SD kartu
→ synchronizaci telemetrie s kamerovým záznamem
Navíc si detailně ukážeme praktickou implementaci ukládání dat, která je odolná vůči chybám i náhlému výpadku systému.
Architektura systému
Datový tok:
senzory → microcontroler → Raspberry Pi
↘
Rádio → Pozemní stanice
Mikrokontroler:
→ sbírá data ze senzorů
→ vytváří binární packety
→ odesílá telemetrii na zem
→ paralelně posílá data na Raspberry Pi
Raspberry Pi:
→ přijímá data přes UART
→ kontroluje CRC
→ ukládá telemetrii na SD kartu
→ zaznamenává video
Tím vzniká plná redundance dat.
Struktura telemetrické packety
Používáme binární formát:
| Byte | Obsah |
| n | Datová část |
| n+1, n+2 | CRC16 |
| poslední | END (0x55, 0xFF) |
Výhody:
→ menší velikost
→ rychlejší přenos
→ jednoduché parsování
→ ochrana integrity
Zpracování dat na Raspberry Pi
Pipeline na client side:
- čtení UART streamu
- detekce packetu (END sekvence)
- parsování dat
- výpočet CRC
- validace packetu
- uložení na SD kartu
Ukládání telemetrie – praktický přístup
Místo složitých formátů používáme jednoduchý textový log, který je:
→ snadno čitelný
→ odolný
→ rychlý na zápis
Formát záznamu
Každý packet = jeden řádek:
[valid] <timestamp_ms> <UTC 0 time> <data>
Nevalidní packet:
[corrupt] <timestamp_ms>
Příklad:
[valid] 171085 TEMP:23.4 PRESS:101325[corrupt] 171086[valid] 171087 TEMP:23.5 PRESS:101300

Časová synchronizace
Aby šla telemetrie přesně spárovat s videem:
→ Raspberry Pi běží v UTC (časové pásmo 0)
→ čas je synchronizovaný (např. NTP před startem)
→ ukládáme timestamp v milisekundách/100
Python:
import timetimestamp_ms = int(time.time() * 10)
Díky tomu lze:
→ přesně mapovat data na jednotlivé snímky videa
→ analyzovat průběh letu v čase
Validace dat
Každý packet prochází kontrolou:
→ CRC16 výpočet
→ porovnání s přijatým CRC
Pokud kontrola selže:
→ packet se NEparsuje
→ uloží se pouze [corrupt]
To je důležité, protože:
→ neztratíme časovou osu
→ víme, kde došlo k chybě
→ neukládáme špatná data
Kritická část: bezpečný zápis na SD kartu
Největší riziko během mise:
→ náhlý výpadek napájení
→ crash Raspberry Pi
Proto používáme:
→ flush po každém packetu

To znamená:
→ každý řádek je okamžitě zapsán na disk
→ ztráta dat maximálně 1 packet
Implementace:
with open("telemetry.txt", "a") as f: while True: packet = read_uart_packet() timestamp = int(time.time() * 1000) if is_valid(packet): parsed = parse_packet(packet) line = f"{timestamp} {parsed}\n" else: line = f"{timestamp} [corrupt]\n" f.write(line) f.flush()
Proč je flush tak důležitý
Bez flush:
→ data zůstávají v RAM
→ při pádu systému se ztratí
S flush:
→ data jsou fyzicky na SD kartě
→ log přežije i tvrdý restart
Trade-off:
→ mírně vyšší zátěž SD karty
→ nižší výkon
V CanSat scénáři je ale spolehlivost důležitější než výkon.
Klíčové vlastnosti řešení:
→ binární packety s CRC16
→ jednoduchý textový log
→ timestamp v ms/100
→ [corrupt] pro nevalidní data
→ flush po každém packetu
Tento přístup zajišťuje, že i při selhání rádia nebo systému máme kompletní a časově přesný záznam celé mise.
