NeoPixelリングに使えるエフェクト実装例集


NeoPixelリングに使えそうなエフェクトをいろいろと自作してみました。
テープ状のLEDとリング上のLEDで向いているエフェクトがちょっと異なる気もしますが、今回はリング向けです。

サンプルは、Arduino UNOで動作を確認しています。

事前準備

Arduino IDEのセットアップして、ArduinoとNeoPixelリングを接続します。

NeoPixel制御用ライブラリのインストール

ライブラリはAdafruit_NeoPixelを使用します。
以下の手順で追加します。

  1. Arduino IDEのメニューから[ツール] > [ライブラリを管理…]を選択してライブラリマネージャを開きます。
  2. 「NeoPixel」で検索して「Adafruit NeoPixel by Adafruit」をインストールします。

Arduino UNOとNeoPixelリングを接続

以下の配線図に従ってArduino UNOとNeoPixelリングをつなぎます。

対応表

Arduino NeoPixelリング
DIGITAL 6 IN
5V V+
GND GND

Adafruit_NeoPixelの基本的な使い方

Adafruit_NeoPixelの使い方を以下のスケッチ例を使って説明します。

こちらは、GithubのREADMEにも載っている例simpleと同じです。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500

void setup() {
  pixels.begin(); // NeoPixel出力ピンの初期化
}

void loop() {
  pixels.clear(); // すべてのLEDの色を0にセット

  for(int i=0; i<NUMPIXELS; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 150, 0));
    pixels.show();
    delay(DELAYVAL);
  }
}

Adafruit_NeoPixelのコンストラクタには、以下の値を渡します。

  1. LEDの数
  2. 信号用のピン番号
  3. パーツの型を表すフラグ
    • NEO_KHZ800 800 KHz 通信周波数 (w/WS2812を積んでいるほとんどのNeoPixel製品に対応)
    • NEO_KHZ400 400 KHz (classic ‘v1’ (not v2)のFLORAシリーズ,その他WS2811を積んでいる製品に対応)
    • NEO_GRB GRB形式で通信 (ほとんどのNeoPixel製品に対応)
    • NEO_RGB RGB形式で通信 ([‘v1′(not v2)のFLORAシリーズ])
    • NEO_RGBW RGBW形式で通信 (NeoPixel RGBW製品)

setPixelColorメソッドは、第1引数にLEDの番号、第2引数に32ビットの符号なし整数で色を指定するものを使用しています。

エフェクトサンプル

以下、主要なエフェクト実装してみます。

実装方針としては、loop関数ごとにエフェクトのステップを進めるようにしてみます。
そのように実装するメリット措置手は、ステップの位置に関わらずいつでも割り込みの処理を入れられるようになります。

サークル

順番に1つのLEDを点灯させます。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 100

int step_num = 0;

void setup() {
  pixels.begin();
}

void loop() {
  pixels.clear();
  pixels.setPixelColor(step_num, pixels.Color(0, 150, 0));
  pixels.show();
  delay(DELAYVAL);

  if (++step_num == pixels.numPixels()) {
    step_num = 0;
  }
}

ワイプ (フィル)

ワイプも順番に1つのLEDを点灯させますが、サークルとの違いは、インターバルが終わるまで点灯したままにします。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 100

int step_num = 0;

void setup() {
  pixels.begin();
}

void loop() {
  if (step_num == pixels.numPixels()) {
    step_num = 0;
    pixels.clear();
  }

  pixels.setPixelColor(step_num, pixels.Color(150, 0, 0));
  pixels.show();
  delay(DELAYVAL);
  step_num++;
}

フェードイン/フェードアウト

フェードイン/フェードアウトを繰り返します。
パーツの特性か、DELAYVALを長くしてもあまり期待通りの光方にはなりません。短めで使うのが良さそうです。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 5

int step_num = 0;
int delta = 1;
int color[] = {255, 255, 0};

void setup() {
  pixels.begin();
}

void loop() {
  if (step_num == 0) {
    delta = 1;
  }else if (step_num == 255) {
    delta = -1;
  }

  float ratio = step_num / 255.0;
  for(int i = 0; i < NUMPIXELS; i++ ) {
    pixels.setPixelColor(i, pixels.Color(color[0] * ratio, color[1] * ratio, color[2] * ratio));
  }
  pixels.show();

  step_num += delta;
  delay(DELAYVAL);
}

シアターチェース

サークルとだいたい同じですが、名前の通り昔のアメリカの劇場のネオンにありそうなエフェクトです。

この例では、3個ごとに点灯させて回しています。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 500

int step_num = 0;
uint32_t color = pixels.Color(127, 127, 127);

void setup() {
  pixels.begin();
}

void loop() {
   pixels.clear();
   for(int c = step_num; c < pixels.numPixels(); c += 3) {
     pixels.setPixelColor(c, color);
   }
   pixels.show();
   if (++step_num == 3) {
     step_num = 0;
   }
   delay(DELAYVAL);
}

レインボーウェーブ

7色に変化させながら回します。

スケッチは以下の通り。

#include <Adafruit_NeoPixel.h>
#define PIN        6 // 信号用のピンを指定
#define NUMPIXELS 16 // LEDの数を指定

Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
#define DELAYVAL 10

int step_num = 0;
int delta = 1;
int color[] = {255, 255, 0};

void setup() {
  pixels.begin();
}

void loop() {
  for(int i=0; i<pixels.numPixels(); i++) {
    // ストリップの長さに沿って色相環(65536の範囲)を1回転させる量だけピクセルの色相をオフセットします。
    int pixelHue = step_num + (i * 65536L / pixels.numPixels());
    // ColorHSV関数に色相(0 to 65535)を渡し、その結果をgamma32()でガンマ補正します。
    pixels.setPixelColor(i, pixels.gamma32(pixels.ColorHSV(pixelHue)));
  }
  pixels.show();
  step_num += 256;
  if (step_num == 65536) {
    step_num = 0;
  }
  delay(DELAYVAL);
}

16ビットで表される色相環(カラーホイール)をLEDの個数分分割し、ステップごとに色相をずらしていきます。

以下のサイトで色を選択すると16ビットの値が確認できイメージが湧くかと思います。

ColorHSV関数は、色相をパックされた32ビットRGBカラーに変換します。
さらにこのスケッチでは、gamma32関数でガンマ補正してからsetPixelColor関数に渡しています。

ライブラリの使用の検討

エフェクトは自作しなくても、NeoPixel用のライブラリをGithub上で探すと以下あたりが見つかります。

ライブラリというよりサンプルぽいもの

ハロウィンキャンドルものがけっこうありますw

あとはなんだかんだと、Adafruit_NeoPixel公式サンプルは参考になります。

上記のうち、APIがシンプルなNeoPixelEffectsを使用した例を紹介してみます。

NeoPixelEffectsのインストール

NeoPixelEffectsはFastLEDを使用するので、ライブラリマネージャを開きインストールします。

  1. Arduino IDEのメニューから[ツール] > [ライブラリを管理…]を選択してライブラリマネージャを開きます。
  2. 「FastLED」で検索して「FastLED by Daniel Garcia」をインストールします。

NeoPixelEffectsはライブラリマネージャからはインストールできないので、ZIPされたソースをダウンロードしてArduino IDEに追加します。

  1. Githubのリポジトリの[Code]から[Download ZIP]をクリックしてソースをダウンロードします。
  2. Arduino IDEのメニューから[スケッチ] > [ライブラリをインクルード] > [.ZIP形式のライブラリをインストール…]を選択して、ダウンロードしたZIPファイルを選択します。

サンプルを動かす

[ファイル] > [スケッチ例] > [NeoPixel Effects]から一つ選択します。
この記事では作成しなかったエフェクト「CometExample」を選択して16連リング用に書き換えてみます。

#include "NeoPixelEffects.h"
#include "FastLED.h"

#define DATA_PIN      6  // 信号用のピン
#define NUM_LEDS      16 // LEDの数 

CRGB leds[NUM_LEDS];

NeoPixelEffects effect = NeoPixelEffects(
  leds,
  COMET,        // エフェクトの種類
  0,            // エフェクト開始位置
  15,           // エフェクト終了位置
  5,            // 点灯する範囲 (COMETの場合)
  50,           // エフェクトの間隔
  CRGB::Magenta,// 色
  true,         // ループするかどうか?
  FORWARD       // エフェクトの方向
);

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

  Serial.begin(9600);
}

void loop() {
  effect.update();
  FastLED.show();
}

実行するとこんな感じに光ります

参考

Arduino – LEDStrip effects for NeoPixel and FastLED

,