LoginSignup
2
1

More than 3 years have passed since last update.

【micro:bit × Processing】魔法を使ってる風を装ってみる

Last updated at Posted at 2020-07-29

はじめに

最近Processingにはまり、この前の4連休はジェネラティブアート作って遊んでいました。
「ハァッ!」とか叫んで手を振るとブワッと円が描画されたら魔法的な雰囲気を醸し出せて楽しいのでは...?と思いmicro:bitの力を借りて作ってみました。
スクリーンショット 2020-07-30 0.04.52.png
▼動かしている動画はこちら
https://twitter.com/rntkym0618/status/1287712456442175488?s=20

用意するもの

  • micro:bit
  • Micro USBケーブル
  • ProcessingをダウンロードしたPC
  • PCとMicro USBケーブルを接続するアダプター
  • micro:bitを固定する手袋(薬局に売っている綿手袋を改造)

何気に手袋にmicro:bit入れるポケット縫うのが一番しんどかった。
え、裁縫ってこんなに難しかったっけ??家庭科の授業でエプロン作れた小学生の私と同一人物??と困惑してます。
スクリーンショット 2019-11-27 22.07.40.png

micro:bitのブロック

ブロック全体はこちら

ジェスチャーと対応する光の挙動

micro:bitで特定のジェスチャーを取得して、その情報をシリアル通信でProcessingに送ります。

ジェスチャー 光(円)の挙動
左に傾ける 小さな光が左に動く
右に傾ける 小さな光が右に動く
奥に傾ける 小さな光が上に動く
手前に傾ける 小さな光が下に動く
手を垂直に勢いよく前へ押す 画面いっぱいに光る
手を水平に勢いよく横に動かす 横一直線に光る

傾きの取得

micro:bitでは「どの方向にどれだけ傾いたか」という数値を取ることができます。

  • ロール:左右の傾きを取得 / 値の範囲は-180° ~ 180°
  • ピッチ:上下の傾きを取得 / 値の範囲は-90° ~ 90° スクリーンショット 2020-07-29 22.47.28.png

勢いの取得

micro:bitでは「どの方向にどれだけはやく動いたか」という数値を取ることができます。
x, y, z, 3軸の絶対値の加速度を取ることができるようで、今回は絶対値を使いました。
スクリーンショット 2020-07-29 23.06.04.png

micro:bitを動かして値を観察してみると、ぶんぶん動かした時に値が2000程度になったので「勢いよく動かした」と判断する境界を加速度2000に定めました。

Processingのコード

コード全体はこちら

micro:bitとのシリアル通信

こちらの記事を参考にさせていただきました!
Serial.list()に接続できるポートのリストが格納されています。micro:bitはusbmodemの方で1番目に格納されてました。
115200はUSBシリアル通信の通信速度らしいです。(bps)
bufferUntil(10)によって改行を読み取ったらserialEventを呼び出します。

magic_glove.pde
import processing.serial.*;
Serial microbit;

void setup() {
  surface.setSize(1500, 900); 

  microbit = new Serial(this, Serial.list()[1], 115200);
  microbit.bufferUntil(10);
}

呼び出されたserialEventがこちら。ここで読み取った情報を整形していきます。
改行まで読んで一つの文字列に格納 → micro:bitではカンマ区切りで情報を送ってたのでカンマ区切りで配列に格納 → 1つ1つ変数に格納、といった流れです。

magic_glove.pde
void serialEvent(Serial microbit) {
  String str = microbit.readStringUntil('\n');
  String[] info = str.split(",");
  if(info.length == 5){
    x = float(info[0]);
    y = float(info[1]);
    attribute = float(info[2]);
    magic1 = float(info[3]);
    magic2 = float(info[4]);
  }
}

受け取った値をもとに描画する

ランダムって...面白!!...この一言に尽きる。

magic_glove.pde
int order = 0;
float red, green, blue, opacity, x, y, size, attribute, magic1, magic2;

void draw() {
  int volume = 1;
  background(0);

  //ジェスチャーによって表示される円の数(volumeの値)を設定
  if(magic1 == 1 || magic2 == 1){
    volume = 200;
    order = 0;
  }

  for(int i = 0; i < volume; i ++){
    //不透明度の設定
    opacity = random(200);

    //micro:bitのボタンを押すことで変化するattributeの値によってRGB値を設定
    if(attribute == 1){
      red = random(50);
      green = random(100, 150);
      blue = random(150);
    }
    //分岐で同じようなコードが続くので省略

    //描画される円の位置とサイズをジェスチャーによって場合分け
    if (magic1 == 1){
      x = random(width);
      y = height / 2 + random(-50, 50);
      size = random(100);
    }
    else if(magic2 == 1){
      x = random(width);
      y = random(height);
      size = random(200);
    }
    else{
      x = x + random(-20, 20);
      y = y + random(-20, 20);
      size = random(50);
    }

    //設定した値をまとめて描画する用の配列に格納
    float[] args = {red, green, blue, opacity, x, y, size};
    array[order] = args;

    //まとめて描画する円は300個までとして、それ以降は上書きする
    order += 1;
    if(order == 300){
      order = 0;
    }
  }

  //円を描画。drawが呼ばれる度に円の大きさを小さくするように更新していく
  for(int i = 0; i < 300; i ++){
    fill(array[i][0], array[i][1], array[i][2], array[i][3]);
    noStroke();
    ellipse(array[i][4], array[i][5], array[i][6], array[i][6]);
    array[i][6] -= 1;
    if(array[i][6] < 0){
      array[i][6] = 0;
    }
  }
}

最後に

手袋をもっとこう...格好良くしたい

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1