見出し画像

サウンドセンサー第一段階完成

先日から、いろいろ助けて頂きながら作成していたサウンドセンサーが第一段階完成しました。配線は以下です。

サウンドセンサー配線_ブレッドボード

スケッチは以下です。

//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);
	}
}

最初ノイズをひろって、ずっと光っぱなしでしたが、ノイズをオフにしたらいい感じになりました。

かなり満足です。(^^)




この記事が気に入ったらサポートをしてみませんか?