收藏官网首页
查看: 6439|回复: 2

[硅谷行报名]“脑电之翼”--牛刀小试(专注度点亮LDE)

4

主题

10

帖子

88

积分

注册会员

Rank: 2

积分
88
跳转到指定楼层
楼主
发表于 2016-11-23 14:25:05 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
注册成为机智云开发者,手机加虚拟设备快速开发
本帖最后由 Genius 于 2016-11-30 16:24 编辑

    话说申请了机智云gokit2开发板,咱就不能闲着啊 ,就要干活 就把最近的进度汇报下
    因为项目的需要,就在网上购买了“意念方舟头带”,下面是他的自拍,好家伙小400块,不是特别贵吧,但是还是感觉有点贵,想想是学校给的项目经费,掏的是学校的腰包就不那么心疼了,但是国家支持咱们研究,咱就得好好干活啊,你说对吧,闲话少叙,开工

                        
    通过这一段时间的学习与实践,已经可以从“意念方舟头带”上获取数据,并进行处理分析,并在读取数据后做出相应动作,下面是具体说明。
    硬件模块: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源程序 :
  1. <em>#define LED 13

  2. #define BAUDRATE 57600

  3. #define DEBUGOUTPUT 0

  4. #define GREENLED1 3

  5. #define GREENLED2 4

  6. #define GREENLED3 5

  7. #define YELLOWLED1 6

  8. #define YELLOWLED2 7

  9. #define YELLOWLED3 8

  10. #define YELLOWLED4 9

  11. #define REDLED1 10

  12. #define REDLED2 11

  13. #define REDLED3 12

  14. #define powercontrol 10

  15. // checksum variables

  16. byte generatedChecksum = 0;

  17. byte checksum = 0;

  18. int payloadLength = 0;

  19. byte payloadData[64] = {0};

  20. byte poorQuality = 0;

  21. byte attention = 0;

  22. byte meditation = 0;

  23. // system variables

  24. long lastReceivedPacket = 0;

  25. boolean bigPacket = false;



  26. void setup()

  27. {

  28. pinMode(GREENLED1, OUTPUT);

  29. pinMode(GREENLED2, OUTPUT);

  30. pinMode(GREENLED3, OUTPUT);

  31. pinMode(YELLOWLED1, OUTPUT);

  32. pinMode(YELLOWLED2, OUTPUT);

  33. pinMode(YELLOWLED3, OUTPUT);

  34. pinMode(YELLOWLED4, OUTPUT);

  35. pinMode(REDLED1, OUTPUT);

  36. pinMode(REDLED2, OUTPUT);

  37. pinMode(REDLED3, OUTPUT);

  38. pinMode(LED, OUTPUT);

  39. Serial.begin(BAUDRATE); // USB

  40. }



  41. byte ReadOneByte()

  42. {

  43. int ByteRead;

  44. while(!Serial.available());

  45. ByteRead = Serial.read();

  46. #if DEBUGOUTPUT

  47. Serial.print((char)ByteRead);

  48. #endif

  49. return ByteRead;

  50. }



  51. void loop()

  52. {

  53. // Look for sync bytes

  54. if(ReadOneByte() == 170)

  55. {

  56. if(ReadOneByte() == 170)

  57. {

  58. payloadLength = ReadOneByte();

  59. if(payloadLength > 169) //Payload lengthcan not be greater than 169

  60. return;

  61. generatedChecksum = 0;

  62. for(int i = 0; i < payloadLength; i++)

  63. {

  64. payloadData = ReadOneByte(); //Readpayload into memory

  65. generatedChecksum += payloadData;

  66. }

  67. checksum = ReadOneByte(); //Read checksumbyte from stream

  68. generatedChecksum = 255 -generatedChecksum; //Take one's compliment of generated checksum

  69. if(checksum == generatedChecksum)

  70. {

  71. poorQuality = 200;

  72. attention = 0;

  73. meditation = 0;

  74. for(int i = 0; i < payloadLength; i++)

  75. { // Parse the payload

  76. switch (payloadData)

  77. {

  78. case 2:

  79. i++;

  80. poorQuality = payloadData;

  81. bigPacket = true;

  82. break;

  83. case 4:

  84. i++;

  85. attention = payloadData;

  86. break;

  87. case 5:

  88. i++;

  89. meditation = payloadData;

  90. break;

  91. case 0x80:

  92. i = i + 3;

  93. break;

  94. case 0x83:

  95. i = i + 25;

  96. break;

  97. default:

  98. break;

  99. } // switch

  100. } // for loop

  101. #if !DEBUGOUTPUT

  102. if(bigPacket)

  103. {

  104. if(poorQuality == 0)

  105. digitalWrite(LED, HIGH);

  106. else

  107. digitalWrite(LED, LOW);

  108. Serial.print("PoorQuality: ");

  109. Serial.print(poorQuality, DEC);

  110. Serial.print(" Attention: ");

  111. Serial.print(attention, DEC);

  112. Serial.print(" Time since last packet:");

  113. Serial.print(millis() - lastReceivedPacket,DEC);

  114. lastReceivedPacket = millis();

  115. Serial.print("\n");

  116. switch(attention / 10)

  117. {

  118. case 0:

  119. digitalWrite(GREENLED1, HIGH);

  120. digitalWrite(GREENLED2, LOW);

  121. digitalWrite(GREENLED3, LOW);

  122. digitalWrite(YELLOWLED1, LOW);

  123. digitalWrite(YELLOWLED2, LOW);

  124. digitalWrite(YELLOWLED3, LOW);

  125. digitalWrite(YELLOWLED4, LOW);

  126. digitalWrite(REDLED1, LOW);

  127. digitalWrite(REDLED2, LOW);

  128. digitalWrite(REDLED3, LOW);

  129. break;

  130. case 1:

  131. digitalWrite(GREENLED1, HIGH);

  132. digitalWrite(GREENLED2, HIGH);

  133. digitalWrite(GREENLED3, LOW);

  134. digitalWrite(YELLOWLED1, LOW);

  135. digitalWrite(YELLOWLED2, LOW);

  136. digitalWrite(YELLOWLED3, LOW);

  137. digitalWrite(YELLOWLED4, LOW);

  138. digitalWrite(REDLED1, LOW);

  139. digitalWrite(REDLED2, LOW);

  140. digitalWrite(REDLED3, LOW);

  141. break;

  142. case 2:

  143. digitalWrite(GREENLED1, HIGH);

  144. digitalWrite(GREENLED2, HIGH);

  145. digitalWrite(GREENLED3, HIGH);

  146. digitalWrite(YELLOWLED1, LOW);

  147. digitalWrite(YELLOWLED2, LOW);

  148. digitalWrite(YELLOWLED3, LOW);

  149. digitalWrite(YELLOWLED4, LOW);

  150. digitalWrite(REDLED1, LOW);

  151. digitalWrite(REDLED2, LOW);

  152. digitalWrite(REDLED3, LOW);

  153. break;

  154. case 3:

  155. digitalWrite(GREENLED1, HIGH);

  156. digitalWrite(GREENLED2, HIGH);

  157. digitalWrite(GREENLED3, HIGH);

  158. digitalWrite(YELLOWLED1, HIGH);

  159. digitalWrite(YELLOWLED2, LOW);

  160. digitalWrite(YELLOWLED3, LOW);

  161. digitalWrite(YELLOWLED4, LOW);

  162. digitalWrite(REDLED1, LOW);

  163. digitalWrite(REDLED2, LOW);

  164. digitalWrite(REDLED3, LOW);

  165. break;

  166. case 4:

  167. digitalWrite(GREENLED1, HIGH);

  168. digitalWrite(GREENLED2, HIGH);

  169. digitalWrite(GREENLED3, HIGH);

  170. digitalWrite(YELLOWLED1, HIGH);

  171. digitalWrite(YELLOWLED2, HIGH);

  172. digitalWrite(YELLOWLED3, LOW);

  173. digitalWrite(YELLOWLED4, LOW);

  174. digitalWrite(REDLED1, LOW);

  175. digitalWrite(REDLED2, LOW);

  176. digitalWrite(REDLED3, LOW);

  177. break;

  178. case 5:

  179. digitalWrite(GREENLED1, HIGH);

  180. digitalWrite(GREENLED2, HIGH);

  181. digitalWrite(GREENLED3, HIGH);

  182. digitalWrite(YELLOWLED1, HIGH);

  183. digitalWrite(YELLOWLED2, HIGH);

  184. digitalWrite(YELLOWLED3, HIGH);

  185. digitalWrite(YELLOWLED4, LOW);

  186. digitalWrite(REDLED1, LOW);

  187. digitalWrite(REDLED2, LOW);

  188. digitalWrite(REDLED3, LOW);

  189. break;

  190. case 6:

  191. digitalWrite(GREENLED1, HIGH);

  192. digitalWrite(GREENLED2, HIGH);

  193. digitalWrite(GREENLED3, HIGH);

  194. digitalWrite(YELLOWLED1, HIGH);

  195. digitalWrite(YELLOWLED2, HIGH);

  196. digitalWrite(YELLOWLED3, HIGH);

  197. digitalWrite(YELLOWLED4, HIGH);

  198. digitalWrite(REDLED1, LOW);

  199. digitalWrite(REDLED2, LOW);

  200. digitalWrite(REDLED3, LOW);

  201. break;

  202. case 7:

  203. digitalWrite(GREENLED1, HIGH);

  204. digitalWrite(GREENLED2, HIGH);

  205. digitalWrite(GREENLED3, HIGH);

  206. digitalWrite(YELLOWLED1, HIGH);

  207. digitalWrite(YELLOWLED2, HIGH);

  208. digitalWrite(YELLOWLED3, HIGH);

  209. digitalWrite(YELLOWLED4, HIGH);

  210. digitalWrite(REDLED1, HIGH);

  211. digitalWrite(REDLED2, LOW);

  212. digitalWrite(REDLED3, LOW);

  213. break;

  214. case 8:

  215. digitalWrite(GREENLED1, HIGH);

  216. digitalWrite(GREENLED2, HIGH);

  217. digitalWrite(GREENLED3, HIGH);

  218. digitalWrite(YELLOWLED1, HIGH);

  219. digitalWrite(YELLOWLED2, HIGH);

  220. digitalWrite(YELLOWLED3, HIGH);

  221. digitalWrite(YELLOWLED4, HIGH);

  222. digitalWrite(REDLED1, HIGH);

  223. digitalWrite(REDLED2, HIGH);

  224. digitalWrite(REDLED3, LOW);

  225. break;

  226. case 9:

  227. digitalWrite(GREENLED1, HIGH);

  228. digitalWrite(GREENLED2, HIGH);

  229. digitalWrite(GREENLED3, HIGH);

  230. digitalWrite(YELLOWLED1, HIGH);

  231. digitalWrite(YELLOWLED2, HIGH);

  232. digitalWrite(YELLOWLED3, HIGH);

  233. digitalWrite(YELLOWLED4, HIGH);

  234. digitalWrite(REDLED1, HIGH);

  235. digitalWrite(REDLED2, HIGH);

  236. digitalWrite(REDLED3, HIGH);

  237. break;

  238. case 10:

  239. digitalWrite(GREENLED1, HIGH);

  240. digitalWrite(GREENLED2, HIGH);

  241. digitalWrite(GREENLED3, HIGH);

  242. digitalWrite(YELLOWLED1, HIGH);

  243. digitalWrite(YELLOWLED2, HIGH);

  244. digitalWrite(YELLOWLED3, HIGH);

  245. digitalWrite(YELLOWLED4, HIGH);

  246. digitalWrite(REDLED1, HIGH);

  247. digitalWrite(REDLED2, HIGH);

  248. digitalWrite(REDLED3, HIGH);

  249. break;

  250. }

  251. }

  252. #endif

  253. bigPacket = false;

  254. }

  255. else {

  256. // Checksum Error

  257. } // end if else for checksum

  258. } // end if read 0xAA byte

  259. } // end if read 0xAA byte

  260. }</em>
复制代码

程序可实现通过把人的专注度以点亮LED多少展示出来 。


     这个是视频展示的地址 :   http://v.youku.com/v_show/id_XMTgzMTY0NjI2OA==.html
    未来计划:
    进一步研究数据,对数据进一步分析处理,深入研究thinkgear数据流,分析每一种波形的相应功能作用,提取关于健康方面有用信息,贴近脑点之翼的初衷,自己设计自己的app进行数据分析处理,尽可能的完成最初的设计理念。











99

主题

123

帖子

1695

积分

金牌会员

Rank: 6Rank: 6

积分
1695
板凳
发表于 2016-11-28 23:44:33 | 只看该作者
期待楼主佳作
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

加入Q群 返回顶部

版权与免责声明 © 2006-2024 Gizwits IoT Technology Co., Ltd. ( 粤ICP备11090211号 )

快速回复 返回顶部 返回列表