脑电波-使用意念说话

本人菜鸟一个,程序不够完美,第一次写博客有很多漏洞,希望谅解!!!

硬件清单:LCD12864,ARDUINO MEGA2560,蓝牙模块,脑电波传感器,usb音响,树莓派3

功能解释:从脑电波模块中解析出人脑数据,实时切换字母,集中注意力采集目标值,目标值通过蓝牙发送给树莓派进行语音合成。

简单点说:用意念说话,根据你的生物电信号解析出信息,使用语音合成与人交流

存在bug,需要锻炼人的注意度和放松度,根据每个人生物电信号的强弱设置阈值,可能会引起误操作,说话速度慢(不可避免)

如果优化的好,可以用在植物人、哑巴、老年人身上,使用意念与他人交流。

程序如下:

/*
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 
#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 = 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字节
  }
}


有疑问者请联系:QQ:1735915513

 

你可能感兴趣的:(STM32,树莓派,PLC)