Головное устройстройство и все модули, входящие в проект, использют единый бинарный протокол. Общая структура пакета данного протокола представлена в Таблице ниже.
Байт # | Поле | Тип | Значение | Описание |
---|---|---|---|---|
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), вычисляемая как младший байт суммы всех байтов пакета.
Пакеты бывают двух типов:
- Пакет типа "Запрос"
- Пакет типа "Ответ"
Пара Запрос-Ответ формирует сущность "Команда". Команды специфичны для каждого типа устройства, которое может работать в данной сети:
- Головное устройство;
- Датчик ФПГ;
- Датчик двигательной активности;
- Датчик температуры.
Стартовый байт всегда равен 0xAA и используется для определения начала пакета.
Идентификатор получателя пакета используется для определения адреса, куда передается запрос.
Идентификаторы получателя пакета приведены в таблице ниже.
Поле ID | Получатель пакета |
---|---|
0x00 | Компьютер (хост-устройство) |
0x01 | Головной модуль |
0x10 | Датчик температуры |
0x30 | Датчик двигательной активности |
0x40 | Датчик ФПГ |
Тип пакета определяет данные, содержащиеся в пакете, которые либо запрашиваются в запросе, либо содержатся в ответе.
Типы пакетов приведены в таблице ниже.
Поле type | Тип пакета |
---|---|
0x01 | Пакет команды "Управление состоянием" |
0x02 | Пакет контроля регистров ADS1299 |
0xA0 | Пакет с данными от одной ADS1299 |
0xA1 | Пакет с данными от двух ADS1299 |
0xA3 | Пакет с данными от четырех ADS1299 |
0xB0 | Пакет с данными регистров ADS1299 |
0x10 | Пакет с данными температуры |
0x20 | Пакет с данными о статусе аккумулятора |
0x30 | Пакет с углами Эйлера (данные IMU) |
0x31 | Пакет с кватернионом (данные IMU) |
0x32 | Пакет с сырыми данными (данные IMU) |
0x40 | Пакет с пульсом (данные ФПГ) |
0x41 | Пакет с сатурацией крови (данные ФПГ) |
0x42 | Пакет с сырыми данными (данные ФПГ) |
Контрольная сумма пакета - 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, специфичны для отдельно взятых устройств и возможных действий.