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


TL&DR

  • 背景
  • 脳波計
  • できたもの
  • 改善したいこと
  • まとめ

背景

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

脳波計って?

Neuro sky社が開発した脳波センサー付きヘッドセット:"MindWave2"
このデバイスを装着すると

α波・β波などのパワースペクトラムや、集中度・リラックス度などを取得することが可能。

とのこと。
詳しくはわからないが、なんかワクワクする・・・!(適当)

作ったもの:射的ゲーム!

・・・なのだが、銃の引き金をトリガとするのではなく、脳波計の計測値をトリガにした。

※イメージです

仕組み

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

できること

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

使ったもの

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


構造

ソフトウェア

PC側

主に以下のサイトを参考にさせていただいた。
- 「MindWaveからPythonを使って脳波の値を取得し、好きなプログラムで利用する方法
- 「脳波データから感情を推測するAIを作ってみる」

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

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

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ではシリアル信号を送付するのみである。

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 ×)によって、ポンプ駆動するかどうかを決定する

// 変数の定義
#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)
・接続したイメージは図を参照

まとめ

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