ArduinoでNeoPixelをAudiのシグネチャーライト風に光らせる

# はじめに
NeoPixelと呼ばれるようなLEDをご存じでしょうか？見た目は普通のフルカラーLEDですが、その中に極小マイコンが内蔵されているため、Arduinoから制御するのに必要な信号線は1本のみ。さらに、複数個を数珠繋ぎに接続しても個別に制御できます。ライブラリも用意されているため、とても手軽に扱えます。色々な光らせ方が可能ですが、今回は[**こちら**](https://youtu.be/HfjO-TYAsFI)の動画で登場するQ8、A7、RS7のシグネチャーライト風に光らせてみたいと思います。
# 開発環境
* Windows 11 Home 22H2 (22621.1265)
* Arduino IDE 1.8.13
* Adafruit NeoPixel 1.11.0
# 部品表
いずれも[__秋月電子通商__](https://akizukidenshi.com/)で入手しました。今回はESP32-WROVER-Eを使用しましたが、大抵のArduinoなら同じように動くと思います。
| 部品名 | 通販コード | 価格 |
|:--|:--|--:|
| ESP32-WROVER-E | K-15779 | 560円 |
| PL9823-F5 | I-08411 | 200円 |
| ブレッドボード | P-09257 | 300円 |
| ジャンパー線 | P-02315 | 300円 |
# ハードウェア
NeoPixelの扱い方などは[**こちら**](https://rikoubou.hatenablog.com/entry/2020/01/14/181031)が参考になります。
![picture.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/0b4da1b5-7950-d1d9-c41e-f17afee311c7.jpeg)
# ソフトウェア
実際に光る様子が動画では確認しにくかったのでGIF画像を作りました。
## Q8
ナイトライダー風に光ります。
<details><summary>ソースコード</summary>

```cpp:light_signature_q8.ino
#include <Adafruit_NeoPixel.h>

#define PIXEL_COUNT 5
#define PIXEL_PIN 15

Adafruit_NeoPixel pixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);


void opening() { 
  for (int i = 0; i < PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 50, 50, 50);
    pixel.show();
    delay(80);
  }
  
  for (int i = PIXEL_COUNT - 1; i >= 0; i--) {
    pixel.setPixelColor(i, 255, 255, 255);
    pixel.setPixelColor(i + 1, 50, 50, 50);
    pixel.show();
    delay(80);
  }
  
  for (int i = 1; i < PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 255, 255, 255);
    pixel.show();
    delay(80);
  }
}

void ending() {
  for (int i = PIXEL_COUNT - 1; i > 0; i--) {
    pixel.setPixelColor(i, 50, 50, 50);
    pixel.show();
    delay(80);
  }
  
  for (int i = 1; i <= PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 255, 255, 255);
    pixel.setPixelColor(i - 1, 50, 50, 50);
    pixel.show();
    delay(80);
  }
  
  for (int i = PIXEL_COUNT - 1; i >= 0; i--) {
    pixel.setPixelColor(i, 0);
    pixel.show();
    delay(80);
  }
}

void setup() {
  pixel.begin();
  pixel.setBrightness(100);
  pixel.clear();
  pixel.show(); //turn off all pixels
}

void loop() {
  opening();
  delay(2000);
  //ending();
  //delay(2000);
}
```
</details>

![light_signature_q8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/711083ba-da84-be33-988a-10d0166fbbde.gif)
## A7
先程の光らせ方に似ていますが、こちらは残像みたいな演出がありません。
<details><summary>ソースコード</summary>

```cpp:light_signature_a7.ino
#include <Adafruit_NeoPixel.h>

#define PIXEL_COUNT 5
#define PIXEL_PIN 15

Adafruit_NeoPixel pixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);


void opening() {
  for (int i = 0; i < PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 50, 50, 50);
    pixel.setPixelColor(i - 1, 0);
    pixel.show();
    delay(80);
  }
  
  for (int i = PIXEL_COUNT - 1; i > 0; i--) {
    pixel.setPixelColor(i - 1, 50, 50, 50);
    pixel.setPixelColor(i, 0);
    pixel.show();
    delay(80);
  }
  
  for (int i = 1; i < PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 50, 50, 50);
    pixel.show();
    delay(80);
  }
  delay(100);
  
  for (int i = 50; i <= 255; i++) {
    for (int j = 0; j < PIXEL_COUNT; j++) {
      pixel.setPixelColor(j, i, i, i);
    }
    pixel.show();
    delay(5);
  }
}

void ending() {
  for (int i = 255; i >= 50; i--) {
    for (int j = 0; j < PIXEL_COUNT; j++) {
      pixel.setPixelColor(j, i, i, i);
    }
    pixel.show();
    delay(5);
  }
  delay(100);
  
  for (int i = PIXEL_COUNT - 1; i > 0; i--) {
    pixel.setPixelColor(i, 0);
    pixel.show();
    delay(80);
  }
  
  for (int i = 1; i < PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 50, 50, 50);
    pixel.setPixelColor(i - 1, 0);
    pixel.show();
    delay(80);
  }
  
  for (int i = PIXEL_COUNT - 1; i >= 0; i--) {
    pixel.setPixelColor(i - 1, 50, 50, 50);
    pixel.setPixelColor(i, 0);
    pixel.show();
    delay(80);
  }
}

void setup() {
  pixel.begin();
  pixel.setBrightness(100);
  pixel.clear();
  pixel.show(); //turn off all pixels
}

void loop() {
  opening();
  delay(2000);
  //ending();
  //delay(2000);
}
```
</details>

![light_signature_a7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/b18b3d33-0fa1-b936-b63c-0b34e589de39.gif)
## RS7
ゲージが溜まっていくような演出です。
<details><summary>ソースコード</summary>

```cpp:light_signature_rs7.ino
#include <Adafruit_NeoPixel.h>

#define PIXEL_COUNT 5
#define PIXEL_PIN 15

Adafruit_NeoPixel pixel(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);


void openingRS() {
  for (int i = PIXEL_COUNT; i > 0; i--) {
    for (int j = 0; j < i; j++) {
      pixel.setPixelColor(j, 50, 50, 50);
      pixel.setPixelColor(j - 1, 0);
      pixel.show();  
      delay(40 + (i - 1) * 10);   
    }
  }
  delay(40);

  for (int i = 0; i <= PIXEL_COUNT; i++) {
    pixel.setPixelColor(i, 255, 255, 255);
    pixel.setPixelColor(i - 1, 50, 50, 50);
    pixel.show();  
    delay(50);  
  }
  delay(100);

  for (int i = 50; i <= 255; i++) {
    for (int j = 0; j < PIXEL_COUNT; j++) {
      pixel.setPixelColor(j, i, i, i);
    }
    pixel.show();
    delay(5);
  }
}

void endingRS() {
  for (int i = 255; i >= 50; i--) {
    for (int j = 0; j < PIXEL_COUNT; j++) {
      pixel.setPixelColor(j, i, i, i);
    }
    pixel.show();
    delay(5);
  }
  delay(100);

  for (int i = 0; i < PIXEL_COUNT; i++) {
    for (int j = i; j >= 0; j--) {
      pixel.setPixelColor(j, 0);
      pixel.setPixelColor(j - 1, 50, 50, 50);
      pixel.show();  
      delay(40 + i * 10);  
    }
  }
}

void setup() {
  pixel.begin();
  pixel.setBrightness(100);
  pixel.clear();
  pixel.show(); //turn off all pixels
}

void loop() {
  openingRS();
  delay(2000);
  //endingRS();
  //delay(2000);
}
```
</details>

![light_signature_rs7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2951963/96d4bde6-8809-1cc2-8d46-ebff613fd7ce.gif)
# おわりに
自作デバイスの起動時、終了時の演出などに使えそうです。