**"Парсинг протоколу CRSF з контролера польоту за допомогою Raspberry Pi для отримання телеметричних даних"**
#### Parsing CRSF Protocol from a Flight Controller with a Raspberry Pi for Telemetry Data

#### Компоненти:
- FPV дрон з контролером Betaflight F405 V3
- Raspberry Pi 5
- Дроти для підключення між контролером польоту та Raspberry Pi

#### Налаштування:
1. **Попередні налаштування:**
- Дрон FPV з контролером польоту Betaflight F405 V3.
- Raspberry Pi 5.
- Дроти для підключення між контролером польоту та Raspberry Pi.
- У вкладці приймача в Betaflight встановіть CRSF як протокол зв’язку.

2. **Підключення:**
- Встановіть SSH-з’єднання для Raspberry Pi для легшого доступу та кодування.
- Підключіть контролер польоту до Raspberry Pi через UART 2, що є тим самим місцем, де підключається приймач ELRS.


#### Структура протоколу CRSF:
1. **Формат пакету:**
- Всі пакети у форматі CRSF: `[sync][len][type][payload][crc8]` з максимальною загальною довжиною 64 байти.
- SYNC: Початок серійного пакету CRSF (0xC8).
- LEN: Довжина байтів, які слідують, включаючи тип, корисне навантаження та CRC.
- TYPE: Тип кадру CRSF.
- PAYLOAD: Дані, специфічні для типу кадру (максимум 60 байтів).
- CRC: CRC8 для забезпечення цілісності даних.
2. **Типи пакетів:**
- GPS (0x02): Позиція GPS, швидкість, висота.
- VARIO (0x07): Вертикальна швидкість.
- BATTERY_SENSOR (0x08): Напруга батареї, струм, залишок.
- ATTITUDE (0x1E): Нахил, крен, курс.
- FLIGHT_MODE (0x21): Режим польоту контролера.
#### Парсинг даних CRSF за допомогою Python:
1. **Python-скрипт:**
```python
import serial
import time
import argparse
from enum import IntEnum
CRSF_SYNC = 0xC8
class PacketsTypes(IntEnum):
GPS = 0x02
VARIO = 0x07
BATTERY_SENSOR = 0x08
ATTITUDE = 0x1E
FLIGHT_MODE = 0x21
def crc8_dvb_s2(crc, a):
crc ^= a
for _ in range(8):
if crc & 0x80:
crc = (crc << 1) ^ 0xD5
else:
crc = crc << 1
return crc & 0xFF
def crc8_data(data):
crc = 0
for a in data:
crc = crc8_dvb_s2(crc, a)
return crc
def crsf_validate_frame(frame):
return crc8_data(frame[2:-1]) == frame[-1]
def signed_byte(b):
return b - 256 if b >= 128 else b
def handleCrsfPacket(ptype, data):
if ptype == PacketsTypes.GPS:
lat = int.from_bytes(data[3:7], byteorder='big', signed=True)
lon = int.from_bytes(data[7:11], byteorder='big', signed=True)
gs = int.from_bytes(data[11:13], byteorder='big', signed=True)
hdg = int.from_bytes(data[13:15], byteorder='big', signed=True)
alt = int.from_bytes(data[15:17], byteorder='big', signed=True)
sats = data[17]
print(f"GPS: Pos={lat} {lon} GSpd={gs} Hdg={hdg} Alt={alt} Sats={sats}")
# Додайте обробку інших типів пакетів
parser = argparse.ArgumentParser()
parser.add_argument('-P', '--port', default='/dev/ttyAMA0')
parser.add_argument('-b', '--baud', default=420000)
args = parser.parse_args()
with serial.Serial(args.port, args.baud, timeout=0.1) as ser:
input_buffer = bytearray()
while True:
if ser.in_waiting > 0:
input_buffer.extend(ser.read(ser.in_waiting))
else:
time.sleep(0.01)
if len(input_buffer) > 2:
expected_len = input_buffer[1]
if expected_len > 64 or expected_len < 4:
input_buffer = []
elif len(input_buffer) >= expected_len + 2:
single_packet = input_buffer[:expected_len + 2]
input_buffer = input_buffer[expected_len + 2:]
if not crsf_validate_frame(single_packet):
packet = ' '.join(map(hex, single_packet))
print(f"CRC error: {packet}")
else:
handleCrsfPacket(single_packet[2], single_packet[3:])
```
2. **Виконання скрипта:**
- Запустіть скрипт на Raspberry Pi через SSH.
- Переконайтеся, що встановлено правильний серійний порт (`/dev/ttyAMA0`) та швидкість передачі даних (420000).
#### Висновок:
Дотримуючись цієї інструкції, ви зможете читати телеметричні дані з вашого FPV дрона за допомогою Raspberry Pi, що дозволить вам моніторити дані в реальному часі та вдосконалювати можливості дрона.