サウンドセンサー第一段階完成
先日から、いろいろ助けて頂きながら作成していたサウンドセンサーが第一段階完成しました。配線は以下です。
スケッチは以下です。
//https://learn.adafruit.com/gemma-powered-neopixel-led-sound-reactive-drums
//ライブラリとしてAdafruitのNeoPixelを入れておく(スケッチ>ライブラリをインクルード>ライブラリの管理から)
//マイクはAdafruitもしくは互換品のMAX4466モジュールを使用
//Arduino Nanoを使用する場合ボードはArduino Nano、プロセッサは互換品の場合大抵はAtmega328P(Old Bootloader)を設定
//書き込み失敗する場合はAtmega328Pに設定
//マイクは3.3V / GND電源とデータをA0ピンに接続
//NeoPixelは5V / GND電源とデータ(DI)をD6ピンに接続
#include <Adafruit_NeoPixel.h>
#define N_PIXELS 30 //連結するNeoPixelの数
#define MIC_PIN A0 //マイクの接続アナログピン
#define LED_PIN 6 //NeoPixelのデータピン
//#define DC_OFFSET -112 //マイクのオフセット マイク5V供給時は512が中央、3.3Vの場合中央が下がるので調整する
#define DC_OFFSET 0
//#define NOISE 100 //ノイズ処理用
#define NOISE 170 //ノイズ処理用
#define SAMPLES 60 //サンプリング数
#define TOP (N_PIXELS +1) //NeoPixelの数より少し上に上限を設定しておく
//NeoPixelの輝度調整をしたい場合、アナログピンに可変抵抗をつけておき下記行のコメントを外す
//#define POT_PIN 3
byte
peak = 0, // Used for falling dot
dotCount = 0, // Frame counter for delaying dot-falling speed
volCount = 0; // Frame counter for storing past volume data
int
vol[SAMPLES], // Collection of prior volume samples
lvl = 10, // Current "dampened" audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;
//Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRBW + NEO_KHZ800);
void setup() {
memset(vol, 0, sizeof(int)*SAMPLES);
strip.begin();
}
void loop() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
//マイクからの入力
n = analogRead(MIC_PIN); // Raw reading from mic
n = abs(n - 512 - DC_OFFSET); // Center on zero
n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + n) >> 3; // "Dampened" reading (else looks twitchy)
//NeoPixelの点灯数
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0; // Clip output
else if (height > TOP) height = TOP;
if (height > peak) peak = height; // Keep 'peak' dot at top
//POT_PIN使用時、輝度を調整する なければ最高輝度
uint8_t bright = 255;
#ifdef POT_PIN
bright = analogRead(POT_PIN); // Read pin (0-255) (adjust potentiometer to give 0 to Vcc volts
#endif
strip.setBrightness(bright);
//NeoPixelの点灯と色の設定0-
for (i = 0; i < N_PIXELS; i++) {
if (i >= height)
strip.setPixelColor(i, 0, 0, 0);
else
strip.setPixelColor(i, Wheel(map(i, 0, strip.numPixels() - 1, 30, 150)));
}
strip.show(); // Update strip
vol[volCount] = n; // Save sample for dynamic leveling
if (++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter
// Get volume range of prior frames
minLvl = maxLvl = vol[0];
for (i = 1; i < SAMPLES; i++) {
if (vol[i] < minLvl) minLvl = vol[i];
else if (vol[i] > maxLvl) maxLvl = vol[i];
}
// minLvl and maxLvl indicate the volume range over prior frames, used
// for vertically scaling the output graph (so it looks interesting
// regardless of volume level). If they're too close together though
// (e.g. at very low volume levels) the graph becomes super coarse
// and 'jumpy'...so keep some minimum distance between them (this
// also lets the graph go to zero when no sound is playing):
if ((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
//虹色の計算
uint32_t Wheel(byte WheelPos) {
if (WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if (WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
最初ノイズをひろって、ずっと光っぱなしでしたが、ノイズをオフにしたらいい感じになりました。
かなり満足です。(^^)
この記事が気に入ったらサポートをしてみませんか?