Протокол обмена

Общие сведения

Головное устройстройство и все модули, входящие в проект, использют единый бинарный протокол. Общая структура пакета данного протокола представлена в Таблице ниже.

Байт # Поле Тип Значение Описание
0 start_byte uint8_t 0xAA Стартовый байт. Всегда равен 0xAA
1 id uint8_t 0xXX Идентификатор получателя пакета
2 type uint8_t 0xXX Тип пакета
... data ... ... Блок данных (зависит от типа пакета)
N checksum uint8_t 0xXX Котрольная сумма пакета - младший байт суммы всех байтов пакета

Для обнаружения начала пакета с данными, используется стартовый байт 0xAA. Следующим идёт байт с идентификатором получателя данного пакета, а затем байт с кодом типа пакета. Далее находятся данные, формат которых зависит от типа пакета.

Данные, для передачи которых требуется больше одного байта (uint16_t, uint32_t) передаются в формате little endian. Выбор данного формата позволяет обойтись без дополнительных конвертаций при использовании платформ x86, AVR и ARM.

В последнем байте пакета содержится контрольная сумма (checksum), вычисляемая как младший байт суммы всех байтов пакета.

Пакеты бывают двух типов:

  1. Пакет типа “Запрос
  2. Пакет типа “Ответ

Пара Запрос-Ответ формирует сущность “Команда”. Команды специфичны для каждого типа устройства, которое может работать в данной сети:

  • Головное устройство;
  • Датчик ФПГ;
  • Датчик двигательной активности;
  • Датчик температуры.

Описание общих полей

Поле “Стартовый байт” - start_byte

Стартовый байт всегда равен 0xAA и используется для определения начала пакета.

Поле “Идентификатор получателя пакета” - id

Идентификатор получателя пакета используется для определения адреса, куда передается запрос.

Идентификаторы получателя пакета приведены в таблице ниже.

Поле ID Получатель пакета
0x00 Компьютер (хост-устройство)
0x01 Головной модуль
0x10 Датчик температуры
0x30 Датчик двигательной активности
0x40 Датчик ФПГ

Поле “Тип пакета” - type

Тип пакета определяет данные, содержащиеся в пакете, которые либо запрашиваются в запросе, либо содержатся в ответе.

Типы пакетов приведены в таблице ниже.

Поле type Тип пакета
0x01 Пакет команды “Управление состоянием”
0x02 Пакет контроля регистров ADS1299
0xA0 Пакет с данными от одной ADS1299
0xA1 Пакет с данными от двух ADS1299
0xA3 Пакет с данными от четырех ADS1299
0xB0 Пакет с данными регистров ADS1299
0x10 Пакет с данными температуры
0x20 Пакет с данными о статусе аккумулятора
0x30 Пакет с углами Эйлера (данные IMU)
0x31 Пакет с кватернионом (данные IMU)
0x32 Пакет с сырыми данными (данные IMU)
0x40 Пакет с пульсом (данные ФПГ)
0x41 Пакет с сатурацией крови (данные ФПГ)
0x42 Пакет с сырыми данными (данные ФПГ)

Поле “Контрольная сумма пакета” - checksum

Контрольная сумма пакета - checksum определяется как младший байт суммы всех байтов пакета.

void NDK_CalcCheckSumForPacket(uint8_t * packet, uint8_t len)
{
    uint8_t checkSum = 0x00;
    for (uint8_t i = 0; i < len - 1; i++)
    {
        checkSum += *packet;
        packet++;
    }
    *packet = checkSum;
  }

Пример реализации вычисления контрольной суммы, где:

  • packet - указатель на массив с пакетом данных;
  • len - длина массива

В результате выполнения данной функции контрольная сумма записывается в последний байт пакета.

Формат запроса для команд

Для управления, получения данных и настройки параметров всех устройств, находящихся в одной сети, используется специфичные для них команды, но формат запроса имеет общую для всех команд структуру. В свою очередь, формат ответа команды специфичен только для нее.

Длина запроса - 8 байт.

Байт # Поле Тип Значение Описание
0 start_byte uint8_t 0xAA Стартовый байт. Всегда равен 0xAA
1 id uint8_t 0xXX Идентификатор получателя пакета
2 type uint8_t 0x01 Тип пакета - пакет команды “Управление состоянием”
3 action uint8_t 0xXX Действие, которое необходимо выполнить
4 param uint8_t 0xXX Параметр для действия
5 data uint8_t 0xXX Данные для действия
6 payload uint8_t 0xXX Дополнительные данные для действия
7 checksum uint8_t 0xXX Котрольная сумма пакета - младший байт суммы всех байтов пакета

Действия специфичны для каждого устройства.

Возможные значения полей param, data, payload, специфичны для отдельно взятых устройств и возможных действий.