Материал: Аппаратура для электроэнцефалографических исследований. Журавлев Д.В

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

всех 4-х каналов последовательнои входа REF в конце каждой серии, пока не получит команду “Z”. Эти значения “Packet ID” перечислены в таблице ниже. Данные импеданса отправляются в виде строки ASCII, представляющей измеренное значение в омах (табл. 4.2).

 

 

 

Таблица 4.2

 

Значения поля Packet ID

Десятичный

Байт ID

Тип

 

 

идентификатор байта

HEX

данных

Описание

 

 

 

 

 

 

0

00

24bit

Данные без сжатия

 

 

 

 

 

 

1-100

0x01-0x64

18bit

18-битное сжатие с акселерометром

 

 

 

 

 

 

 

 

 

19-битное сжатие без

 

101-200

0x65-0xC8

19bit

акселерометра

 

 

 

 

 

 

201

0xC9

impedance

Канал импеданса 1

 

 

 

 

 

 

202

0xCA

impedance

Канал импеданса 2

 

 

 

 

 

 

203

0xCB

impedance

Канал Импеданса 3

 

 

 

 

 

 

204

0xCC

impedance

Канал импеданса 4

 

 

 

 

 

 

205

0xCD

impedance

Ссылка на канал импеданса

 

 

 

 

 

 

206

0xCE

multi

Часть сообщения ASCII

 

 

 

 

 

 

207

0xCF

multiStop

Конец сообщения ASCII

 

 

 

 

 

 

4.6.7. Вывод протокола

Плата Ganglion иногда отправляет подробные данные через соединение BLE. В этом случае Ganglion может отправлять от 1 до многих пакетов подробных данных в формате ASCII. “Packet ID” для ASCII сообщений проинформирует компьютер, если сообщение не будет сделано и он должен ожидать другой пакет “206” или “0xCE”. Когда Ganglion отправляет последний пакет сообщений ASCII, то “Packet ID” будет иметь значение “207” или “0xCF”.

100

4.6.8. Примеры интерпретации данных с платы Ganglion

При передаче 24-х битных необработанных данных без сжатия они всегда сохраняются, если приходит “Byte ID” равный “0”.

4.6.8.1. 18-битное дельта-сжатие

Далее рассмотрим практический пример передачи 18-битных данных на основе автоматизированного теста, используемого в драйвере Ganglion NodeJS, для объяснения стратегии 18-ти разрядного дельта-сжатия.

let buffer = new Buffer(

[

0b00000001, // 0 0b00000000, // 1 0b00000000, // 2 0b00000000, // 3 0b00000000, // 4 0b00100000, // 5 0b00000000, // 6 0b00101000, // 7 0b00000000, // 8 0b00000100, // 9 0b10000000, // 10 0b00000000, // 11 0b10111100, // 12 0b00000000, // 13 0b00000111, // 14 0b00000000, // 15 0b00101000, // 16 0b11000000, // 17 0b00001010, // 18 0b00001110 // 19 ]);

let expectedValue = [[0, 2, 10, 4], [131074, 245760, 114698, 49162]];

Первый сжатый канал в первой выборке будет получен из первых двух байтов плюс первые два бита третьего байта: канал 1 - выборка 1 - “0b000000000000000000” или “0” в десятичном формате.

Второй сжатый канал в первой выборке будет получен из последних шести битов третьего байта, всех четырех байтов и первых четырех битов пятого байта: канал 2 - выборка 1 “0b000000000000000010” или “2” в

десятичном формате.

Третья сжатая выборка во второй выборке будет получена из последних четырех битов 14-го байта, всех битов 15-го байта и первых шести битов 16-го байта: канал 3 - выборка 2 “0b011100000000001010” или “114698” в десятичном виде.

Чтобы получить данные 8-битного акселерометра с частотой 10 Гц из 18битных пакетов, необходимо задать модуль 10-байтового идентификатора “Byte

101

ID”: если (идентификатор байта “% 10”) равен 1, 2 и 3, то необходимо брать последний байт, чтобы получить значения X, Y и Z.

В вышеприведенном примере байт 19 - это последний байт, он имеет значение 14, или “0x0E”, которое будет сохранено как значение оси X для этого образца акселерометра.

Номер образца для образца 1 будет “1” и номер образца для образца 2 будет “2”. Если идентификатор байта был 47, а номер образца был “1”, то получим номер 93, а номер образца 2 - 94.

Далее рассмотрим отрицательные значения.

let buffer = new Buffer(

[

0b00000001, // 0 0b11111111, // 1 0b11111111, // 2 0b01111111, // 3 0b11111111, // 4 0b10111111, // 5 0b11111111, // 6 0b11100111, // 7 0b11111111, // 8 0b11110101, // 9 0b00000000, // 10 0b00000001, // 11 0b01001111, // 12 0b10001110, // 13 0b00110000, // 14 0b00000000, // 15 0b00011111, // 16 0b11110000, // 17 0b00000001 // 18 ]);

let expectedValue = [[-3, -5, -7, -11], [-262139, -198429, -262137, -4095]];

Первый сжатый канал в первой выборке будет получен из первых двух байтов плюс первые два бита третьего байта для образования общего количества 19 бит: канал 1 - выборка 1 – “0b111111111111111101” – или “3” в

десятичном формате.

Второй сжатый канал в выборке два будет получен из последних шести битов 12-го байта, целого байта 13 и первых четырех битов из байта 14: канал 2 - выборка 2 – “0b001111100011100011” или “198429” в десятичном формате. “MSB” будет иметь значение “0”, но это будет отрицательное число, потому что значение “LSB” будет “1”.

4.6.8.2. 19-битное дельта-сжатие

Для объяснения стратегии 19-разрядного дельта-сжатия рассмотрим практический пример на основе автоматизированного теста, используемого в драйвере Ganglion NodeJS.

102

let buffer = new Buffer(

[

0b01100101, // 0 0b00000000, // 1 0b00000000, // 2 0b00000000, // 3 0b00000000, // 4 0b00001000, // 5 0b00000000, // 6 0b00000101, // 7 0b00000000, // 8 0b00000000, // 9 0b01001000, // 10 0b00000000, // 11 0b00001001, // 12 0b11110000, // 13 0b00000001, // 14 0b10110000, // 15 0b00000000, // 16 0b00110000, // 17 0b00000000, // 18 0b00001000 // 19 ]);

let expectedValue = [[0, 2, 10, 4], [262148, 507910, 393222, 8]];

Первый сжатый канал в первой выборке будет получен из первых двух байтов плюс первые три бита третьего байта для получения общего количества 19 битов: канал 1 - выборка 1 – “0b0000000000000000000” или “0” в десятичном формате.

Второй сжатый канал во второй выборке будет получен из последнего бита в байте №12, всех байтов №13 и №14 и только первых двух битов байта №15: канал 2 - выборка 2 – “0b1111100000000000110” или “507910” в десятичном формате. “MSB” будет иметь значение “1”, но это положительное число, потому что “LSB” будет иметь значение “0”.

Номер образца для образца 1 равен “1” и номер образца для образца 2 будет “2”. Если идентификатор байта был “104”, то номер выборки 1 будет “7а”, а номер выборки 2 будет “8”.

Далее рассмотрим отрицательные значения.

let buffer = new Buffer(

[

0b01100101, // 0 0b11111111, // 1 0b11111111, // 2 0b10111111, // 3 0b11111111, // 4 0b11101111, // 5 0b11111111, // 6 0b11111100, // 7 0b11111111, // 8 0b11111111, // 9 0b01011000, // 10 0b00000000, // 11 0b00001011, // 12 0b00111110, // 13

103

0b00111000, // 14 0b11100000, // 15 0b00000000, // 16 0b00111111, // 17 0b11110000, // 18 0b00000001 // 19 ]);

let expectedValue = [[-3, -5, -7, -11], [-262139, -198429, -262137, -4095]];

Обращение к LSB происходит для 19-битного числа. Первый сжатый канал в выборке №1 будет получен из первых двух байтов плюс первые три бита третьего байта: канал 1 - выборка 1 “0b1111111111111111101” или “3” в десятичном формате.

Четвертый сжатый канал в выборке №2 будет получен из последних трех битов байта №17 и всех байтов №18 и №19: канал 4 - выборка 2 “0b001111100011100011” или “198429” в десятичном формате. “MSB” будет иметь значение “0”, но это отрицательное число, так как “LSB” будет иметь значение “1”.

Значения импеданса отправляются с байтовыми идентификаторами в формате ASCII, заканчивающемся на “Z”. Разбор необходимо проводить от байта №1, пока не встретится “Z”.

4.6.8.3. 18-битные данные со знаком

Сжатые значения регистрируемых данных ЭЭГ передаются в виде 18разрядного целого числа со знаком, что немного необычно. Но используется этот числовой формат потому, что это родной формат, используемый A/D- чипом, который является основным на плате Ganglion. Чтобы преобразовать этот необычный числовой формат в более стандартное 32-разрядное целое число со знаком, можно взять некоторые идеи из примера кода NodeJS (он же JavaScript):

/**

*Converts a special ganglion 18 bit compressed number

*The compressions uses the LSB, bit 1, as the signed bit, instead of using

*the MSB. Therefore you must not look to the MSB for a sign extension, one

*must look to the LSB, and the same rules applies, if it's a 1, then it's a

*negative and if it's 0 then it's a positive number.

*@param threeByteBuffer {Buffer}

*A 3-byte buffer with only 18 bits of actual data.

*@return {number} A signed integer.

*/

function convert18bitAsInt32 (threeByteBuffer) { let prefix = 0;

if (threeByteBuffer[2] & 0x01 > 0) { // console.log('\t\tNegative number') prefix = 0b11111111111111;

}

return (prefix << 18) | (threeByteBuffer[0] << 16) | (threeByteBuffer[1] << 8) | threeByteBuffer[2];

}

104

Источник: https://studfile.net/preview/16566241/