[硅谷行报名]“脑电之翼”--牛刀小试(专注度点亮LDE)
本帖最后由 Genius 于 2016-11-30 16:24 编辑话说申请了机智云Gokit2开发板,咱就不能闲着啊 ,就要干活 ,就把最近的进度汇报下:lol。 因为项目的需要,就在网上购买了“意念方舟头带”,下面是他的自拍,好家伙小400块,不是特别贵吧,但是还是感觉有点贵,想想是学校给的项目经费,掏的是学校的腰包就不那么心疼了,但是国家支持咱们研究,咱就得好好干活啊,你说对吧,闲话少叙,开工:lol。
通过这一段时间的学习与实践,已经可以从“意念方舟头带”上获取数据,并进行处理分析,并在读取数据后做出相应动作,下面是具体说明。 硬件模块:Thinkgear模块机智云GoKit2 蓝牙HC-05模块 软件:MindViewer XCOM V2.0.exe Arduino 细节说明:之前一直再采集数据,但是数据一直不能正常读取到,后来通过与卖家的交流与沟通发现可能是头带上蓝牙模块的问题,经过改装最后终于解决了其中的问题,最后能从头带上获取数据了。 数据通过蓝牙传输,其中只要把蓝牙模块配置为主机,波特率设置为57600 接线方式如图
实物图:
至于头带吗 当然是要戴在头上的,因为本人忒丑,就让这个歪果仁来展示怎么佩戴吧 。
原始数据:
经过查阅thinkgear数据手册可以知道:TGAM大约每秒钟发送513个包, 发送送的包有小包和大包两种:小包的格式是AA AA 04 80 02 xxHigh xxLow xxCheckSum前面的AA AA 04 80 02 是不变的,后三个字节是一只变化的,xxHigh和xxLow组成了原始数据rawdata,xxCheckSum就是校验和。所以一个小包里面只包含了一个对开发者来 说有用的数据,那就是rawdata,可以说一个小包就是一个原始数据,大约每秒钟会有 512个原始数据。rawdata = (xxHigh << 8) | xxLow; if(rawdata > 32768){ rawdata=65536;
}现在原始数据就这么算出来了,但是在算原始数据之前,我们先应该检查校验和。sum = ((0x80 + 0x02 + xxHigh + xxLow)^ 0xFFFFFFFF) & 0xFF 就是把04后面的四个字节加起来,取反,再取低八位。 如果算出来的sum和xxCheckSum是相等的,那说明这个包是正确的,然后再去计算 rawdata,否则直接忽略这个包。丢包率在10%以下是不会对最后结果造成影响的。大包中是信号强度Signal,专注度Attention,放松度 Meditation,和8个EEG Power的值它们在在第513个这个大包里面,这个大包的格式是固定的。
AA 同步AA 同步20 是十进制的32,即有32个字节的payload,除掉20本身+两个AA同步+最后校验和 02 代表信号值Signal 33信号的值 83 代表EEG Power开始了 18 是十进制的24,说明EEG Power是由24个字节组成的,以下每三个字节为一组 0D Delta 1/3 CC Delta 2/3 64Delta 3/3 01 Theta 1/3 81 Theta 2/3 C5 Theta 3/3 01 LowAlpha 1/3 30 LowAlpha 2/3 36 LowAlpha 3/3 00 HighAlpha 1/3 BD HighAlpha 2/3 E4 HighAlpha 3/3 00 LowBeta 1/3 A9LowBeta 2/3 F0 LowBeta 3/3 00 Hi**eta 1/3 F4 Hi**eta 2/3 66 Hi**eta 3/3 00 LowGamma 1/3 FF LowGamma 2/3 F0 LowGamma 3/3 00 MiddleGamma 1/3 DB MiddleGamma 2/3 FB MiddleGamma 3/3 04 代表专注度Attention 00 Attention的值(0到100之间) 05 代表放松度Meditation 00 Meditation的值(0到100之间) D5 校验和 所得的数据可以在MindViewer中显示出来,其中包括attention,Meditation等数据 及最原始的α,β,γ等波形 。效果如图所示
通过对数据的识别与处理,我使用机智云提够的Gokit2开发板,对数据进行处理,计划做成专注度识别控制的LED显示。下面为arduino源程序 :<em>#define LED 13
#define BAUDRATE 57600
#define DEBUGOUTPUT 0
#define GREENLED1 3
#define GREENLED2 4
#define GREENLED3 5
#define YELLOWLED1 6
#define YELLOWLED2 7
#define YELLOWLED3 8
#define YELLOWLED4 9
#define REDLED1 10
#define REDLED2 11
#define REDLED3 12
#define powercontrol 10
// checksum variables
byte generatedChecksum = 0;
byte checksum = 0;
int payloadLength = 0;
byte payloadData = {0};
byte poorQuality = 0;
byte attention = 0;
byte meditation = 0;
// system variables
long lastReceivedPacket = 0;
boolean bigPacket = false;
void setup()
{
pinMode(GREENLED1, OUTPUT);
pinMode(GREENLED2, OUTPUT);
pinMode(GREENLED3, OUTPUT);
pinMode(YELLOWLED1, OUTPUT);
pinMode(YELLOWLED2, OUTPUT);
pinMode(YELLOWLED3, OUTPUT);
pinMode(YELLOWLED4, OUTPUT);
pinMode(REDLED1, OUTPUT);
pinMode(REDLED2, OUTPUT);
pinMode(REDLED3, OUTPUT);
pinMode(LED, OUTPUT);
Serial.begin(BAUDRATE); // USB
}
byte ReadOneByte()
{
int ByteRead;
while(!Serial.available());
ByteRead = Serial.read();
#if DEBUGOUTPUT
Serial.print((char)ByteRead);
#endif
return ByteRead;
}
void loop()
{
// Look for sync bytes
if(ReadOneByte() == 170)
{
if(ReadOneByte() == 170)
{
payloadLength = ReadOneByte();
if(payloadLength > 169) //Payload lengthcan not be greater than 169
return;
generatedChecksum = 0;
for(int i = 0; i < payloadLength; i++)
{
payloadData = ReadOneByte(); //Readpayload into memory
generatedChecksum += payloadData;
}
checksum = ReadOneByte(); //Read checksumbyte from stream
generatedChecksum = 255 -generatedChecksum; //Take one's compliment of generated checksum
if(checksum == generatedChecksum)
{
poorQuality = 200;
attention = 0;
meditation = 0;
for(int i = 0; i < payloadLength; i++)
{ // Parse the payload
switch (payloadData)
{
case 2:
i++;
poorQuality = payloadData;
bigPacket = true;
break;
case 4:
i++;
attention = payloadData;
break;
case 5:
i++;
meditation = payloadData;
break;
case 0x80:
i = i + 3;
break;
case 0x83:
i = i + 25;
break;
default:
break;
} // switch
} // for loop
#if !DEBUGOUTPUT
if(bigPacket)
{
if(poorQuality == 0)
digitalWrite(LED, HIGH);
else
digitalWrite(LED, LOW);
Serial.print("PoorQuality: ");
Serial.print(poorQuality, DEC);
Serial.print(" Attention: ");
Serial.print(attention, DEC);
Serial.print(" Time since last packet:");
Serial.print(millis() - lastReceivedPacket,DEC);
lastReceivedPacket = millis();
Serial.print("\n");
switch(attention / 10)
{
case 0:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, LOW);
digitalWrite(GREENLED3, LOW);
digitalWrite(YELLOWLED1, LOW);
digitalWrite(YELLOWLED2, LOW);
digitalWrite(YELLOWLED3, LOW);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 1:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, LOW);
digitalWrite(YELLOWLED1, LOW);
digitalWrite(YELLOWLED2, LOW);
digitalWrite(YELLOWLED3, LOW);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 2:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, LOW);
digitalWrite(YELLOWLED2, LOW);
digitalWrite(YELLOWLED3, LOW);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 3:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, LOW);
digitalWrite(YELLOWLED3, LOW);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 4:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, LOW);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 5:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, LOW);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 6:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, HIGH);
digitalWrite(REDLED1, LOW);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 7:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, HIGH);
digitalWrite(REDLED1, HIGH);
digitalWrite(REDLED2, LOW);
digitalWrite(REDLED3, LOW);
break;
case 8:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, HIGH);
digitalWrite(REDLED1, HIGH);
digitalWrite(REDLED2, HIGH);
digitalWrite(REDLED3, LOW);
break;
case 9:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, HIGH);
digitalWrite(REDLED1, HIGH);
digitalWrite(REDLED2, HIGH);
digitalWrite(REDLED3, HIGH);
break;
case 10:
digitalWrite(GREENLED1, HIGH);
digitalWrite(GREENLED2, HIGH);
digitalWrite(GREENLED3, HIGH);
digitalWrite(YELLOWLED1, HIGH);
digitalWrite(YELLOWLED2, HIGH);
digitalWrite(YELLOWLED3, HIGH);
digitalWrite(YELLOWLED4, HIGH);
digitalWrite(REDLED1, HIGH);
digitalWrite(REDLED2, HIGH);
digitalWrite(REDLED3, HIGH);
break;
}
}
#endif
bigPacket = false;
}
else {
// Checksum Error
} // end if else for checksum
} // end if read 0xAA byte
} // end if read 0xAA byte
}</em>
程序可实现通过把人的专注度以点亮LED多少展示出来 。
这个是视频展示的地址 : http://v.youku.com/v_show/id_XMTgzMTY0NjI2OA==.html 未来计划: 进一步研究数据,对数据进一步分析处理,深入研究thinkgear数据流,分析每一种波形的相应功能作用,提取关于健康方面有用信息,贴近脑点之翼的初衷,自己设计自己的app进行数据分析处理,尽可能的完成最初的设计理念。
赞一个:lol 期待楼主佳作
页:
[1]