16:25 2013/1/19
兩種耳機的區別:主要是數據傳輸方式不一樣。MindSet是通過藍牙發送,MindWave是通過射頻發送。
兩種開發包的區別:mrt(mind research tool),主要是研究用;mdt(mind develop tool),主要是開發用。
13:31 2013/1/20
其中一種用途,用來根據興奮狀態檢測出是否處於睡眠狀態,這樣就可以在睡眠時減少數據采樣速度。
13:52 2013/1/20
終於明白了,原來MRT是要錢的,而且要花500美元,坑爹啊!
13:57 2013/1/20
MDT各種工具的用途:
ThinkGear Connector:提供了一個連接軟件,獲取數據的話,只需要通過socket來獲取就可以了。可以把連接和控制分離,但是要自己去獲取socket數據並解析。
ThinkGear Communications Driver:把那些API都給你了,目前看來是最簡單的了。
ThinkGear Communications Protocol:最底層的通信協議。一般不用。
14:19 2013/1/20
ThinkGear Connector的Socket地址:127.0.0.1:13854;TCP協議
14:28 2013/1/20
最后還是決定使用ThinkGear Communications Driver來做了,使用C語言版本來做最簡單,因為原本就是先用C開發的。了解API后,可以移植到java上,使用JNI調用dll就可以了。
20:13 2013/1/22
TODO:為什么使用package,就無法調用JNI?
/////////////////////////////////////////////////////////////////////////////////////////////
C語言版本使用手冊:
1、新建工程后,將ThinkGear.h、ThinkGear.lib、thinkgear_testapp.cpp放入工程;
2、編譯后,將thinkgear.dll文件放入exe所在文件夾;
3、將耳機和接收器連接好,啟動程序,指示燈應該由紅變藍。
主程序:
#include <stdlib.h> #include <stdio.h> #include "thinkgear.h" int main() { // 獲取一個連接句柄 int connectionId = TG_GetNewConnectionId(); if( connectionId < 0 ) { printf( "ERROR: TG_GetNewConnectionId() returned %d.\n", connectionId ); exit( EXIT_FAILURE ); } else printf( "SUCCESS: TG_GetNewConnectionId() returned %d.\n", connectionId ); char *comPortName = "\\\\.\\COM3"; // 注意COM名要和電腦的連接相對應 // TG_BAUD_*可以設置波特率,TG_STREAM_PACKETS是數據格式 int errCode = TG_Connect( connectionId, comPortName, TG_BAUD_9600, TG_STREAM_PACKETS ); if( errCode < 0 ) { printf( "ERROR: TG_Connect() returned %d.\n", errCode ); exit( EXIT_FAILURE ); } else printf( "SUCCESS: TG_Connect() returned %d.\n", errCode ); while( 1 ) { errCode = TG_ReadPackets( connectionId, 1 ); //讀取數據包 if( errCode==1 ) { if( TG_GetValueStatus(connectionId, TG_DATA_ATTENTION) != 0 ) { //讀取attention數據 printf( "New attention value: %f\n", TG_GetValue(connectionId, TG_DATA_ATTENTION) ); } } } TG_FreeConnection( connectionId ); // 釋放句柄 return( EXIT_SUCCESS ); }
API大概說明:
TG_GetNewConnectionId() : 獲取一個連接句柄,在后面都要用到
TG_FreeConnection() : 把句柄釋放掉
TG_SetStreamLog() : 設置流日志
TG_SetDataLog() : 在把流轉換為數據時,記錄日志
TG_Connect() : 連接
TG_Disconnect() : 取消連接,調用后一些依賴函數就不可用
TG_ReadPackets() : 讀取若干個packet,是讀取最新的嗎?
TG_GetValueStatus() : 判斷數據是否更新過
TG_GetValue() : 讀取數據,為主要功能
TG_SetBaudrate() : 運行中改變波特率
TG_SetDataFormat() : 運行中改變數據轉化類型
TG_EnableAutoRead() : 開啟1個后台線程,每隔1ms刷新一次
TG_EnableBlinkDetection() : 控制是否開啟眨眼功能
TG_EnableLowPassFilter() : 。。。
TG_GetDriverVersion() : 獲取dll版本
TG_SendByte() : 向耳機發送控制信息,一般不用
TG_GetValue()獲取的數據(不同耳機不同,請查閱文檔):
#define TG_DATA_BATTERY 0
#define TG_DATA_POOR_SIGNAL 1
#define TG_DATA_ATTENTION 2
#define TG_DATA_MEDITATION 3
#define TG_DATA_RAW 4
#define TG_DATA_DELTA 5
#define TG_DATA_THETA 6
#define TG_DATA_ALPHA1 7
#define TG_DATA_ALPHA2 8
#define TG_DATA_BETA1 9
#define TG_DATA_BETA2 10
#define TG_DATA_GAMMA1 11
#define TG_DATA_GAMMA2 12
#define TG_DATA_BLINK_STRENGTH 37
///////////////////////////////////////////////////////////////////////////////////////
java版本大致相同,只是使用JNI調用而已。
ThinkGear.java中開啟了一個線程,用於主動更新數據:
public static int connectionId=0; //主要句柄 public static boolean init() { connectionId = GetNewConnectionId(); if( connectionId < 0 ) return false; String comPortName = "\\\\.\\COM3"; // 注意COM名要和電腦的連接相對應 // TG_BAUD_*可以設置波特率,TG_STREAM_PACKETS是數據格式 int errCode = Connect( connectionId, comPortName, BAUD_9600, STREAM_PACKETS ); if( errCode < 0 ) return false; Runnable auto=new AutoReadThread(); new Thread(auto).start(); return true; } public static int getAttention() { return (int)GetValue(connectionId, DATA_ATTENTION); } //內部類,自動更新數據用 public static class AutoReadThread implements Runnable { @Override public void run() { while(true) { ThinkGear.ReadPackets(connectionId,-1); try { Thread.sleep(5); // 5ms更新一次數據 } catch (Exception e) { e.printStackTrace(); } } } }
Test.java:
/** * 用於從腦電波采集數據 * 使用方法: * 1、使用ThinkGear.init()進行初始化 * 2、然后隨時可以使用ThinkGear.getAttention()獲取最新數據 * 3、目前要自己調節時間間隔,后面要做什么清楚了再封裝為每秒1個數組 * @author 林培東 * */ public class Test { public static final int times=10; //每秒采集10次數據 public static void main(String[] args) { Runnable r=new ReadData(); new Thread(r).start(); } public static class ReadData implements Runnable { @Override public void run() { if( !ThinkGear.init() ) //初始化失敗 { System.out.println("Initialize Error!"); System.exit(1); } else { System.out.println("Initialize Succeed!"); } int count=1; System.out.println("The attention data read in every second:"); while(true) //循環采集 { if(count%times==0) System.out.printf("%d\n",ThinkGear.getAttention()); else System.out.printf("%d-", ThinkGear.getAttention()); count++; try { Thread.sleep(1000/times); } catch(Exception e) { e.printStackTrace(); } } } } }
相關資源已存檔在博客園后台處。