digispark FastLEDでイルミネーションを


これもよくありがちな題材ではありますが,楽しむつもりでやってみました。

使ったのはこれ。

テープ状にたくさん実装されたものを使うのも定番のようですが,リビングにちょこっと置くことを考えて,これにしてみました。

ライブラリーは, NeoPixel という名前で, Adafruit から提供されていました。また,調べていくと,FastLEDというライブラリーも存在しました。

使うチップですが,いくつか種類があるようでした。

結果としては,Adafruit, FastLEDどちらのライブラリーも,ほぼそのままで動きました。

何となくですが,FastLEDを以下では使いました。

#include <FastLED.h>
#define NUM_LEDS 8
#define DATA_PIN PB0
CRGB leds[NUM_LEDS];

#define MAX_LEDS 3

struct led {
  uint8_t position; // 0 to (NUM_LEDS - 1)
  uint8_t brightness; // 0 to 7. 0 is max brightness.
  int8_t brightnessChangeMode; // positive or negative
  uint16_t nextTime;
};

struct led led[MAX_LEDS] = {
  // position, initial brightness, mode, next time
  {0,  0,  1, 1},
  {2,  3,  1, 1},
  {4,  7, -1, 1}
};

uint32_t alarm1 = 0;

void setup() {
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
  FastLED.setBrightness(150);
}

void loop() {
  for (int i = 0; i < MAX_LEDS; i++) {
    leds[led[i].position].setRGB(
      (random(220, 256)) >> led[i].brightness,
      (random(220, 256)) >> led[i].brightness,
      (random(220, 256)) >> led[i].brightness);
    FastLED.show();
    delay(100);

    if (millis() / 1000 > led[i].nextTime) {
      led[i].nextTime += random(20, 40);
      if (led[i].brightness == 0) {
        led[i].brightnessChangeMode = 1;
      }
      if (led[i].brightness == 7) {
        led[i].brightnessChangeMode = -1;
        leds[led[i].position].setRGB(0, 0, 0);
        do {
          led[i].position = random(NUM_LEDS);
        } while (leds[led[i].position]);
      }
      led[i].brightness += led[i].brightnessChangeMode;
    }
  }
}

ああ, forループが意図せず二重になってますね... あとで直します... 修正しました。思い出しましたが,コンパイル時警告が出ますが,問題なく書き込み実行できます。

結線は,Digisparkから,電源,グランド,PB0を接続します。

すぐに光り出したのはいいのですが,恐ろしいほどの輝度です... FastLED.setBrightness(150); で全体が少し下がります。

さて,インテリアとして,どのように光らせるか,自信がありませんが,私のセンスが問われますね...

  • 基本的に「白」く光らせることにしました。リビング内は「電球色」の照明が多いのですが,多少人工的,それでも人工的過ぎず,ということで決めてみました。
  • 「星のまたたき」をイメージして,少し「チラチラ」させてみました。試した結果,random(220, 256)を用いて,RGBの各値を「少しだけ減らす」と,いい具合に「チラチラ」しました。
  • 薄暗いところからスタート,だんだん明るくし,また徐々に暗くして,最後は消えて別の場所に,という感じにしました。ある程度明るい時に突然別の場所に写すと,「人工的な感じ」がするように思えたからです。
  • 8個中,3個光らせることにしました。「次への移動場所」はランダムに決めるのですが,すでに光っている場所でも良いことにしました。したがって,全体として2個だけ光っている時もあるのですが,まあそれも「いい感じ」のように思えました。

スケッチ作成で気をつけた,および気づいたところです。

  • 初めて「構造体」を使って3個のLEDのデータ整理をしました。今時はclassを使うべきなのかもしれませんが,まだその方法は知りませんし...
  • 個々のLEDの輝度を変える方法がわかりません。そのため,各RGB値を減らしていく,という方法にしました。この方法により,色味を維持しながら暗くすることができました。厳密な方法ではないかと思いますが,今回はこれで十分かと。この部分です。
    leds[led[i].position].setRGB(
      (random(220, 256)) >> led[i].brightness,
      (random(220, 256)) >> led[i].brightness,
      (random(220, 256)) >> led[i].brightness);

以下のページを参考にさせていただきました。まとめて感謝いたします。