作品の概要
ここでご紹介する作品は、音楽に合わせて光る「パリピクリスマスツリー」です。
音楽に合わせて電飾がオーディオレベルメーターとして光ります。実際に光る様子は以下の動画からどうぞ。
アナログ回路とArduinoを組み合わせ、音楽に合わせてArduinoでNeo Pixelを制御してレベルメーターを作ります。
電子回路の概要
まずは電子回路からご紹介します。電子回路は意外と単純な作りで、既存のICを使うことでシンプルな構成にできました。
電子回路は主に以下の4つの構成で成り立っています。
- 音声入力のマイク
- 音声の周波数分解アナログ回路(IC)
- Neo Pixel
- 周波数分解回路とNeo Pixel制御用Arduino
それぞれの詳細について以下でご紹介します。
音声入力のマイク
マイクの回路は秋月電子通商にて販売されているマイクアンプキットを使用しました。
高感度マイクアンプキット
電源とGND、音声出力のシンプルな3ピンのインターフェースになっているため、簡単に扱えます。
このマイクアンプキットを使って、音楽を周波数分解回路に取り込みます。
音声の周波数分解アナログ回路(IC)
マイクから入力された音を周波数ごとに分割します。このためにオーディオ用7バンドスペクトラムアナライザ-用IC MSGEQ7Pを使いました。こちらも秋月電子通商にて購入しました。
オーディオ用7バンドスペクトラムアナライザ-用IC MSGEQ7P
7バンドの周波数帯域に分ける回路をディスクリートで作ろうとすると、規模が少々大きくなってしまいますが、このICを使うことでとても簡単でシンプルに周波数を分解できます。
こちらはArduinoで制御します。
Neo Pixel
Neo Pixelはシリアル信号でカラーを制御できるフルカラーLEDです。音の大きさにあわせてNeo Pixelを光らせることでオーディオレベルメーターにします。Neo Pixelは最近はおなじみになってきており、価格も安価になってきています。
今回の製作ではフレキシブルなテープ状の基板にNeo Pixelが実装されたテープLEDを使用しました。
参考に秋月電子通商にて取り扱いがあるものをご紹介します。
SK6812使用マイコン内蔵フルカラーテープLED 1m 60LED IP20
オーディオレベルメーターは各周波数に16個のNeo Pixelを使い、24つのレベルメーターを作りました。周波数帯は7つですので、24つのレベルメーターの中で同じ周波数帯がいくつか存在します。レベルメーター部で16 x 24 = 384個のNeo Pixelを使用しました。
また、クリスマスツリーの先端の星かざりを照らすためにも追加で48個のNeo Pixelを使用しました。
これらは全てシリアルでつながっています。
Neo Pixelのテープを16個毎に切り、改めてワイヤーで接続します。
周波数分解回路とNeo Pixel制御用Arduino
周波数分解アナログ回路(MSGEQ7P)とNeo Pixelの制御にArduinoを使用します。
今回はなるべく安価で小型に作りたかったため、Arduino Pro miniを使用しました。
電子回路の組み立て
電子回路の組み立てについては難しいことはなく、それぞれの部品の標準アプリケーションの説明を参考に組み合わせます。
回路図を以下に示します。
Arduino Pro miniのシンボルはArduino UNO R3のシンボルで代替しています。Arduino Pro miniへの給電については、別途プログラム書き込み用のシリアル通信モジュールを接続し、ここから給電しています。Neo Pixelへの給電はACアダプタの電源ジャックを搭載し、ここから5VのACアダプタで給電します。
回路としては非常にシンプルな作りな反面、あとはArduinoのソフトの方で作り込みを行います。
ソフトウェア
MSGEQ7PとNeo Pixelの制御にArduinoを使用しました。
Arduinoでやることは主に以下の3つです。
- MSGEQ7Pの周波数帯を制御
- MSGEQ7Pからアナログ信号を読み取り
- アナログ信号強度をもとにNeo Pixelを点灯制御
ソフトウェアのコードを以下に示します。
パリピクリスマスツリーのソースコード
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
/************************************************************/
#define VAL_SCALE 2 // 表示する値のスケール(1024 * 整数)
const int Val_Scale = VAL_SCALE - 1;
#define PX_MAX 16 // 周波数あたりの使用LED数
#define AUDIO_RESOLUTION (1024 / (PX_MAX)) // 表示分解能 (ADC bit) / (LED数)
const int Audio_Res = AUDIO_RESOLUTION; // 表示分解能
int PX_OFFSET = AUDIO_RESOLUTION * 0;
/************************************************************/
/***** Pin Setting *****/
// MSGEQ7
#define RST 10
#define STROBE 9
#define ANALOG_PIN A0
// LED
#define LED_PIN 2
#define NUMPIXELS (384+48) //LED NUM
int freq_val[7] = {0, 0, 0, 0, 0, 0, 0};
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
/*LED Setup*/
pixels.begin();
pixels.clear();
pixels.show();
/*MSGEQ7 Setup*/
pinMode(RST, OUTPUT);
pinMode(STROBE, OUTPUT);
digitalWrite(RST, HIGH);
digitalWrite(STROBE, LOW);
delay(500);
digitalWrite(RST, LOW);
}
void loop() {
/************************************************************/
/* Get MSGEQ7 Value */
/************************************************************/
for (int i = 0; i < 7; i++) {
digitalWrite(STROBE, HIGH);
delayMicroseconds(20); // storobe width
digitalWrite(STROBE, LOW);
delayMicroseconds(40); //output setting time
freq_val[i] = analogRead(ANALOG_PIN) << Val_Scale;
}
/************************************************************/
/* Set LED Color Data */
/************************************************************/
// LEDアドレス初期化
int px_addr = 0;
for (int freq = 1; freq < 6; freq++) {
setColor(freq_val[freq], px_addr);
px_addr = px_addr + PX_MAX;
}
setColor(freq_val[3], px_addr);
px_addr = px_addr + PX_MAX;
for (int freq = 1; freq < 6; freq++) {
setColor(freq_val[freq], px_addr);
px_addr = px_addr + PX_MAX;
}
setColor(freq_val[3], px_addr);
px_addr = px_addr + PX_MAX;
for (int freq = 1; freq < 6; freq++) {
setColor(freq_val[freq], px_addr);
px_addr = px_addr + PX_MAX;
}
setColor(freq_val[3], px_addr);
px_addr = px_addr + PX_MAX;
for (int freq = 1; freq < 6; freq++) {
setColor(freq_val[freq], px_addr);
px_addr = px_addr + PX_MAX;
}
setColor(freq_val[3], px_addr);
px_addr = px_addr + PX_MAX;
//Star 点灯
if(512 < freq_val[2]){
for(int i=px_addr; i<(px_addr + 48); i++){
pixels.setPixelColor(i, pixels.Color(76, 72, 0));
}
}
else{
for(int i=px_addr; i<(px_addr + 48); i++){
pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
}
px_addr = px_addr + 48;
/*カラーデータを送信*/
pixels.show();
}
void setColor(int freq_val, int led_addr) {
int px_num = 0; // LEDの順番
int audio_level = 0;
audio_level+=PX_OFFSET;
for (int i = led_addr; i < (led_addr + PX_MAX); i++) {
if (px_num < 2) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(43, 0, 39));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else if (px_num < 4) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(0, 30, 57));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else if (px_num < 6) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(0, 145, 76));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else if (px_num < 8) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(0, 40, 0));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else if (px_num < 10) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(76, 72, 0));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else if (px_num < 12) {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(76, 45, 0));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
else {
if (audio_level < freq_val) pixels.setPixelColor(i, pixels.Color(76, 0, 0));
else pixels.setPixelColor(i, pixels.Color(0, 0, 0));
}
px_num++;
audio_level = audio_level + Audio_Res;
}
}
7帯域のアナログ値を順番に取得し、変数に格納します。その後、setColor関数で各周波数の音の大きさに対応してLEDの色をセットしています。Neo Pixelのアドレスをインクリメントしながら全てのNeo Pixelにデータを作り、pixels.show関数でNeo Pixelにデータを流しこみます。
Neo Pixelの制御にはAdafruit製のライブラリであるAdafruit_NeoPixel.hを使用しました。
このプログラムでレベルメーターの動作をテストした様子を以下に示します。(星かざりの部分は入っていません。)
ソフトがうまく動いたことが確認できたので、ユニバーサル基板に実装しました。
また、384個のレベルメーター部分のNeo Pixelと星かざり部分の48個のNeo Pixelを全て連結しました。
飾り付け
全てのNeo Pixelを連結したら、クリスマスツリーに飾り付けます。
クリスマスツリーは100円ショップで販売している小型のツリーを使いました。
見栄えがよくなるように、レベルメーターの表示が下から上に上がって行くように縦方向に飾り付けました。
また、クリスマスツリーらしくクリスマス飾りも付けます。
これで「パリピクリスマスツリー」の完成です。
完成したパリピクリスマスツリー
EDM風のクリスマスソングを作り、パリピクリスマスツリーの近くで再生しました。
クリスマスソングに合わせてレベルメーターが動く様子がわかります。
以上、パリピクリスマスツリーのご紹介でした。
-
aki_bmxyz
さんが
2021/02/28
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する