本人菜鸟一个,程序不够完美,第一次写博客有很多漏洞,希望谅解!!!
硬件清单:LCD12864,ARDUINO MEGA2560,蓝牙模块,脑电波传感器,usb音响,树莓派3
功能解释:从脑电波模块中解析出人脑数据,实时切换字母,集中注意力采集目标值,目标值通过蓝牙发送给树莓派进行语音合成。
程序如下:
/*
LCD Arduino
PIN1 = GND
PIN2 = 5V
RS(CS) = 8;
RW(SID)= 9;
EN(CLK) = 3;
PIN15 PSB = GND;
BLA = VCC
BLK = GND
TX0,RX0 //脑电波蓝牙接受
TX2,RX2 //蓝牙发送
13 //信号噪声指示灯
*/
#include <SoftwareSerial.h>
#include "LCD12864RSPI.h"
#define BAUDRATE 57600
#define DEBUGOUTPUT 0
#define beep 12
#define AR_SIZE( a ) sizeof( a ) / sizeof( a[0] ) //显示的长度
int i= 0;
int bai1=0,shi1=0,ge1=0;
int bai2=0,shi2=0,ge2=0;
int bai3=0,shi3=0,ge3=0;
int yan = 0; //切换输入的字符
char biaozhi = 'a';
//校验和变量
byte generatedChecksum = 0;
byte checksum= 0;
int payloadLength = 0;
byte payloadData [64] = {0};
byte poorQuality = 0;
//字节关注= 0;
//字节冥想= 0;
byte attention = 0; //专注度
byte meditation = 0;//放松度
int raw = 0;
unsigned int delta =0;
unsigned int deltamid =0;
unsigned int theta = 0;
unsigned int thetamid =0;
unsigned int lowalpha = 0;
unsigned int highalpha = 0;
unsigned int lowbeta = 0;
unsigned int highbeta = 0;
unsigned int lowgamma = 0;
unsigned int middlegamma = 0;
unsigned char show0[]="SIAS"; //SIAS
unsigned char show1[]="poor :"; //信号噪声
unsigned char show2[]="atten:"; //专注度
unsigned char show3[]="medit:"; //放松度
unsigned char shu0[]={0x30, 0x00}; //0
unsigned char shu1[]={0x31, 0x00}; //1
unsigned char shu2[]={0x32, 0x00}; //2
unsigned char shu3[]={0x33, 0x00}; //3
unsigned char shu4[]={0x34, 0x00}; //4
unsigned char shu5[]={0x35, 0x00}; //5
unsigned char shu6[]={0x36, 0x00}; //6
unsigned char shu7[]={0x37, 0x00}; //7
unsigned char shu8[]={0x38, 0x00}; //8
unsigned char shu9[]={0x39, 0x00}; //9
//系统变量
long lastReceivedPacket = 0;
boolean bigPacket = false;
//SoftwareSerial mySerial(7, 6); //rx,tx
//////////////////////////
//微处理器设置
////////////////// ////////
void setup(){
pinMode(13, OUTPUT); //LED
pinMode(12, OUTPUT); //BEEP
Serial.begin(BAUDRATE); // USB
Serial2.begin(9600); //硬件串口2
LCDA.Initialise(); // 屏幕初始化
LCDA.CLEAR();//清屏
LCDA.DisplayString(0,0,show1,AR_SIZE(show1));//信号噪声 长度为6
LCDA.DisplayString(1,0,show2,AR_SIZE(show2));//专注度
LCDA.DisplayString(2,0,show3,AR_SIZE(show3));//放松度
}
////////////////////////////////
//读取从串行UART数据//
///// ///////////////////////////
byte ReadOneByte()
{
int ByteRead;
while(!Serial.available());
ByteRead = Serial.read();
/*
#if DEBUGOUTPUT
Serial.print((char)ByteRead); //回显USB串口的相同字节(用于调试目的)
#endif
*/
return ByteRead;
}
/////////////
// MAIN LOOP //
///////////
void poor_quzhi()
{
//LCDA.CLEAR();//清屏
bai1 = poorQuality/100;
shi1= poorQuality/10;
ge1 = poorQuality%10;
switch(bai1)
{
case 0: LCDA.DisplayString(0,3,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(0,3,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(0,3,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(0,3,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(0,3,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(0,3,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(0,3,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(0,3,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(0,3,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(0,3,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(0,3,shu0,AR_SIZE(shu0)); break;
}
switch(shi1)
{
case 0: LCDA.DisplayString(0,4,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(0,4,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(0,4,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(0,4,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(0,4,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(0,4,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(0,4,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(0,4,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(0,4,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(0,4,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(0,4,shu0,AR_SIZE(shu0)); break;
}
switch(ge1)
{
case 0: LCDA.DisplayString(0,5,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(0,5,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(0,5,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(0,5,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(0,5,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(0,5,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(0,5,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(0,5,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(0,5,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(0,5,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(0,5,shu0,AR_SIZE(shu0)); break;
}
}
void attention_quzhi()
{
//LCDA.CLEAR();//清屏
bai2 = attention/100;
shi2= attention/10;
ge2= attention%10;
switch(bai2)
{
case 0: LCDA.DisplayString(1,3,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(1,3,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(1,3,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(1,3,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(1,3,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(1,3,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(1,3,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(1,3,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(1,3,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(1,3,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(1,3,shu0,AR_SIZE(shu0)); break;
}
switch(shi2)
{
case 0: LCDA.DisplayString(1,4,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(1,4,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(1,4,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(1,4,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(1,4,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(1,4,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(1,4,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(1,4,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(1,4,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(1,4,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(1,4,shu0,AR_SIZE(shu0)); break;
}
switch(ge2)
{
case 0: LCDA.DisplayString(1,5,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(1,5,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(1,5,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(1,5,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(1,5,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(1,5,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(1,5,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(1,5,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(1,5,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(1,5,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(1,5,shu0,AR_SIZE(shu0)); break;
}
}
void meditation_quzhi()
{
//LCDA.CLEAR();//清屏
bai3 = meditation/100;
shi3= meditation/10;
ge3= meditation%10;
switch(bai3)
{
case 0: LCDA.DisplayString(2,3,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(2,3,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(2,3,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(2,3,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(2,3,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(2,3,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(2,3,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(2,3,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(2,3,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(2,3,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(2,3,shu0,AR_SIZE(shu0)); break;
}
switch(shi3)
{
case 0: LCDA.DisplayString(2,4,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(2,4,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(2,4,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(2,4,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(2,4,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(2,4,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(2,4,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(2,4,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(2,4,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(2,4,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(2,4,shu0,AR_SIZE(shu0)); break;
}
switch(ge3)
{
case 0: LCDA.DisplayString(2,5,shu0,AR_SIZE(shu0)); break;
case 1: LCDA.DisplayString(2,5,shu1,AR_SIZE(shu1)); break;
case 2: LCDA.DisplayString(2,5,shu2,AR_SIZE(shu2)); break;
case 3: LCDA.DisplayString(2,5,shu3,AR_SIZE(shu3)); break;
case 4: LCDA.DisplayString(2,5,shu4,AR_SIZE(shu4)); break;
case 5: LCDA.DisplayString(2,5,shu5,AR_SIZE(shu5)); break;
case 6: LCDA.DisplayString(2,5,shu6,AR_SIZE(shu6)); break;
case 7: LCDA.DisplayString(2,5,shu7,AR_SIZE(shu7)); break;
case 8: LCDA.DisplayString(2,5,shu8,AR_SIZE(shu8)); break;
case 9: LCDA.DisplayString(2,5,shu9,AR_SIZE(shu9)); break;
default : LCDA.DisplayString(2,5,shu0,AR_SIZE(shu0)); break;
}
}
void xianshi()
{
LCDA.DisplayString(0,0,show1,AR_SIZE(show1));//信号噪声 长度为6
LCDA.DisplayString(1,0,show2,AR_SIZE(show2));//专注度
LCDA.DisplayString(2,0,show3,AR_SIZE(show3));//放松度
}
void loop()
{
//查找同步字节
if(ReadOneByte()== 170) //0xaa
{
if(ReadOneByte()== 170)
{
payloadLength = ReadOneByte();
if(payloadLength> 169)//有效载荷长度不能大于169
return;
generatedChecksum = 0;
for(int i = 0; i <payloadLength; i ++)
{
payloadData[i] = ReadOneByte(); //将有效载荷读入内存
generatedChecksum += payloadData[i];
}
checksum = ReadOneByte(); //从流中读取校验和字节
generatedChecksum = 255 - generatedChecksum; //
if(checksum == generatedChecksum)
{
poorQuality = 200;
attention = 0;
meditation = 0;
for(int i = 0; i <payloadLength; i ++) //解析有效负载
{
switch(payloadData[i])
{
case 2:
i ++;
poorQuality = payloadData[i];
bigPacket = true;
break;
case 4:
i ++;
attention = payloadData[i];
break;
case 5:
i ++;
meditation = payloadData[i];
break;
case 0x80:
i = i + 3;
raw = payloadData[i-1]*256+payloadData[i];
if(raw >= 32768)
raw = raw - 65536;
break;
case 0x83:
//delta = ((payloadData[i+2]<<16)|(payloadData[i+3]<<8)|(payloadData[i+4]));
delta = payloadData[i+2];
deltamid = payloadData[i+3];
//theta = ((payloadData[i+5]<<16)|(payloadData[i+6]<<8)|(payloadData[i+7]));
theta = payloadData[i+5];
thetamid = payloadData[i+6];
//lowalpha = ((payloadData[i+8]<<16)|(payloadData[i+9]<<8)|(payloadData[i+10]));
//highalpha = ((payloadData[i+11]<<16)|(payloadData[i+12]<<8)|(payloadData[i+13]));
//lowbeta = ((payloadData[i+14]<<16)|(payloadData[i+15]<<8)|(payloadData[i+16]));
//highbeta = ((payloadData[i+17]<<16)|(payloadData[i+18]<<8)|(payloadData[i+19]));
//lowgamma = ((payloadData[i+20]<<16)|(payloadData[i+21]<<8)|(payloadData[i+22]));
//middlegamma = ((payloadData[i+23]<<16)|(payloadData[i+24]<<8)|(payloadData[i+25]));
i = i + 25;
break;
default :
break;
} //切换
} // for循环
#if !DEBUGOUTPUT
// ***添加您的代码在这里***
if(bigPacket)
{
Serial.print("耳朵:");
Serial.print(poorQuality,DEC); //信号噪声
Serial.print(" 注意:");
Serial.print(attention,DEC); //专注度
Serial.print(" 放松:");
Serial.print(meditation,DEC); //放松度
poor_quzhi();
attention_quzhi();
meditation_quzhi();
/*
Serial.print(" Delta-HIGH:"); //精神无意识状态
Serial.print(delta,DEC);
Serial.print(" Delta-MID:"); //精神无意识状态
Serial.print(deltamid,DEC);
Serial.print(" Theta:"); //想象,回忆,幻想,浅睡
Serial.print(theta,DEC);
Serial.print(" Theta-MID:"); //想象,回忆,幻想,浅睡
Serial.print(thetamid,DEC);
Serial.print(" LowAlpha:"); //放松,但是不困
Serial.print(lowalpha,DEC);
Serial.print(" HighAlpha:"); //放松,但是不困
Serial.print(highalpha,DEC);
Serial.print(" LowBeta:"); //警觉,烦躁,思考
Serial.print(lowbeta,DEC);
Serial.print(" HighBeta:"); //警觉,烦躁,思考
Serial.print(highbeta,DEC);
Serial.print(" LowGamma:"); //心理活跃
Serial.print(lowgamma,DEC);
Serial.print(" MiddleGamma:"); //心理活跃
Serial.print(middlegamma,DEC);
*/
//Serial.print(" 原始: ");
//Serial.print(raw);
//Serial.print(" 自上次数据包以来的时间: ");
//Serial.print(millis() - lastReceivedPacket,DEC);
//lastReceivedPacket = millis();
//Serial.print(" ATT: ");
//int att = Serial.print(attention,DEC);
Serial.print("\n");
Serial.flush();
if ((poorQuality > 10)&&(attention != 0)&&(meditation != 0)) //确认字母
{
digitalWrite(13,50);
analogWrite(12,0);
//digitalWrite(12,0);
biaozhi = 'a'; //
Serial2.println(char(biaozhi));
}
else if((poorQuality == 0)&&(attention != 0)&&(meditation != 0))
{
digitalWrite(13,0);
if( (attention > 80) &&(meditation <80) ) //专注 > 80
{
biaozhi = 'b'; //删除字符串最后一位
analogWrite(12,200);
//digitalWrite(12,80);
Serial2.println(char(biaozhi));
delay(200);
analogWrite(12,0);
}
else if((attention > 80) &&(meditation >80)) //放松 > 80
{
biaozhi = 'c'; //确认发送字符串
analogWrite(12,0);
// digitalWrite(12,0);
Serial2.println(char(biaozhi));
}
//else biaozhi = 'd'; //发送一个无效值 验证脑电波数据是否正常
//Serial2.println(char(biaozhi));
}
else
{
digitalWrite(13,0);
analogWrite(12,0);
//digitalWrite(12,0);
}
#endif
bigPacket = false;
}
else
{
//校验和错误
} //如果其他校验和结束
Serial.flush();
} //结束,如果读取0xAA字节
} //结束,如果读取0xAA字节
}
}