意念控制四旋翼 學習筆記

      第一部分:模塊原始數據 

      拿到模塊,在網上查了一圈,發現基本沒什麼有用的資料,很多都是一些相關但是沒有實際價值的東西。許多論文都是再談怎麼去做,而沒有實實在在的去完成這麼一個過程。

       廢話不多說,直接步入正題。

       

          昨天在網上才發現這個軟件,據評論說是這款串口軟件很好用。

          RealTerm的下載地址https://realterm.sourceforge.io/       

          這是通過單片機的232通信例程直接接收得到的原始數據,也就是參考手冊中的數據流。其中小包數據,是每秒512個大概,大包數據是每秒1個。

       小包的格式是AA AA 04 80 02 xxHigh xxLow xxCheckSum前面的AA AA 04 80 02 是不變的,後三個字節是一隻變化的,xxHigh和xxLow組成了原始數據rawdata,xxCheckSum就是校驗和。所以一個小包裏面只包含了一個對開發者來說有用的數據,那就是rawdata,可以說一個小包就是一個原始數據,大約每秒鐘會有512個原始數據。
      從小包中解析出原始數據:

rawdata = (xxHigh << 8) | xxLow;

  if(rawdata > 32768){   rawdata ­=65536;  }

      根據手冊,在計算原始數據之前,要先檢查檢驗和:

sum = ((0x80 + 0x02 + xxHigh + xxLow)^ 0xFFFFFFFF) & 0xFF。

     就是把頭文件AA AA 04後面的四個數據加起來,取反,在取低八位。當檢驗碼不對時,直接丟棄該包。

     在大包數據裏面可以解析Signal,Attention,Meditation和8個EEG的信號值,大包的格式是固定的:

AA 同步
AA 同步
20 是十進制的32,即有32個字節的payload,除掉20本身+兩個AA同步+最後校驗和
02 代表信號值Signal
C8 信號的值
83 代表EEG Power開始了
18 是十進制的24,說明EEG Power是由24個字節組成的,以下每三個字節爲一組
18 Delta 1/3
D4 Delta 2/3
8B Delta 3/3
13 Theta 1/3
D1 Theta 2/3
69 Theta 3/3
02 LowAlpha 1/3
58 LowAlpha 2/3
C1 LowAlpha 3/3
17 HighAlpha 1/3
3B HighAlpha 2/3
DC HighAlpha 3/3
02 LowBeta 1/3
50 LowBeta 2/3
00 LowBeta 3/3
03 HighBeta 1/3
CB HighBeta 2/3
9D HighBeta 3/3
03 LowGamma 1/3
6D LowGamma 2/3
3B LowGamma 3/3
03 MiddleGamma 1/3
7E MiddleGamma 2/3
89 MiddleGamma 3/3
04 代表專注度Attention
00 Attention的值(0到100之間)
05 代表放鬆度Meditation
00 Meditation的值(0到100之間)
D5 校驗和

      想要獲得某個EEG信號值,只需將相應信號的1/3值左移16位,2/3值左移8位,3/3值不變,然後將他們或運算:

delta=(payload[i]<<16) | (payload[(i+1)]<<8)  | (payload[(i+2)])。

第二部分:串口接收處理

將數據處理移植到STM32上,採用串口的DMA接收模式,注意的是DMA_MODE採用Circular,DMA_BufferSize>(8*512+36=4132)(小包8個字節,每秒512個,完整的大包36個字節)。

代碼如下:

void usart_init()
{
    //聲明結構體//
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    
    //時鐘打開//
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//DMA1時鐘
    
    //GPIO配置//
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    //USART配置//
    USART_InitStructure.USART_BaudRate=57600;
    USART_InitStructure.USART_WordLength=USART_WordLength_8b;//傳送數據長度
    USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位長度
    USART_InitStructure.USART_Parity=USART_Parity_No;//校檢
    USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流DMA
    USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//接受發送
    USART_Init(USART1,&USART_InitStructure);
    USART_Cmd(USART1,ENABLE);
}    
 //DMA接收//
    void USART1_DMA_Recv(void)
 {
     
     DMA_InitTypeDef DMA_InitStructure;    
     NVIC_InitTypeDef NVIC_InitStructure;
     
     DMA_InitStructure.DMA_PeripheralBaseAddr=(u32)&(USART1->DR);//外設基地址
     DMA_InitStructure.DMA_MemoryBaseAddr=(u32)&buffer;//內存基地址
     DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//SRC作爲數據傳送的來源
     DMA_InitStructure.DMA_BufferSize=5000;//數據傳輸長度!!!!!!
     DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外設地址不自增
     DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//內存地址自增
     DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外設數據單位字節
     DMA_InitStructure.DMA_MemoryDataSize=DMA_PeripheralDataSize_Byte;//內出數據單位
     DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//傳輸模式!!!!!
     DMA_InitStructure.DMA_Priority=DMA_Priority_High;//優先級
     DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//禁止內存到內存傳輸
     DMA_Init(DMA1_Channel5,&DMA_InitStructure);
     DMA_ClearFlag(DMA1_FLAG_TC5);
     
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel5_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
     NVIC_Init(&NVIC_InitStructure);
     
     DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE);//DMA1傳送完成產生中斷
     USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
     DMA_Cmd(DMA1_Channel5,ENABLE);
    }

      void DMA1_Channel5_IRQHandler(void)//中斷函數
{  
     if (DMA_GetITStatus(DMA1_IT_TC5)==1)
         {
        DMA_ClearITPendingBit(DMA1_IT_TC5); 
        DMA_Cmd(DMA1_Channel5, DISABLE);
        flag = 1;  //將下面的程序放到main的while中,不然運行容易丟包
//          for(i=0;i<5000;i++)
//              {
//                    parseByte( buffer[i]);
//              }
//          DMA_Cmd(DMA1_Channel5,ENABLE);
    }
}

這部分代碼還需要進一步修改……我們是依靠藍牙傳輸信號,在下面會解決如何通信的問題。

下一部分將會講述當STM3原2接收到始數據後,怎樣將它處理後得到signal,attention,meditation和eeg信號的值

第三部分:數據解析

待續……通信協議部分還是比較關鍵的

第四部分:數據通信

這一部分在我另一篇文章裏有示例性的圖文介紹

https://blog.csdn.net/seek97/article/details/81333701

我使用的是HC05和BT06倆個藍牙模塊

1、【AT模式】HC05藍牙模塊的PIO11接VCC,上電後即進入HC05AT指令模式,對於BT06藍牙直接上電進入AT模式,用USBT06轉TTL模塊連接到電腦的USBT06接口。

2、【打開串口調試助手】開啓2個串口調試窗口,一個打開HC05的COM口,一個打開BT06的COM口。【HC05默認波特率一般爲38400,BT06默認是9600】.

3、【恢復HC05默認設置】串口調試助手HC05,將HC05恢復默認設置:AT+ORGL【即回車、換行,在串口調試助手上輸入一個回車即可】

4、【設置HC05配對碼】串口調試助手HC05,配置藍牙HC05的配對碼:AT+PSWD=1234【藍牙HC05與藍牙BT06的配對碼相同,這樣才能成功配對,配對碼隨意】

5、【設置HC05主模式】串口調試助手HC05,將藍牙HC05配置爲主機模式:AT+ROLE=1

6、【恢復BT06默認設置】串口調試助手BT06,將藍牙BT06恢復默認設置:AT+ DEFAULT 

7、【設置BT06配對碼】串口調試助手BT06,配置藍牙BT06的配對碼與藍牙HC05一致:AT+PIN 1234

8、【設置BT06從模式】串口調試助手BT06,將藍牙BT06配置爲從機模式:AT+ ROLE

9、【 查詢BT06地址 】串口調試助手BT06,查詢藍牙BT06的地址:AT+LADDR    【如20:15:02:12:07:58】

10、【藍牙HC05綁定藍牙BT06】串口調試助手HC05,藍牙HC05綁定藍牙BT06地址:AT+BIND=0101,01,010101    

【注意把地址的冒號換成逗號,同時注意這個格式,實驗多次,只有這樣寫,HC05纔可以綁定該地址】

11、【設置波特率】根據各自的命令符號修改各自的波特率 HC05:AT+UART=57600,0,0。BT06:AT+BAUD7.

12、【常規工作模式】2個模塊斷電,重新上電後進入常規工作模式,自動完成配對。之後, HC05就能接收到BT06的數據了。

【注意事項】:確保2個藍牙模塊的配對碼(PSWD)相同,都上電後兩個模塊會自動相連。

【設置藍牙的連接模式】:默認是:0—指定藍牙地址連接模式,這樣HC05才能自動連接綁定的地址,如果不是模式0,設置爲模式0:AT+CMODE=0

第五部分:數據處理

待續……這部分會涉及一些算法,比如BP神經網絡模型提速特徵值

第六部分:系統控制

待續……這部分比較簡單,把小四軸的代碼理解完成,也就可以實現控制了。

第七部分:論文寫作

待續....這部分應該貫穿於整個項目研究過程,注重將學習成果記錄

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章