-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
115 lines (96 loc) · 4.03 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
var SYNC_BYTE = 0xaa,
EXCODE_BYTE = 0x55,
POOR_SIGNAL_BYTE = 0x02,
ATTENTION_BYTE = 0x04,
MEDITATION_BYTE = 0x05,
BLINK_STRENGTH_BYTE = 0x16,
RAW_EEG_BYTE = 0x80,
ASIC_EEG_BYTE = 0x83;
var rawEegTimeSent = (new Date()).getTime();
var SerialPort = require("serialport").SerialPort;
module.exports = new SerialPort("/dev/tty.MindWaveMobile-DevA", {
baudrate: 57600,
parser: function(emitter, rawData) {
var payLoadLength, packet, checkSum, checkSumExpected, parsedData, rawEeg, eegTick,
payLoad, extendedCodeLevel, code, bytesParsed, dataLength, dataValue;
for (var i = 0, l = rawData.length; i < l; i++) {
if (typeof rawData[i] == 'undefined' || typeof rawData[i+1] == 'undefined' || typeof rawData[i+2] == 'undefined') {
return;
}
payLoadLength = parseInt(rawData[i+2],10);
if (rawData[i] == SYNC_BYTE && rawData[i+1] == SYNC_BYTE && payLoadLength < 170) {
packet = rawData.slice(i, i + payLoadLength + 4);
checkSumExpected = packet[packet.length - 1];
payLoad = packet.slice(3, -1);
checkSum = 0;
payLoad = payLoad.toJSON();
payLoad.forEach(function(e) { checkSum += e });
checkSum &= 0xFF;
checkSum = ~checkSum & 0xFF;
if (checkSum == checkSumExpected) {
bytesParsed = 0;
parsedData = {};
while (bytesParsed < payLoadLength) {
extendedCodeLevel = 0;
while( payLoad[bytesParsed] == EXCODE_BYTE ) {
extendedCodeLevel++; bytesParsed++;
}
code = payLoad[bytesParsed++];
dataLength = code & 0x80 ? payLoad[bytesParsed++] : 1;
if (dataLength == 1) {
dataValue = payLoad[bytesParsed];
}
else {
dataValue = [];
for(var j = 0; j < dataLength; j++ ) {
dataValue.push(payLoad[bytesParsed + j]);
}
}
bytesParsed += dataLength;
if (extendedCodeLevel == 0) {
switch (code) {
case POOR_SIGNAL_BYTE:
parsedData.poorSignal = dataValue;
break;
case ATTENTION_BYTE:
parsedData.attention = dataValue;
break;
case MEDITATION_BYTE:
parsedData.meditation = dataValue;
break;
case BLINK_STRENGTH_BYTE:
parsedData.blinkStrength = dataValue;
break;
case RAW_EEG_BYTE:
eegTick = (new Date()).getTime()
if (eegTick - rawEegTimeSent > 200){
rawEegTimeSent = eegTick;
rawEeg = dataValue[0] * 256 + dataValue[1];
rawEeg = rawEeg >=32768 ? rawEeg - 65536 : rawEeg;
parsedData.rawEeg = rawEeg;
}
break;
case ASIC_EEG_BYTE:
parsedData.delta = dataValue[0] * 256 * 256 + dataValue[1] * 256 + dataValue[2];
parsedData.theta = dataValue[3] * 256 * 256 + dataValue[4] * 256 + dataValue[5];
parsedData.lowAlpha = dataValue[6] * 256 * 256 + dataValue[7] * 256 + dataValue[8];
parsedData.highAlpha = dataValue[9] * 256 * 256 + dataValue[10] * 256 + dataValue[11];
parsedData.lowBeta = dataValue[12] * 256 * 256 + dataValue[13] * 256 + dataValue[14];
parsedData.highBeta = dataValue[15] * 256 * 256 + dataValue[16] * 256 + dataValue[17];
parsedData.lowGamma = dataValue[18] * 256 * 256 + dataValue[19] * 256 + dataValue[20];
parsedData.highGamma = dataValue[21] * 256 * 256 + dataValue[22] * 256 + dataValue[23];
break;
default:
break;
}
}
}
if (Object.keys(parsedData).length) {
emitter.emit('data', parsedData);
}
}
i = i + payLoadLength + 3;
}
}
}
}, false);