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板与HC-05芯片连接如下:
连线方式.jpgArduino 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
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啃了两口传感器芯片,让它突然就配对成功了。