脳波を使ったおもちゃを作ってみた

# TL&DR
- 背景
- 脳波計
- できたもの
- 改善したいこと
- まとめ

# 背景
ESP32を使った温湿度計について紹介したが、どうせならオリジナルなものを作ってみたい！
ということで、興味があった脳波計を使っておもちゃを作ってみることにした。

## 脳波計って？
Neuro sky社が開発した脳波センサー付きヘッドセット:"[MindWave2](https://www.neurosky.jp/mindwave-mobile2/)"
このデバイスを装着すると
> α波・β波などのパワースペクトラムや、集中度・リラックス度などを取得することが可能。

とのこと。
詳しくはわからないが、なんかワクワクする・・・！（適当）

# 作ったもの：射的ゲーム！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316011/6c940d2f-90ae-8936-97d0-34dd282c696c.png)

・・・なのだが、銃の引き金をトリガとするのではなく、脳波計の計測値をトリガにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316011/2acc5422-2bf3-e47f-a1a7-23b3a4372406.png)
※イメージです


### 仕組み
1. 脳波計の集中力を示す値をノートPCで読み取る
2. 集中力が一定値を上回っている間、マイコンにポンプを駆動するよう命令する
3. マイコン側で駆動命令を受けている間ポンプを駆動し続ける
4. チューブ内の圧力が上がっていき、チューブ先に付けた"玉"が的に向かって発射される

# できること
- ESP32を使った簡単なおもちゃを作ることができる！
- 脳波計のデータを使ったアプリを作ることができる！！
- モータードライバを使った電子工作ができる！！！
    - ポンプやモーターを動かすので、電子工作やってる感が出る！！

# 使ったもの
- ノートPC
- マイコン：ESP32(Dev-KitC)　※開発環境：ArduinoIDE
- 脳波計(MindWave2)
    - 正確には[脳波センサー付ヘッドセット](https://www.neurosky.jp/mindwave-mobile2/)を今回は使用した
- デュアルモータードライバ([DRV8835](https://www.amazon.co.jp/POLOLU-2135-%E3%83%87%E3%83%A5%E3%82%A2%E3%83%AB%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90DRV8835/dp/B00R7EKBQA))
- [マイクロ真空ポンプ](https://www.amazon.co.jp/uxcell-a13082000ux0026-uxcell-%E6%B0%B4%E6%A7%BD%E3%81%AE%E9%85%B8%E7%B4%A0%E5%9B%9E%E8%B7%AFDC-6V%E3%83%9F%E3%83%8B%E3%82%A8%E3%82%A2%E3%83%BC%E3%83%9D%E3%83%B3%E3%83%97%E3%83%A2%E3%83%BC%E3%82%BF%E3%83%BC/dp/B00H52NPGM/ref=pd_lpo_60_t_1/358-4824087-0531725?_encoding=UTF8&pd_rd_i=B00H52NPGM&pd_rd_r=781962f0-0890-430a-9677-4acb697237df&pd_rd_w=x68O7&pd_rd_wg=Kd5Mg&pf_rd_p=4b55d259-ebf0-4306-905a-7762d1b93740&pf_rd_r=67YJAZ5Z5174DNJZE15J&psc=1&refRID=67YJAZ5Z5174DNJZE15J)
- [シリコンチューブ](https://www.amazon.co.jp/MGJG-3-0-Silicone-Tube-0-1-inches/dp/B00FGO7SXC/ref=pd_sim_60_4/358-4824087-0531725?_encoding=UTF8&pd_rd_i=B00FGO7SXC&pd_rd_r=5146eedd-b121-4952-9d10-993338e87482&pd_rd_w=lRdCv&pd_rd_wg=WBAAY&pf_rd_p=eb211d4f-9ce6-46da-bef2-e4b11fe6bb87&pf_rd_r=0BMA1Q1PDGV2ZHKGJP01&psc=1&refRID=0BMA1Q1PDGV2ZHKGJP01)
- 発射する玉（チューブ内に詰め込める丸くて軽いものであればなんでもOK）

※金額的には総額2万円くらい（脳波計が1.8万くらいだったので）

___
# 構造
## ソフトウェア
### PC側
主に以下のサイトを参考にさせていただいた。
- 「[MindWaveからPythonを使って脳波の値を取得し、好きなプログラムで利用する方法](https://mikenerian.hatenablog.com/entry/2017/12/18/222633#MindWave%E3%81%8B%E3%82%89%E5%80%A4%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)」
- [「脳波データから感情を推測するAIを作ってみる」](https://qiita.com/kousho/items/4a56c26a18973564db9a)

※NeuroPyモジュールの仕様？のため、python2.7で開発した
　ーpython3ではエラーが発生して動作しなかった（残念）

〇脳波計が取得した値を読み取る
Mindwave2とPCを無線接続した状態で信号を読み取る。
以下のコードで”neuroPy”に脳波計が取得したデータが格納される。

```python
def set_com(COM_to_connect):
    # input: com No.
    try:
        # 利用するCOMポートの設定
        ser_sig=serial.Serial(COM_to_connect, 9600, timeout=0.1)
    except:
        # 接続に不具合が生じた場合、COMポートを閉じる
        try:
            ser_sig.close()![MindWaveApp_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316011/d5d3c1e0-47a5-4f66-e16e-6f22d1334a0f.png)

        except:
            pass
    
    return ser_sig

if __name__ == '__main__':
    # prepare output of serial port.
    ser_esp = set_com(COM_for_ESP32)
    
    # mindwave 起動
    neuroPy=NeuroPy(COM_for_mind_wave)
    neuroPy.start()

    '''
    ※この間にやりたいことを書く
    '''

    # 測定終了
    neuroPy.stop()
    # ポートを閉じる
    ser_esp.close()
``` 

〇集中度に応じて、マイコンに信号を送る
"仕組み"にも記載した通り、集中度が一定値を超えている間ポンプを動かすため、以下のコードにした。
なお、ポンプを動かすのはPCと接続したESP32側のため、PCではシリアル信号を送付するのみである。

```python
if __name__ == '__main__':
    '''
    # ～ここから上は省略～
    '''
    neuroPy.start()
    
    # Ctrl+Cが入力されるまで続ける
    try:
        # シリアル信号を出力        
        if neuroPy.attention >= th_attension:
            # 集中度が閾値を超えていたら"o"を送信
            ser_esp.write("o") 
        elif neuroPy.highAlpha >= th_attension:
            # 集中度が閾値を超えていたら"o"を送信
            ser_esp.write("o") 
        else:
            # 集中度が閾値を下回っていたら"x"を送信
            ser_esp.write("x")

    except KeyboardInterrupt:   
        # 測定終了
        neuroPy.stop()
        # ポートを閉じる
        ser_esp.close()
``` 

### ESP32側
集中度に応じてPC側から送られる信号（〇 or ×）によって、ポンプ駆動するかどうかを決定する

```c
// 変数の定義
#define PUMP_PIN 13
 
// 初期化
void setup(){
  pinMode(PUMP_PIN , OUTPUT);
 
  // シリアルポートを9600 bps[ビット/秒]で初期化 
  Serial.begin(9600);
}
 
// 繰り返し処理
void loop(){
  int inputchar;
 
  // シリアルポートより1文字読み込む
  inputchar = Serial.read();
 
  if(inputchar != -1 ){
    // 読み込んだデータが -1 以外の場合　以下の処理を行う
 
    switch(inputchar){
      case 'o':
        // 読み込みデータが　o の場合
        Serial.print("PUMP ON\n");
        digitalWrite(PUMP_PIN, HIGH);
        break;
      case 'x':  
        // 読み込みデータが　x の場合
        Serial.print("PUMP OFF\n");
        digitalWrite(PUMP_PIN, LOW);
        break;
      case 'z':
        // 読み込みデータが　z の場合
        Serial.print("Reset\n");
        digitalWrite(PUMP_PIN, LOW);
        delay(1000 * 5); // 5sec wait
        break;
    }
  } else {
    // 読み込むデータが無い場合は何もしない
  }
}
``` 

## ハードウェア
接続自体は非常にシンプルだった。
・ESP32とPCは有線接続（USB）
・ポンプの先にはシリコンチューブと発射する玉を接続する
・LEDはポンプ駆動中を知らせるために接続した（無くてもOK）
・接続したイメージは図を参照
![MindWaveApp_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316011/a79661db-63f7-2f34-b602-daf3addda689.png)

# まとめ
　マイコンを使って「センシングしたデータをスマホに送る」ようなことだけでなく、ポンプ駆動、玉の発射と機械的な動作を加えることで難易度が上がった（個人的には）。
　このおもちゃを電子工作コンペのようなものに出展したところ、子供には受けが良かったが、大人からすると構造が簡単だったので評判はぼちぼち。次はデザイン的なところにも注力したい！