TGAM(脑波传感器)+Arduino开发笔记

最近闲来无事搞了个TGAM蓝牙脑电波模块
事实证明有钱还是去买游戏吧买什么传感器
谁能帮我打塞尔达剑之试炼免费送脑波代码

故事还要从多年前NeuroSky公司搞了个Mindwave脑电波蓝牙耳机说起。笔者曾有幸借到过这个蓝牙耳机感觉很高大上,长这样:

Mindwave.jpg

有了脑电波数据后,就可以……比如把自己的注意力集中度投影到boss的屏幕上,让boss知道你在认真工作,听起来还有些小激动呢(谁会做这种事啊(╯‵□′)╯︵┻━┻!)

Anyway,最近ST也想重新尝试一下脑电波,但是耳机套要一千多呢,作为一个穷人,ST只淘宝了神念科技用的脑电波采集模块——ThinkgearAM,嗯……长这样:

TGAM.jpg

虽然看着很简陋但是功能是一样的!(并且省了一个任天堂健身环的钱呢。)

言归正传,开始开发。


一.开发思路

TGAM套件自带一个蓝牙从机,一般来讲,如果直接用Thinkgear官方的api开发,用电脑配上蓝牙,运行官方的C或者Java就行。
但是如果你想用脑电波点亮个灯或驱动个车,还是直接连Arduino单片机比较方便。具体思路是在Arduino板上接一个蓝牙主机,接收传感器发送的数据,并在Arduino程序中使用它们。
我们需要:
Arduino Uno开发板一块;
HC-05蓝牙模块一个(用作主蓝牙);
TGAM套件一组,套件自带从蓝牙;
导线若干;

二.AT命令与主从蓝牙配对

1. HC-05与Arduino连接

HC-05是主从一体的蓝牙模块,HC-05与Arduino连接可以参照Arduino实验室里面的

Arduino使用HC05蓝牙模块与手机连接

在上面教程上稍微做些更改,Arduino板与HC-05芯片连接如下:

连线方式.jpg
Arduino 5V – VCC
Arduino GND – GND
Arduino Pin10 – TXD
Arduino Pin11 – RXD
Arduino 3.3V – KEY

这里Pin10和Pin11的引脚可换,但要和程序里SoftwareSerial(rxPin, txPin)对应。rxPin是软串口接收引脚,txPin是软串口发送引脚,保证单片机发送对芯片接收,单片机接收对芯片发送。
EN/KEY接3.3V是为了用AT+INIT初始化命令,这个命令只有EN/KEY引脚置高电平时才能使用。只有初始化了之后,才能用AT+INQ搜索其他蓝牙设备。

#include <SoftwareSerial.h> 
 
// Pin10为RX,接HC05的TXD
// Pin11为TX,接HC05的RXD
SoftwareSerial BT(10, 11); 
char val;
 
void setup() {
  Serial.begin(38400); 
  Serial.println("BT is ready!");
  // HC-05默认,38400
  BT.begin(38400);
}
 
void loop() {
  if (Serial.available()) {
    val = Serial.read();
    BT.print(val);
  }
 
  if (BT.available()) {
    val = BT.read();
    Serial.print(val);
  }
}

程序中的Serial.begin波特率我们不用动,它跟HC-05与其他蓝牙模块配对传输时的波特率是两个概念,此处的波特率只是Arduino给HC-05写指令用的波特率,不影响配对。

HC-05有两种工作模式,普通模式和AT模式。准备完程序并且插好线后,按住HC-05模块角落的黑色小按钮,同时给Arduino开发板通电,这时会看到蓝牙模块的LED灯大概2秒闪烁一下,证明蓝牙模块已经进入AT模式,可以编写指令了 ♪(^∀^●)。

2. 写入AT指令

在写AT指令前,我们要知道,两个蓝牙模块成功配对有几个条件:
配对密码要一样;
两个蓝牙模块的串口波特率要一样;
主模块找到从模块地址;

根据Thinkgear给的官方api,TGAM的默认密码是0000,波特率是57600;我们需要将HC-05的密码和波特率也设置成这个才能配对。

Thinkgear参数.png

打开Arduino的串口监视器,选NL和CR,调到38400的波特率,会看到显示了BT is ready!
此时发送AT,会回复OK,可以配置HC-05蓝牙芯片了。这里我第一次发送AT的时候程序总会返回ERROR,再发一遍才显示OK

串口监视器.png

AT指令百度一下有很多也很全,这里只写重要的几个。
AT+INIT:初始化。初始化了之后才能AT+INQ查询其他蓝牙设备,当然如果你已经知道了从机蓝牙的MAC地址,可以不查询。
AT+ROLE:选择HC05蓝牙模块的角色,AT+ROLE=0为从机,AT+ROLE=1为主机,默认是从机,这里我们需要输入AT+ROLE=1改成主机。用AT+ROLE?可以查看当前角色。
AT+PSWD:设置蓝牙模块的配对密码,HC-05的默认配对密码是1234,TGAM从机密码是0000,我们要输入AT+PSWD=0000改成一样的。
AT_UART:设置蓝牙与其他蓝牙通讯的波特率,指令格式是AT+UART=<Param>,<Param1>,<Param2>,第一个参数是波特率,后面两个参数是停止位和校验位(一般置0),HC-05默认波特率是9600,TGAM从机默认波特率是57600,我们输入AT+UART=57600,0,0
AT+INQ:查询蓝牙设备,返回设备的mac地址。
AT+BIND:绑定其他蓝牙MAC地址,AT+BIND=<address>,这里,如果你的从蓝牙MAC地址是A44A:0E:08008D,输入时需要把冒号改为逗号,输入AT+BIND=A44A,0E,08008D
AT+CMODE:是否允许蓝牙连接任何设备,0表示只能连接绑定地址的蓝牙,1表示可以连接任何蓝牙。
AT+LINK:这是最后一步,连接蓝牙设备,输入AT+LINK=A44A,0E,08008D,返回OK为成功,返回FAIL为失败。失败的话,请确认两个蓝牙的配对密码和波特率是否一致。

3. 主从蓝牙配对

如果两个蓝牙成功连接上,HC-05的LED灯会每2秒很快的闪2下,而TGAM蓝牙的指示灯会一直亮着,此时就说明连接成功了。
接下来,断开Arduino板,去掉HC-05 KEY引脚的导线,再次插上时会回到HC-05的工作模式,同时两个蓝牙模块还是会自动匹配。

友情提示,当两个蓝牙成功连接上时,串口监视器可能会突然蹦出好多乱码,影响判断连接状态,可以直接通过观察两个蓝牙芯片指示灯状态判断是否连接成功。

连接成功.jpg

三.Arduino读取数据

连接上了之后,我们就可以在Arduino中编程读取脑电波传感器的数据了。
此时需要改变一下连线:
HC-05的TXD接Uno板的0->RX引脚,RXD接TX->1引脚

Arduino 5V – VCC
Arduino GND – GND
Arduino Pin0 – TXD
Arduino Pin1 – RXD

接完后重新插上Arduino Uno板,并烧录Arduino读取脑电波数值的程序。

这里遇到个问题,TXD和RXD接了Pin0和Pin1时,程序一直上传不上去(⊙.⊙),只好先在接10和11引脚的时候把程序上传上去,然后改导线到Pin0和Pin1,这样串口监视器才会显示数据,不知为何,还请大神赐教。

总之,磕磕绊绊的总算是调通了 (ง •̀灬•́)ง。这样就可以拿数据为所欲为了。

成功.jpg

示例代码如下:

 /*
 通过UART串口显示信号值、注意力及放松度的值
 */
#define BAUDRATE 57600
#define DEBUGOUTPUT 0

//校验相关变量
int   generatedChecksum = 0;
byte  checksum = 0; 

//接收数据长度和数据数组
byte  payloadLength = 0;
byte  payloadData[32] = {0};//总共接收32个自己的数据

//需要读取的信息变量
byte signalquality = 0;//信号质量
byte attention = 0;    //注意力值
byte meditation = 0;   //放松度值

//初始化
void setup() 
{
  Serial.begin(BAUDRATE); 
}

//从串口读取一个字节数据
byte ReadOneByte() 
{
  int ByteRead;
  while(!Serial.available());
  ByteRead = Serial.read();
  return ByteRead;//返回读到的字节
}

//读取串口数据
void read_serial_data()
{
    //寻找数据包起始同步字节,2个
    if(ReadOneByte() == 0xAA)//先读一个
    {
      if(ReadOneByte() == 0xAA)//读第二个
      {
        payloadLength = ReadOneByte();//读取第三个,数据包字节的长度
        if(payloadLength == 0x20)//如果接收到的是大包数据才继续读取,小包数据则舍弃不读取
        {
          generatedChecksum = 0; //校验变量清0       
          for(int i = 0; i < payloadLength; i++)//连续读取32个字节
          {  
            payloadData[i] = ReadOneByte();//读取指定长度数据包中的数据
            generatedChecksum += payloadData[i];//计算数据累加和
          }         
          checksum = ReadOneByte();//读取校验字节  
          //校验
          generatedChecksum = (~generatedChecksum)&0xff;       
          //比较校验字节
          if(checksum == generatedChecksum)//数据接收正确,继续处理 
          {    
            signalquality = 0;//信号质量变量
            attention = 0;    //注意力值变量
            //赋值数据
            signalquality = payloadData[1];//信号值      
            attention = payloadData[29];//注意力值
            meditation = payloadData[31];//放松度值
            #if !DEBUGOUTPUT         
            //打印信号质量
            Serial.print("SignalQuality: ");
            Serial.print(signalquality, DEC);
            //打印注意力值
            Serial.print("Attation: ");
            Serial.print(attention, DEC);
            //打印放松度值
            Serial.print("Meditation: ");
            Serial.print(meditation, DEC);
            //换行
            Serial.print("\n");       
            #endif              
          } 
        } 
      }
    }
}

//主循环
void loop() 
{
  read_serial_data();//读取串口数据 
}

折腾了三天,总算是配对了蓝牙也接收了数据,心满意足!然后……
Arduino关闭!
Idea启动!
直接用Java读数不香吗?什么单片机导线太费脑细胞了吧乛 з乛


感谢YCK大神教我Thinkgear的Java api怎么使用。
感谢Doggy看串口看了个两秒左右。
感谢面包匠同志在我身边看沙雕视频保证了我愉悦的好心情。
感谢Berber啃了两口传感器芯片,让它突然就配对成功了。

最大功臣.jpg
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容