ArduinoでLEDを脳波に合わせて光らせるin development

 
date:2013.11.07   posted by:saito
 

こんにちは、まりもです。

Samuration」について技術的な側面から全3回に渡って解説しています。

内訳はこちら。
1. Mindwaveで脳波を取得する
2. ArduinoでLEDを脳波に合わせて光らせる
3. Kinectで竹を切るモーションを判定する

今日は前回のブログで掲載した「1. Mindwaveで脳波を取得する」の続き、
2. ArduinoでLEDを脳波に合わせて光らせる
を解説したいと思います。
C#からArduinoへ送信する上で問題がありましたので共有します。

■Arduinoとは
Aruduino(アルドゥイーノ)とは、オープンソースハードウェアであり誰でも自分で組み立てることができる基板です。
開発環境はProcessingベース。詳しいスペックはArduino公式サイトを御覧ください。

■実装
今回Arduinoの種類はArduino Uno、LEDはフルカラーシリアルLEDテープ(17cm)を4つ繋げて使いました。
Arduino側のコードはフルカラーシリアルLEDテープを光らせてみた。を参考にして、少し改変したものを実装させました。
C#とArduinoのつなぎ込みはserialportを使いました。
しかし、serialportを使ってArduinoを実装させるデバック作業が難しかったため、C#側で主な計算を行いました。

■C#からArduinoへ送信する上での問題点
当初、C#で算出したint値をserialPort1.Write(int値.toString());に変換し送っていたのですが、0~9までは正常にLEDに出力できましたが、10以上だとLEDの光がちらついてしまったりと、正しく出力されなくなってしまうバグが起きてしまいました。
予測ではint->Stringに変換した時に何らかの変化が起こってしまっているのだと思います。
そこで、1バイトでは正常に出力されていたということをもとに、2バイトである10以上の値はAやBなどの1バイトの記号に置き換えて送り、Arduino側で数値を入力しなおしたところ、正常に出力されました。
よって、switch文を使ったかなり力技なコードになってしまいましたが、なんとかきれいなイルミネーションを作ることに成功しました。
もっと良い方法があるはずなので、次にリリースするまでにはこの問題点を解消する予定です。

以下が実際に作品に使われたコードです。

-C#側

//生成
private System.IO.Ports.SerialPort serialPort1;

//初期化、ポート・バンド設定
serialPort1 = new System.IO.Ports.SerialPort();
serialPort1.PortName = "COM5"; //開発環境によって違うので自分で確認して下さい
serialPort1.BaudRate = 9600;
serialPort1.Open();

//ここから計算&Arduinoに送る処理
totalValue = 0;

//集中度が65以上であればLED光らせる処理
//集中度0~100
if (_thinkGearWrapper.ThinkGearState.Attention >= 65) value = (int)((_thinkGearWrapper.ThinkGearState.Attention - 64));
else value = 0;

//LEDの光を滑らかにする
array[val] = value;

for (int j = 0; j < N; j++)
{
  //ここで配列arrayに入っているvalueをtotalValueに入れる
  totalValue += array[j];
}

//平均を出す
averageValue = totalValue / N;

//averageValueをArduinoに送る
switch (averageValue)
{
  case 0:
     serialPort1.Write("0");
     break;
  case 1:
     serialPort1.Write("1");
     break;
  case 2:
     serialPort1.Write("2");
     break;
  case 3:
     serialPort1.Write("3");
     break;
  :
  :長いので省略
  :
  case 34:
     serialPort1.Write("Y");
     break;
  case 35:
     serialPort1.Write("Z");
     break;
  default:
     break;
}

//配列arrayの格納場所をひとつずらす
if (val == N - 1) val = 0;
else val++;


-Arduino側

//実際に光らせる処理をする関数colorWipeに代入
if(value == '0')
{
colorWipe(strip.Color( 0, 0, 0), DELAY_TIME);
}
else{
colorWipe(strip.Color(valueRed, valueGreen, 0), DELAY_TIME);
}

//受け取った値valueを光の強さに変換
if(value == '0' || value == '1' || value == '2' ||
value == '3' || value == '4' || value == '5' ||
value == '6' || value == '7' || value == '8' || value == '9'){
valueRed = (int)(value - '0');
}else if(value == 'A') valueRed = 10;
else if(value == 'B') valueRed = 11;
else if(value == 'C') valueRed = 12;
else if(value == 'D') valueRed = 13;
:
:長いので省略
:
else if(value == 'Y') valueRed = 34;
else if(value == 'Z') valueRed = 35;

valueGreen = (int)((valueRed)/2);

RGBでのオレンジはR:G:B=2:1:0なので、valueRedの半分の値をvalueGreenに入れました。
DELAY_TIMEは0です。

いかがでしたでしょうか。
次回は「3. Kinectで竹を切るモーションを判定する」を解説します。

work from home jobs in nc
 
Copyright © TheDesignium inc. powered by WordPress & mootools.
Relative Keyword|none