**"Парсинг протоколу CRSF з контролера польоту за допомогою Raspberry Pi для отримання телеметричних даних"**

**"Парсинг протоколу 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, що дозволить вам моніторити дані в реальному часі та вдосконалювати можливості дрона.

Report Page