最近閑來無事搞了個(gè)TGAM藍(lán)牙腦電波模塊
事實(shí)證明有錢還是去買游戲吧買什么傳感器
誰能幫我打塞爾達(dá)劍之試煉免費(fèi)送腦波代碼
故事還要從多年前NeuroSky公司搞了個(gè)Mindwave腦電波藍(lán)牙耳機(jī)說起满败。筆者曾有幸借到過這個(gè)藍(lán)牙耳機(jī)感覺很高大上奋蔚,長(zhǎng)這樣:
有了腦電波數(shù)據(jù)后线召,就可以……比如把自己的注意力集中度投影到boss的屏幕上翻翩,讓boss知道你在認(rèn)真工作祷安,聽起來還有些小激動(dòng)呢(誰會(huì)做這種事啊(╯‵□′)╯︵┻━┻L劾)耗啦。
Anyway纫版,最近ST也想重新嘗試一下腦電波床绪,但是耳機(jī)套要一千多呢,作為一個(gè)窮人其弊,ST只淘寶了神念科技用的腦電波采集模塊——ThinkgearAM癞己,嗯……長(zhǎng)這樣:
雖然看著很簡(jiǎn)陋但是功能是一樣的!(并且省了一個(gè)任天堂健身環(huán)的錢呢梭伐。)
言歸正傳痹雅,開始開發(fā)。
一.開發(fā)思路
TGAM套件自帶一個(gè)藍(lán)牙從機(jī)糊识,一般來講绩社,如果直接用Thinkgear官方的api開發(fā)摔蓝,用電腦配上藍(lán)牙,運(yùn)行官方的C或者Java就行愉耙。
但是如果你想用腦電波點(diǎn)亮個(gè)燈或驅(qū)動(dòng)個(gè)車贮尉,還是直接連Arduino單片機(jī)比較方便。具體思路是在Arduino板上接一個(gè)藍(lán)牙主機(jī)朴沿,接收傳感器發(fā)送的數(shù)據(jù)猜谚,并在Arduino程序中使用它們。
我們需要:
Arduino Uno開發(fā)板一塊赌渣;
HC-05藍(lán)牙模塊一個(gè)(用作主藍(lán)牙)魏铅;
TGAM套件一組,套件自帶從藍(lán)牙坚芜;
導(dǎo)線若干览芳;
二.AT命令與主從藍(lán)牙配對(duì)
1. HC-05與Arduino連接
HC-05是主從一體的藍(lán)牙模塊,HC-05與Arduino連接可以參照Arduino實(shí)驗(yàn)室里面的
在上面教程上稍微做些更改货岭,Arduino板與HC-05芯片連接如下:
Arduino 5V – VCC
Arduino GND – GND
Arduino Pin10 – TXD
Arduino Pin11 – RXD
Arduino 3.3V – KEY
這里Pin10和Pin11的引腳可換路操,但要和程序里SoftwareSerial(rxPin, txPin)
對(duì)應(yīng)。rxPin是軟串口接收引腳千贯,txPin是軟串口發(fā)送引腳屯仗,保證單片機(jī)發(fā)送對(duì)芯片接收,單片機(jī)接收對(duì)芯片發(fā)送搔谴。
EN/KEY接3.3V是為了用AT+INIT初始化命令魁袜,這個(gè)命令只有EN/KEY引腳置高電平時(shí)才能使用。只有初始化了之后敦第,才能用AT+INQ搜索其他藍(lán)牙設(shè)備峰弹。
#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默認(rèn)鞠呈,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
波特率我們不用動(dòng),它跟HC-05與其他藍(lán)牙模塊配對(duì)傳輸時(shí)的波特率是兩個(gè)概念右钾,此處的波特率只是Arduino給HC-05寫指令用的波特率蚁吝,不影響配對(duì)。
HC-05有兩種工作模式舀射,普通模式和AT模式窘茁。準(zhǔn)備完程序并且插好線后,按住HC-05模塊角落的黑色小按鈕脆烟,同時(shí)給Arduino開發(fā)板通電山林,這時(shí)會(huì)看到藍(lán)牙模塊的LED燈大概2秒閃爍一下,證明藍(lán)牙模塊已經(jīng)進(jìn)入AT模式邢羔,可以編寫指令了 ?(^?^●)驼抹。
2. 寫入AT指令
在寫AT指令前桑孩,我們要知道,兩個(gè)藍(lán)牙模塊成功配對(duì)有幾個(gè)條件:
配對(duì)密碼要一樣砂蔽;
兩個(gè)藍(lán)牙模塊的串口波特率要一樣洼怔;
主模塊找到從模塊地址;
根據(jù)Thinkgear給的官方api左驾,TGAM的默認(rèn)密碼是0000镣隶,波特率是57600;我們需要將HC-05的密碼和波特率也設(shè)置成這個(gè)才能配對(duì)诡右。
打開Arduino的串口監(jiān)視器安岂,選NL和CR,調(diào)到38400的波特率帆吻,會(huì)看到顯示了BT is ready!
此時(shí)發(fā)送AT域那,會(huì)回復(fù)OK,可以配置HC-05藍(lán)牙芯片了猜煮。這里我第一次發(fā)送AT的時(shí)候程序總會(huì)返回ERROR次员,再發(fā)一遍才顯示OK
AT指令百度一下有很多也很全,這里只寫重要的幾個(gè)王带。
AT+INIT:初始化淑蔚。初始化了之后才能AT+INQ查詢其他藍(lán)牙設(shè)備,當(dāng)然如果你已經(jīng)知道了從機(jī)藍(lán)牙的MAC地址愕撰,可以不查詢刹衫。
AT+ROLE:選擇HC05藍(lán)牙模塊的角色,AT+ROLE=0為從機(jī)搞挣,AT+ROLE=1為主機(jī)带迟,默認(rèn)是從機(jī),這里我們需要輸入AT+ROLE=1
改成主機(jī)囱桨。用AT+ROLE?
可以查看當(dāng)前角色仓犬。
AT+PSWD:設(shè)置藍(lán)牙模塊的配對(duì)密碼,HC-05的默認(rèn)配對(duì)密碼是1234舍肠,TGAM從機(jī)密碼是0000搀继,我們要輸入AT+PSWD=0000
改成一樣的。
AT_UART:設(shè)置藍(lán)牙與其他藍(lán)牙通訊的波特率貌夕,指令格式是AT+UART=<Param>,<Param1>,<Param2>
律歼,第一個(gè)參數(shù)是波特率民镜,后面兩個(gè)參數(shù)是停止位和校驗(yàn)位(一般置0)啡专,HC-05默認(rèn)波特率是9600,TGAM從機(jī)默認(rèn)波特率是57600制圈,我們輸入AT+UART=57600,0,0
AT+INQ:查詢藍(lán)牙設(shè)備们童,返回設(shè)備的mac地址畔况。
AT+BIND:綁定其他藍(lán)牙MAC地址,AT+BIND=<address>
慧库,這里跷跪,如果你的從藍(lán)牙MAC地址是A44A:0E:08008D
,輸入時(shí)需要把冒號(hào)改為逗號(hào)齐板,輸入AT+BIND=A44A,0E,08008D
AT+CMODE:是否允許藍(lán)牙連接任何設(shè)備吵瞻,0表示只能連接綁定地址的藍(lán)牙,1表示可以連接任何藍(lán)牙甘磨。
AT+LINK:這是最后一步橡羞,連接藍(lán)牙設(shè)備,輸入AT+LINK=A44A,0E,08008D
济舆,返回OK為成功卿泽,返回FAIL為失敗。失敗的話滋觉,請(qǐng)確認(rèn)兩個(gè)藍(lán)牙的配對(duì)密碼和波特率是否一致签夭。
3. 主從藍(lán)牙配對(duì)
如果兩個(gè)藍(lán)牙成功連接上,HC-05的LED燈會(huì)每2秒很快的閃2下椎侠,而TGAM藍(lán)牙的指示燈會(huì)一直亮著第租,此時(shí)就說明連接成功了。
接下來肺蔚,斷開Arduino板煌妈,去掉HC-05 KEY引腳的導(dǎo)線,再次插上時(shí)會(huì)回到HC-05的工作模式宣羊,同時(shí)兩個(gè)藍(lán)牙模塊還是會(huì)自動(dòng)匹配璧诵。
友情提示,當(dāng)兩個(gè)藍(lán)牙成功連接上時(shí)仇冯,串口監(jiān)視器可能會(huì)突然蹦出好多亂碼之宿,影響判斷連接狀態(tài),可以直接通過觀察兩個(gè)藍(lán)牙芯片指示燈狀態(tài)判斷是否連接成功苛坚。
三.Arduino讀取數(shù)據(jù)
連接上了之后比被,我們就可以在Arduino中編程讀取腦電波傳感器的數(shù)據(jù)了。
此時(shí)需要改變一下連線:
HC-05的TXD接Uno板的0->RX引腳泼舱,RXD接TX->1引腳
Arduino 5V – VCC
Arduino GND – GND
Arduino Pin0 – TXD
Arduino Pin1 – RXD
接完后重新插上Arduino Uno板等缀,并燒錄Arduino讀取腦電波數(shù)值的程序。
這里遇到個(gè)問題娇昙,TXD和RXD接了Pin0和Pin1時(shí)尺迂,程序一直上傳不上去(⊙.⊙),只好先在接10和11引腳的時(shí)候把程序上傳上去,然后改導(dǎo)線到Pin0和Pin1噪裕,這樣串口監(jiān)視器才會(huì)顯示數(shù)據(jù)蹲盘,不知為何,還請(qǐng)大神賜教膳音。
總之召衔,磕磕絆絆的總算是調(diào)通了 (? ??灬??)?。這樣就可以拿數(shù)據(jù)為所欲為了祭陷。
示例代碼如下:
/*
通過UART串口顯示信號(hào)值苍凛、注意力及放松度的值
*/
#define BAUDRATE 57600
#define DEBUGOUTPUT 0
//校驗(yàn)相關(guān)變量
int generatedChecksum = 0;
byte checksum = 0;
//接收數(shù)據(jù)長(zhǎng)度和數(shù)據(jù)數(shù)組
byte payloadLength = 0;
byte payloadData[32] = {0};//總共接收32個(gè)自己的數(shù)據(jù)
//需要讀取的信息變量
byte signalquality = 0;//信號(hào)質(zhì)量
byte attention = 0; //注意力值
byte meditation = 0; //放松度值
//初始化
void setup()
{
Serial.begin(BAUDRATE);
}
//從串口讀取一個(gè)字節(jié)數(shù)據(jù)
byte ReadOneByte()
{
int ByteRead;
while(!Serial.available());
ByteRead = Serial.read();
return ByteRead;//返回讀到的字節(jié)
}
//讀取串口數(shù)據(jù)
void read_serial_data()
{
//尋找數(shù)據(jù)包起始同步字節(jié),2個(gè)
if(ReadOneByte() == 0xAA)//先讀一個(gè)
{
if(ReadOneByte() == 0xAA)//讀第二個(gè)
{
payloadLength = ReadOneByte();//讀取第三個(gè)兵志,數(shù)據(jù)包字節(jié)的長(zhǎng)度
if(payloadLength == 0x20)//如果接收到的是大包數(shù)據(jù)才繼續(xù)讀取毫深,小包數(shù)據(jù)則舍棄不讀取
{
generatedChecksum = 0; //校驗(yàn)變量清0
for(int i = 0; i < payloadLength; i++)//連續(xù)讀取32個(gè)字節(jié)
{
payloadData[i] = ReadOneByte();//讀取指定長(zhǎng)度數(shù)據(jù)包中的數(shù)據(jù)
generatedChecksum += payloadData[i];//計(jì)算數(shù)據(jù)累加和
}
checksum = ReadOneByte();//讀取校驗(yàn)字節(jié)
//校驗(yàn)
generatedChecksum = (~generatedChecksum)&0xff;
//比較校驗(yàn)字節(jié)
if(checksum == generatedChecksum)//數(shù)據(jù)接收正確,繼續(xù)處理
{
signalquality = 0;//信號(hào)質(zhì)量變量
attention = 0; //注意力值變量
//賦值數(shù)據(jù)
signalquality = payloadData[1];//信號(hào)值
attention = payloadData[29];//注意力值
meditation = payloadData[31];//放松度值
#if !DEBUGOUTPUT
//打印信號(hào)質(zhì)量
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
}
}
}
}
}
//主循環(huán)
void loop()
{
read_serial_data();//讀取串口數(shù)據(jù)
}
折騰了三天毒姨,總算是配對(duì)了藍(lán)牙也接收了數(shù)據(jù)哑蔫,心滿意足!然后……
Arduino關(guān)閉弧呐!
Idea啟動(dòng)闸迷!
直接用Java讀數(shù)不香嗎?什么單片機(jī)導(dǎo)線太費(fèi)腦細(xì)胞了吧乛 з乛
感謝YCK大神教我Thinkgear的Java api怎么使用俘枫。
感謝Doggy看串口看了個(gè)兩秒左右腥沽。
感謝面包匠同志在我身邊看沙雕視頻保證了我愉悅的好心情。
感謝Berber啃了兩口傳感器芯片鸠蚪,讓它突然就配對(duì)成功了今阳。