めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

OpenSiv3DでLチカをエミュレーション

こんにちは、めのんです!

金曜日の夜からLチカに挑戦しています。 LチカというのはLEDをチカチカ点滅させることなんですが、普通に簡単な回路を作ってのLチカでは当たり前すぎて面白くありません。 そこでsACNという業務用の照明制御のためのネットワークプロトコルを使ったLチカに挑戦中です。

これまでも何度も書きましたが、本物のLED器具を用意するのはコストも馬鹿になりませんし場所も取ります。 そこでOpenSiv3Dでエミュレーションしようということになりました。 本物のLED器具とイーサネットDMX変換を行うノードと呼ばれている装置があれば結線だけで済むんですけどね(あっ、サスペンションバトンに釣ったりするのは手間です💧)。

エミュレーションといっても全然大したことはありません。 LED器具に見立てた円に、sACNで送られてきたデータをもとに色を付けるだけです。

f:id:elddiry:20200712125346p:plain

以前にも書きましたがsACNで扱うデータはDMX512-A(通称DMX)という規格が基本になっていて、DMXでは512バイト(512チャンネルというそうです)で1セットになっています。 RGBの3チャンネルで制御するLEDだと、512÷3=170.066...なので170台まで制御することができます。 今回は横に17台、縦に10台を並べることにしました。

sACNで受信したデータを適用するのは次回以降に回すとして、今回はサンプルとして順に色相を変化させるようにしてみました。 ずっと同じだと面白くないので、36秒で1周するように少しずつ変化させています。

簡単ですのでソースコードを貼っておきますね。

# include <Siv3D.hpp> // OpenSiv3D v0.4.3

void Main()
{
    const auto 幅 = Scene::Width();
    const auto 高さ = Scene::Height();
    constexpr int 行数 = 10;
    constexpr int 列数 = 17;
    const auto 器具ピッチ = 幅 / 列数;
    const int 器具直径 = 器具ピッチ - 2 * 2;
    const auto 器具半径 = 器具直径 / 2.0;
    const auto 上端位置 = (高さ % (器具ピッチ * 行数)) / 2.0;
    const auto 左端位置 = (幅 % (器具ピッチ * 列数)) / 2.0;

    while (System::Update())
    {
        auto 色相 = std::fmod(Scene::Time() * 10, 360.0); // 36秒で1周
        for (int row = 0; row < 行数; row++)
        {
            for (int column = 0; column < 列数; column++)
            {
                const auto x = 左端位置 + 器具ピッチ * column + 器具ピッチ / 2.0;
                const auto y = 上端位置 + 器具ピッチ * row + 器具ピッチ / 2.0;
                Circle(x, y, 器具半径).draw(HSV(色相, 1, 1, 1));
                色相 = std::fmod((色相 + 1), 360.0);
            }
        }
    }
}

今回はあえて変数名を日本語にしてみました。 こんな風に識別子を日本語にするとコメントは本当に最小限で済みますね。

今回はこれぐらいにしておきたいと思います。

それでは!!