クリスマスツリーに音楽に合わせて光るLEDを装飾をしてみた

みなさん、こんにちわ。
都心の街やビルにはイルミネーションが飾られ、残業の光と合わせ幻想的な夜景が広がっております。

さて、今回の投稿はクリスマスツリーに音楽に合わせて光るLEDを装飾したお話です。

# 材料と費用
今回の材料はスイッチサイエンスとAmazonで購入しました。

| 名前|値段|
|:-----------------|------------------:|
|[スペクトラムシールド](https://www.switch-science.com/catalog/2244/)|3,118 円|
|[Arduino Uno R3](https://www.switch-science.com/catalog/789/)|3,240 円|
|[USB2.0ケーブル (A-Bタイプ)50cm](https://www.switch-science.com/catalog/1033/)|162 円|
|[ACアダプター 9V/1.3A](https://www.switch-science.com/catalog/1795/)|945 円|
|[Arduinoシールド用ピンソケットのセット(R3対応)](https://www.switch-science.com/catalog/995/)|185 円|
|[ジャンパワイヤ(オス～オス)](https://www.switch-science.com/catalog/57/)|492 円|
|[WS2812B LEDテープ 1m](https://www.amazon.co.jp/gp/product/B01MTU20FM/ref=ox_sc_act_title_1?smid=A19WO9MMW0TDGT&psc=1) |1,480 円|
|[3.5mmステレオミニケーブル 10cm](https://www.amazon.co.jp/gp/product/B00KS3N470/ref=oh_aui_detailpage_o01_s00?ie=UTF8&psc=1)　|498 円|
|[クリスマスツリーセット ミニ 60cm](https://www.amazon.co.jp/gp/product/B077GVSJ5Y/ref=ox_sc_act_title_2?smid=A2Q7MMNWV9T3PD&psc=1)|2,380 円|
|合計:|12,500 円|

## 環境とツール

- [Arduino IDE](https://www.arduino.cc/en/main/software)がインストール済みのPC
- ハンダごて
- ハンダ

## スペクトラムシールドにピンソケットをハンダ付け
まずは、スペクトラムシールドにピンソケットをハンダ付けをします。
ハンダ付けが初めての方はこちらの動画を参考にしてください。
→[Arduino用シールド基板へのピンソケットの半田付け方法](https://www.youtube.com/watch?v=oQT_VyJvRls)
![Sparkfun Spectrum Shield_Soldering.JPG](https://qiita-image-store.s3.amazonaws.com/0/60630/3e4d2712-8aa8-519d-68fc-15dd86f48c99.jpeg)

## マイコンボードとシリアルポートの設定

私の環境はMacのため、この記事ではMacでの説明になります。

1. ArduinoとPCをUSBケーブルで繋ぎます。
![USB_Connection.JPG](https://qiita-image-store.s3.amazonaws.com/0/60630/2a374e16-239f-1f42-93b5-083c72ecf8b5.jpeg)

２.　Arduino IDEを起動します。
<img width="612" alt="Arduino_IDE.png" src="https://qiita-image-store.s3.amazonaws.com/0/60630/05146f6d-1125-113c-ade8-bb4a082bb689.png">


３. メニューから「ツール」→「ボード」でプルダウンからArduino Unoを選択します。
<img width="1388" alt="DropShadow ~ Arduino_Bord.png" src="https://qiita-image-store.s3.amazonaws.com/0/60630/49a18a76-6770-1253-11a4-f8353a3d478b.png">


４. メニューから「ツール」→「シリアルポート」をプルダウンからUSBを選択します。
<img width="1292" alt="DropShadow ~ Arduino_Port.png" src="https://qiita-image-store.s3.amazonaws.com/0/60630/c38691a0-1b2b-e1c1-4c57-3e7311d98353.png">



## FastLEDライブラリのインストール
1. メニューから「スケッチ」→「ライブラリをインクルード」→「ライブラリ管理...」でライブラリマネージャを起動します。

2. 検索フィールドに「FastLED」と入力して表示されたFastLEDをインストールをします。
<img width="948" alt="DropShadow ~ FastLED.png" src="https://qiita-image-store.s3.amazonaws.com/0/60630/143947c4-3975-4231-0c7d-67c8dc3dc691.png">


## Arduinoにスケッチ（コード）書き込み

1.以下のコードをIDEにコピペする。

```c:sketch_visualizer.ino
#include "FastLED.h"

// LEDの設定
#define LED_PIN     6
#define NUM_LEDS    60 // LEDの数
#define BRIGHTNESS  64
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define UPDATES_PER_SECOND 100
#define REACT_LEVEL 1023L // 音の反応レベル値

CRGB leds[NUM_LEDS];

// オーディオ入力の設定
int strobe = 4;
int reset = 5;
int audio1 = A0;
int audio2 = A1;
int left[7];
int right[7];
int band;
int audio_input = 0;
int freq = 0;

// ビジュアライザの変数
int midway = NUM_LEDS / 2; // 真ん中のLED
int loop_max = 0;
int k = 255;
int decay = 0;
int decay_check = 0;
long pre_react = 0;
long react = 0;
long post_react = 0;
int wheel_speed = 2;

void setup()
{
  // スペクトルの設定
  pinMode(audio1, INPUT);
  pinMode(audio2, INPUT);
  pinMode(strobe, OUTPUT);
  pinMode(reset, OUTPUT);
  digitalWrite(reset, LOW);
  digitalWrite(strobe, HIGH);

  // LEDの明るさを調整
  delay( 3000 );
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );

  // LEDの初期化
  for (int i = 0; i < NUM_LEDS; i++)
    leds[i] = CRGB(0, 0, 0);
  FastLED.show();

  // シリアル入力にの設定
  Serial.begin(115200);
  Serial.println("\nListening...");
}

// 虹色の作成
// 参考 https://github.com/NeverPlayLegit/Rainbow-Fader-FastLED/blob/master/rainbow.ino
CRGB Scroll(int pos) {
  CRGB color (0, 0, 0);
  if (pos < 85) {
    color.g = 0;
    color.r = ((float)pos / 85.0f) * 255.0f;
    color.b = 255 - color.r;
  } else if (pos < 170) {
    color.g = ((float)(pos - 85) / 85.0f) * 255.0f;
    color.r = 255 - color.g;
    color.b = 0;
  } else if (pos < 256) {
    color.b = ((float)(pos - 170) / 85.0f) * 255.0f;
    color.g = 255 - color.b;
    color.r = 1;
  }
  return color;
}

// MSGEQ7(スペクトラムアナライザ)から値を読み込む
void readMSGEQ7()
{
  digitalWrite(reset, HIGH);
  digitalWrite(reset, LOW);
  for (band = 0; band < 7; band++)
  {
    digitalWrite(strobe, LOW);
    delayMicroseconds(30); //
    left[band] = analogRead(audio1);
    right[band] = analogRead(audio2);
    digitalWrite(strobe, HIGH);
  }
}

// 真ん中のLEDから両端に向けてビジュアライズする
void doubleVisualizer()
{
  for (int i = NUM_LEDS - 1; i >= midway; i--) {
    if (i < react + midway) {
      leds[i] = Scroll((i * 256 / 50 + k) % 256);
      leds[(midway - i) + midway] = Scroll((i * 256 / 50 + k) % 256);
    }
    else
      leds[i] = CRGB(0, 0, 0);
      leds[midway - react] = CRGB(0, 0, 0);
  }
  FastLED.show();
}

// オーディオ信号からLEDを光らせるレベルを算出
void convertDouble()
{
  if (left[freq] > right[freq])
    audio_input = left[freq];
  else
    audio_input = right[freq];

  if (audio_input > 80)
  {
    pre_react = ((long)midway * (long)audio_input) / REACT_LEVEL;

    if (pre_react > react)
      react = pre_react;

    Serial.print(audio_input);
    Serial.print(" -> ");
    Serial.println(pre_react);
  }
}

void doubleLevel()
{
  readMSGEQ7();

  convertDouble();

  doubleVisualizer();

  k = k - wheel_speed;
  if (k < 0)
    k = 255;

  decay_check++;
  if (decay_check > decay)
  {
    decay_check = 0;
    if (react > 0)
      react--;
  }
}

void loop()
{
  doubleLevel();
}
```

2.　　スケッチの定数を自分の環境に合わせて変更します。

| 定数      |説明 |
|:-----------|:--------------------|
|NUM_LEDS|使用するLED数を設定してください。|
|REACT_LEVEL　|音の反応レベルです。出力レベルや曲のジャンルに合わせて調整してください。|

3.「コンパイルボタン」を押してコンパイルします。

![IDE_Compile_skitch.png](https://qiita-image-store.s3.amazonaws.com/0/60630/8d44ef5d-44c0-c90a-30e2-616b611de7a5.png)

4.「書き込みボタン」を押してArduinoへ書き込みをします。
![IDE_Uplode_skitch.png](https://qiita-image-store.s3.amazonaws.com/0/60630/b27432c1-dfc4-76cf-45cc-c76b96a215ac.png)

## ピンの接続

1. WS2812B LEDテープ側にジャンパワイヤを差し込みます。
![connect_jumper.jpg](https://qiita-image-store.s3.amazonaws.com/0/60630/aa9b9fcb-cd24-0327-d0c5-9f4b83d10473.jpeg)

2. 以下のようにピンを接続します。

| WS2812B LEDテープ      |     |    Arduino の ピン     |
|:-----------------:|:------------------:|:------------------:|
| GND             |            --->|       GND       |
| DATA           |            ---> |       6        |
| 5v             |           ---> |        5v         |

![connect_sheld.jpg](https://qiita-image-store.s3.amazonaws.com/0/60630/8137db52-b040-c30a-c337-35aa53686c4c.jpeg)


## 音楽プレイヤーを接続して音楽を再生してみる
スマホを音楽プレイヤーとして接続し音楽を再生しました。
![test_play.gif](https://qiita-image-store.s3.amazonaws.com/0/60630/1fc1ca1e-c592-d147-8403-4673f64d37d0.gif)

## LEDとビジュいあらクリスマスツリーに装飾する
隣席の人がUSBスピーカーを持っていたため拝借しました。
![illumination.jpg](https://qiita-image-store.s3.amazonaws.com/0/60630/d192f46d-bf75-a9ec-a474-421c5c37dad8.jpeg)

## 動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">クリスマスツリーに音楽に合わせて光るLEDを装飾をしてみた <a href="https://t.co/SXCOqjqFVW">pic.twitter.com/SXCOqjqFVW</a></p>&mdash; kokichi@opst (@kokichi_opst) <a href="https://twitter.com/kokichi_opst/status/1072005912653524992?ref_src=twsrc%5Etfw">2018年12月10日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

## 最後に
ハンダ付けを含めても1時間半くらいで作成できました。ただ、材料費が高いですね。もし社内に設置するなら[社内クラウドファンディング](https://vacks.paid.jp/?p=1575)で資金調達してみてはどうでしょうか。また、音楽プレイヤーとしてスマホを直接繋いで使用しましたが、[Volumio](https://volumio.org/)をインストール済みのRaspberry PiとArduinoを接続し、AirPlayでスマホに入れている音楽を流すのもいいかもしれません。

家庭や職場のクリスマスツリーをバージョンアップしてみましょう！

## 参考
[スペクトラムシールドの使い方](https://learn.sparkfun.com/tutorials/spectrum-shield-hookup-guide?_ga=1.102027329.1778610866.1428461277)
[FastLED](https://github.com/NeverPlayLegit/Rainbow-Fader-FastLED)