複数のアドレサブルRGBデバイスをアニメーションする

ALEDクラスには、複数のアドレサブルRGBデバイスに異なる模様やアニメーションを描写する機能が装備されています。本記事では、ParallelAnimationクラスを使う方法と、複数のチャネルをグループ化したALEDクラスを作成する方法について、スケッチを動かしながら解説しました。この機能を使えば、少ないコードで複数のチャネルに異なるイルミネーションをさせることが可能になります。

本記事はArduino互換機「CG-CustomARGB」を使ったアドレサブルRGBプログラミングチュートリアルの一部です。

更新日 : 2020年5月19日

各チャネルに異なるイルミネーションを出力する必要性

これまでのチュートリアル記事では、全てのチャネルに同じイルミネーション(模様、アニメーション)を描写していました。具体的には、以下のように1つのALEDクラスを作成し、全チャネルに同じデータを出力していました。

ALED aled(CH1 | CH2 | CH3 | CH4 | CH5, 34);

この方法は、同じアドレサブルRGBデバイスを複数接続し、同じイルミネーションを表示したい場合は問題ありませんが、以下のような場合には対応できません。

異なるアドレサブルRGBデバイスを接続する場合

デバイスによってLEDの数や配置が異なるため、それぞれに合わせた模様を描写しないと綺麗に見えない場合があります。

チャネルごとに異なるイルミネーションを描写したい場合

複数のデバイスを順番に点灯させたり、デバイス間で連携するようなイルミネーションにしたい場合があります。また、同じデバイスであっても、表裏や向きが異なるように設置されていると、異なる模様を描写したい状況が出てきます。

ALEDクラスには、こういった課題を解決する機能が装備されています。大きく分けて2つの方法があります。

  1. チャネルごとに複数のALEDクラスを作成し、ParallelAnimationクラスを使ってアニメーションする
  2. 複数のチャネルをグループ化したALEDクラスを作成し、あたかも1つのデバイスのように制御する

これらの方法について、実際にスケッチを動かしながら解説していきます。

異なるイルミネーションを描写する

複数のALEDクラスを同時アニメーションするスケッチ「ParallelAnimation」

まずは「1. チャネルごとに複数のALEDクラスを作成し、ParallelAnimationクラスを使ってアニメーションする」方法を試すスケッチを用意しました。以下からダウンロードして下さい。

書き込む前に、ParallelAnimation.inoの7, 8行目の最後の引数をお使いのデバイスの制御可能LED数に変更します。7行目がチャネル1、8行目がチャネル2に接続するデバイスに対応します。それぞれのチャネルにデバイスを接続しておいて下さい。

// アドレサブルRGB制御用のALEDクラスを使う
//  チャネルを分けて複数のALEDクラスを作成すると、それぞれ異なる模様にしたり、
//  それぞれのデバイスのLED数にあわせて模様を描写できる。
//  LED数は使うデバイスに合わせる
ALED aled1(CH1, 18);  // チャネル1を制御するaled1を作成
ALED aled2(CH2, 16);  // チャネル2を制御するaled2を作成

変更できたらスケッチを書き込んで動作させてみましょう。以下のように動けば成功です。

  1. チャネル1に虹色模様になり、4周アニメーションする
  2. チャネル2にLED1つが点灯する模様になり、4周アニメーションする
  3. チャネル1とチャネル2が両方とも4周アニメーションする

ParallelAnimationスケッチ解説

10-13行目
// 複数のALEDクラスを並行してアニメーションさせるParallelAnimationクラスを作成
//  引数には登録するaled1とaled2の参照(「&」を前につける)を渡す
//  最大5個(5チャネル分)登録できる
ParallelAnimation parallel(&aled1, &aled2);

ここで、複数のALEDクラスを同時にアニメーションしてくれるParallelAnimationクラスを、「parallel」という名前で作成しています。引数には同時アニメーションしたいALEDクラスを最大5つまで指定できます。

指定する際は先頭に「&」を付けた参照を使います。というのも、ALEDクラスは既に7-8行目でaled1とaled2という名前で作成(インスタンス化)済なので、そこを参照させる形になるからです。

24-39行目
  // チャネル1の模様、アニメーションを指定する
  aled1.color.hue = 0.0f;
  aled1.color.sat = 100.0f;
  aled1.color.val = 100.0f;
  aled1.colorPattern.hue = 360.0f;
  aled1.pattern = ALED::patGrad;  // グラデーション模様を選択
  aled1.posChange = 2.0f;         // 移動アニメーション

  // チャネル2の模様、アニメーションを指定する
  aled2.color.hue = 0.0f;
  aled2.color.sat = 100.0f;
  aled2.color.val = 100.0f;
  aled2.colorPattern.hue = 360.0f;
  aled2.pattern = ALED::patPoint1;  // LEDを1つずつ変更する模様を選択
  aled2.posChange = 2.0f;           // 移動アニメーション
  aled2.colorChange.hue = 2.0f;     // 色変化アニメーション

aled1とaled2にそれぞれ模様とアニメーションのパラメーターを設定しています。今回の目的である、異なる模様を表示するようにしました。ParallelAnimationクラスはアニメーションの時間を調整するだけなので、模様の描写やアニメーションのパラメーターは、それぞれのALEDクラスで設定します。

43-45行目
  // ALEDクラスのアニメーションを使うと1チャネルしかアニメーションできない
  aled1.animation(200);
  aled2.animation(200);

この部分は、これまでのようにALEDクラスのanimation関数を呼び出した場合どうなるかの実験です。aled1のanimation関数だとチャネル1のデバイスしかアニメーションできないことが分かると思います。aled2でも同様です。

47-48行目
  // ParallelAnimationクラスを使うと複数同時にアニメーションできる
  parallel.animation(200);

ParallelAnimationクラスを使うことで、チャネル1、2を同時にアニメーションすることができます。内部的にはParallelAnimationクラスのperiodで設定した周期になるように調整しながら、aled1とaled2のdraw関数を呼び出して模様を描写する仕組みになっています。そのため、この機能を使う場合はparallelで設定したperiodが優先され、aled1とaled2のperiodは無視されます。(デフォルトではいずれも33msに設定されており、特に変更する必要はありません)

複数のチャネルをグループ化して1つのデバイスのように制御するスケッチ「GroupAnimation」

次は「2. 複数のチャネルをグループ化したALEDクラスを作成し、あたかも1つのデバイスのように制御する」方法を試すスケッチを用意しました。以下からダウンロードして下さい。

書き込む前に、GroupAnimation.inoの7行目の2つめ以降の引数をお使いのデバイスの制御可能LED数に変更します。2つめがチャネル1、3つめがチャネル2に接続するデバイスに対応します。それぞれのチャネルにデバイスを接続しておいて下さい。

// アドレサブルRGB制御用のALEDクラスを使う
//  3つめ以降の引数にもLED数を指定することで、複数のチャネルをまとめて(グループ化)
//  1つのデバイスのように制御することができる。最大5チャネル全てをグループ化できる。
//  LED数は使うデバイスに合わせる
ALED aled(CH1 | CH2, 18, 18);  // チャネル1と2グループ化して1つのデバイスのように制御するaledを作成

変更できたらスケッチを書き込んで動作させてみましょう。以下のように動けば成功です。

  1. グループ化したデバイス全体に対して1つのLEDが移動するアニメーション
  2. グループ化したデバイス全体に対して1つずつLEDが変化するアニメーション
  3. グループ化したデバイス全体に対してグラデーション模様が移動するアニメーション

GroupAnimationスケッチ解説

3-7行目
// アドレサブルRGB制御用のALEDクラスを使う
//  3つめ以降の引数にもLED数を指定することで、複数のチャネルをまとめて(グループ化)
//  1つのデバイスのように制御することができる。最大5チャネル全てをグループ化できる。
//  LED数は使うデバイスに合わせる
ALED aled(CH1 | CH2, 18, 18);  // チャネル1と2グループ化して1つのデバイスのように制御するaledを作成

今回の例ではチャネル1とチャネル2に同じLED数18のファンを接続し、この2つをグループ化してあたかもLED数36個の1つのデバイスのように制御します。実はこのALED宣言部分が異なるだけで、これ以降の模様の描写やアニメーションについては、これまでのALEDクラスと全く同じ使い方ができます。

チャネル数と引数を増やせば最大5チャネル全てをグループ化できます。異なるLED数のデバイスでも構いません。以下は5チャネル全てグループ化するコードです。

ALED aled(CH1 | CH2 | CH3 | CH4 | CH5, 18, 18, 16, 10, 20);

チャネルは連続していなくても構いませんが、LED数の指定は若いチャネルから順番に指定して下さい。以下はチャネル2と4をグループ化するコードです。

ALED aled(CH2 | CH4, 18, 16);
25-29行目
  // 1つのLEDが移動するアニメーション
  aled.pattern = ALED::patPoint1;
  aled.posChange = 2.0f;        // 移動アニメーション
  aled.colorChange.hue = 3.6f;  // 色変化アニメーション
  aled.animation(101);  // 最後のLEDを消灯するため、101ステップにしている

1つのLEDが移動するアニメーションです。グループ化されているので、チャネル1の最後のLEDの次はチャネル2の先頭のLEDが点灯します。チャネル2の最後のLEDの後はチャネル1の先頭に戻る、という具合です。

なおアニメーションが101ステップになっているのは、次の模様にスムーズに移行するためで、グループ化とは関係ありません。100ステップだと最後のLEDが点灯したまま残る場合があります。

31-33行目
  // 1つずつLEDが変化するアニメーション
  aled.pattern = ALED::patPoint2;
  aled.animation(99);

今度はLEDが1つずつ変化していくアニメーションです。こちらも複数のチャネルがグループ化してあたかも1つのように振る舞うのが分かると思います。

35-40行目
  // グラデーション模様が移動するアニメーション
  aled.pattern = ALED::patGrad;
  aled.colorPattern.hue = 360.0f;
  aled.posChange = 1.0f;        // 移動アニメーション
  aled.colorChange.hue = 0.0f;  // 色変化アニメーションを停止
  aled.animation(100);

最後はグラデーション模様です。グループ化しない時は1デバイスに赤〜紫まで色が360°変化していたと思いますが、グループ化しているのでチャネル1とチャネル2合計で360°変化するような動作になります。

まとめ

ALEDクラスには、複数のアドレサブルRGBデバイスに異なる模様やアニメーションを描写する機能が装備されています。本記事では、ParallelAnimationクラスを使う方法と、複数のチャネルをグループ化したALEDクラスを作成する方法について、スケッチを動かしながら解説しました。この機能を使えば、少ないコードで複数のチャネルに異なるイルミネーションをさせることが可能になります。

注意点としては、多くのデバイスに異なるイルミネーションをさせるほど、色の計算にかかる時間が長くなります。デフォルトの33ミリ秒(30Hz)で間に合わないような場合は、ALEDクラスもしくはParallelAnimationクラスのperiodを長くするなどして対応して下さい。

LEDの並び順を変更する

ALEDクラスのscrメンバ変数を変更することで、アニメーションや模様を描写する際のLEDの並び順を変更する方法について解説しました。この機能を使うことで、LEDの配置を意識したイルミネーションを作成できるようになります。