728x90
ESP32
- 와이파이 / 블루투스 내장
- A feature-rich MCU with integrated Wi-Fi and
Bluetooth connectivity for a wide-range
of applications - ESP32-WROOM-32는 저전력 센서 네트워크에서 음성 인코딩, 음악 스트리밍 및 MP3 디코딩과 같은 가장 까다로운 작업에 이르기까지 다양한 애플리케이션을 대상으로 하는 강력한 일반 Wi-Fi BT BLE MCU 모듈입니다.
https://www.espressif.com/en/products/socs/esp32 |
참조 https://makernambo.com/54 |
데이터 시트 https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32_datasheet_en.pdf |
|
아두이노 마이크로폰 소리 증폭 감지 센서 MAX9814 / 사운드
이 멋진 마이크 앰프 모듈은 자동 게인 제어 기능이 내장되어 있어 다른 제품보다 한 단계 더 높습니다. 앰프의 AGC는 가까운 '큰' 소리가 조용해져서 앰프를 압도하지 않고 '잘라내지' 않고 조용하고 멀리 있는 소리도 증폭된다는 것을 의미합니다. 이 앰프는 레벨이 변하는 설정에서 오디오를 녹음하거나 감지하고 항상 앰프 게인을 조정할 필요가 없는 경우에 적합합니다. |
https://learn.adafruit.com/adafruit-agc-electret-microphone-amplifier-max9814 |
FASTLED Library
라이브러리 참조
이것은 adafruit(Neopixel, DotStar, LPD8806), Sparkfun(WS2801) 및 aliexpress에서 판매하는 것과 같은 다양한 LED 칩셋을 쉽고 효율적으로 제어하기 위한 라이브러리입니다. LED에 쓰는 것 외에도 이 라이브러리에는 RGB 값을 조작하기 위한 고성능 8비트 수학을 위한 여러 기능과 핀 및 SPI 하드웨어에 대한 액세스를 추상화하기 위한 저수준 클래스가 포함되어 있습니다. 가능한 한. arduino.cc에서 최대 1.6.5까지 Arduino로 테스트했습니다. |
|
https://github.com/FastLED/FastLED |
라이브러리 샘플 예제
DemoReal100.ino
ColorPalette.ino
다양한 색상 팔레트가 있습니다. FastLED는 여러 '사전 설정' 팔레트를 제공합니다. RainbowColors_p, RainbowStripeColors_p, OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p 및 PartyColors_p. 추가적으로 자신만의 색상 팔레트를 수동으로 정의하거나 다음과 같이 작성할 수 있습니다. 즉석에서 색상 팔레트를 생성하는 코드. 모두 여기에 표시됩니다. |
ColorPaletteSerialInput.ino
- 시리얼모니터를 이용하여 LED 패턴을 변경합니다.
#include <FastLED.h>
#include <EEPROM.h>
#define LED_PIN 17
// #define NUM_LEDS 128
int NUM_LEDS = 64;
#define BRIGHTNESS 64
#define LED_TYPE WS2811
#define COLOR_ORDER GRB
// CRGB leds[NUM_LEDS];
CRGB * leds; // [NUM_LEDS];
#define UPDATES_PER_SECOND 100
int user_delay = 100;
CRGBPalette16 currentPalette;
TBlendType currentBlending;
extern CRGBPalette16 myRedWhiteBluePalette;
extern const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM;
void writeIntIntoEEPROM(int address, int number)
{
EEPROM.write(address, number >> 8);
EEPROM.write(address + 1, number & 0xFF);
EEPROM.commit();
}
int readIntFromEEPROM(int address)
{
return (EEPROM.read(address) << 8) + EEPROM.read(address + 1);
}
void setup() {
delay( 3000 ); // power-up safety delay
EEPROM.begin(100);
Serial.begin(57600);
NUM_LEDS = readIntFromEEPROM(0);
if(1025 < NUM_LEDS) NUM_LEDS = 1024;
Serial.print("NUM_LEDS=");
Serial.print(NUM_LEDS);
leds = (CRGB*)malloc(sizeof(CRGB)* NUM_LEDS);
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
// currentPalette = RainbowColors_p;
// currentBlending = LINEARBLEND;
int hand = readIntFromEEPROM(4);
if(10 < hand) hand = 1;
Serial.print(",hand=");
Serial.print(hand);
ChangePalettePeriodically(hand);
user_delay = readIntFromEEPROM(2);
if(1000 < user_delay) user_delay = 50;
Serial.print(",user_delay=");
Serial.println(user_delay);
}
void loop()
{
if(0 < Serial.available()) {
String str = Serial.readString();
char buffer[20];
str.toCharArray(buffer, 20);
if(buffer[0] == 'D') {
user_delay = atoi(buffer+1);
Serial.print("DELAY=");
Serial.println(user_delay);
writeIntIntoEEPROM(2, user_delay);
}
else
if(buffer[0] == 'N') {
NUM_LEDS = atoi(buffer+1);
Serial.print("NUM_LEDS=");
Serial.println(NUM_LEDS);
writeIntIntoEEPROM(0, NUM_LEDS);
ESP.restart();
}
else {
int hand= atoi(buffer);
Serial.println(hand);
ChangePalettePeriodically(hand);
writeIntIntoEEPROM(4, hand);
}
}
// ChangePalettePeriodically();
static uint8_t startIndex = 0;
startIndex = startIndex + 1; /* motion speed */
FillLEDsFromPaletteColors( startIndex);
FastLED.show();
if(0 < user_delay) {
FastLED.delay(user_delay);
}
}
void FillLEDsFromPaletteColors( uint8_t colorIndex)
{
uint8_t brightness = 255;
for( int i = 0; i < NUM_LEDS; ++i) {
leds[i] = ColorFromPalette( currentPalette, colorIndex, brightness, currentBlending);
colorIndex += 3;
}
}
// There are several different palettes of colors demonstrated here.
//
// FastLED provides several 'preset' palettes: RainbowColors_p, RainbowStripeColors_p,
// OceanColors_p, CloudColors_p, LavaColors_p, ForestColors_p, and PartyColors_p.
//
// Additionally, you can manually define your own color palettes, or you can write
// code that creates color palettes on the fly. All are shown here.
// void ChangePalettePeriodically()
// {
// uint8_t secondHand = (millis() / 1000) % 60;
// static uint8_t lastSecond = 99;
// if( lastSecond != secondHand) {
// lastSecond = secondHand;
// if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; }
// if( secondHand == 10) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; }
// if( secondHand == 15) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; }
// if( secondHand == 20) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; }
// if( secondHand == 25) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; }
// if( secondHand == 30) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; }
// if( secondHand == 35) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; }
// if( secondHand == 40) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; }
// if( secondHand == 45) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; }
// if( secondHand == 50) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; }
// if( secondHand == 55) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
// }
// }
void ChangePalettePeriodically(int secondHand)
{
if( secondHand == 0) { currentPalette = RainbowColors_p; currentBlending = LINEARBLEND; }
if( secondHand == 1) { currentPalette = RainbowStripeColors_p; currentBlending = NOBLEND; }
if( secondHand == 2) { currentPalette = RainbowStripeColors_p; currentBlending = LINEARBLEND; }
if( secondHand == 3) { SetupPurpleAndGreenPalette(); currentBlending = LINEARBLEND; }
if( secondHand == 4) { SetupTotallyRandomPalette(); currentBlending = LINEARBLEND; }
if( secondHand == 5) { SetupBlackAndWhiteStripedPalette(); currentBlending = NOBLEND; }
if( secondHand == 6) { SetupBlackAndWhiteStripedPalette(); currentBlending = LINEARBLEND; }
if( secondHand == 7) { currentPalette = CloudColors_p; currentBlending = LINEARBLEND; }
if( secondHand == 8) { currentPalette = PartyColors_p; currentBlending = LINEARBLEND; }
if( secondHand == 9) { currentPalette = myRedWhiteBluePalette_p; currentBlending = NOBLEND; }
if( secondHand == 10) { currentPalette = myRedWhiteBluePalette_p; currentBlending = LINEARBLEND; }
}
// This function fills the palette with totally random colors.
void SetupTotallyRandomPalette()
{
for( int i = 0; i < 16; ++i) {
currentPalette[i] = CHSV( random8(), 255, random8());
}
}
// This function sets up a palette of black and white stripes,
// using code. Since the palette is effectively an array of
// sixteen CRGB colors, the various fill_* functions can be used
// to set them up.
void SetupBlackAndWhiteStripedPalette()
{
// 'black out' all 16 palette entries...
fill_solid( currentPalette, 16, CRGB::Black);
// and set every fourth one to white.
currentPalette[0] = CRGB::White;
currentPalette[4] = CRGB::White;
currentPalette[8] = CRGB::White;
currentPalette[12] = CRGB::White;
}
// This function sets up a palette of purple and green stripes.
void SetupPurpleAndGreenPalette()
{
CRGB purple = CHSV( HUE_PURPLE, 255, 255);
CRGB green = CHSV( HUE_GREEN, 255, 255);
CRGB black = CRGB::Black;
currentPalette = CRGBPalette16(
green, green, black, black,
purple, purple, black, black,
green, green, black, black,
purple, purple, black, black );
}
// This example shows how to set up a static color palette
// which is stored in PROGMEM (flash), which is almost always more
// plentiful than RAM. A static PROGMEM palette like this
// takes up 64 bytes of flash.
const TProgmemPalette16 myRedWhiteBluePalette_p PROGMEM =
{
CRGB::Red,
CRGB::Gray, // 'white' is too bright compared to red and blue
CRGB::Blue,
CRGB::Black,
CRGB::Red,
CRGB::Gray,
CRGB::Blue,
CRGB::Black,
CRGB::Red,
CRGB::Red,
CRGB::Gray,
CRGB::Gray,
CRGB::Blue,
CRGB::Blue,
CRGB::Black,
CRGB::Black
};
테스트
소리크기에 따라 LED 로 표현합니다.
//first include library/ download library: Adafruit Neopixel and FirstLED
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <FastLED.h>
// #include <EEPROM.h>
#define N_PIXELS 128 // Number of pixels in strand
#define N_PIXELS_HALF (N_PIXELS/2)
#define MIC_PIN 2 // Microphone is attached to this analog pin
#define LED_PIN 17 // NeoPixel LED strand is connected to this pin
#define LED_PIN2 16 // NeoPixel LED strand is connected to this pin
#define LED_PIN3 18 // NeoPixel LED strand is connected to this pin
#define SAMPLE_WINDOW 10 // Sample window for average level
#define PEAK_HANG 24 //Time of pause before peak dot falls
#define PEAK_FALL 20 //Rate of falling peak dot
#define PEAK_FALL2 8 //Rate of falling peak dot
#define INPUT_FLOOR 0 // 10 // Lower range of analogRead input
#define INPUT_CEILING 800 // 1000 //Max range of analogRead input, the lower the value the more sensitive (1023 = max)300 (150)
#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0
#define NOISE 10 // Noise/hum/interference in mic signal
#define SAMPLES 60 // Length of buffer for dynamic level adjustment
#define TOP (N_PIXELS + 2) // Allow dot to go slightly off scale
#define SPEED .20 // Amount to increment RGB color by each cycle
#define TOP2 (N_PIXELS + 1) // Allow dot to go slightly off scale
#define LAST_PIXEL_OFFSET N_PIXELS-1
#define PEAK_FALL_MILLIS 10 // Rate of peak falling dot
#define POT_PIN 4
#define BG 0
#define LAST_PIXEL_OFFSET N_PIXELS-1
#if FASTLED_VERSION < 3001000
#error "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define BRIGHTNESS 255
#define LED_TYPE WS2812B // Only use the LED_PIN for WS2812's
#define COLOR_ORDER GRB
#define COLOR_MIN 0
#define COLOR_MAX 255
#define DRAW_MAX 100
#define SEGMENTS 4 // Number of segments to carve amplitude bar into
#define COLOR_WAIT_CYCLES 10 // Loop cycles to wait between advancing pixel origin
#define qsubd(x, b) ((x>b)?b:0)
#define qsuba(x, b) ((x>b)?x-b:0) // Analog Unsigned subtraction macro. if result <0, then => 0. By Andrew Tuline.
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
// #define CENTERED
//Variables will change:
// 1 x
// 9 x
// 2, 3, 4, 5, 6, 7, 8, 10
int buttonPushCounter = 7; // 2; // 1 ; // 0; // counter for the number of button presses
int buttonState = 0; // current state of the button
int lastButtonState = 0;
struct CRGB leds[N_PIXELS];
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(N_PIXELS, LED_PIN2, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip3 = Adafruit_NeoPixel(N_PIXELS, LED_PIN3, NEO_GRB + NEO_KHZ800);
static uint16_t dist; // A random number for noise generator.
uint16_t scale = 30; // Wouldn't recommend changing this on the fly, or the animation will be really blocky.
uint8_t maxChanges = 48; // Value for blending between palettes.
CRGBPalette16 currentPalette(OceanColors_p);
CRGBPalette16 targetPalette(CloudColors_p);
//new ripple vu
uint8_t timeval = 20; // Currently 'delay' value. No, I don't use delays, I use EVERY_N_MILLIS_I instead.
uint16_t loops = 0; // Our loops per second counter.
bool samplepeak = 0; // This sample is well above the average, and is a 'peak'.
uint16_t oldsample = 0; // Previous sample is used for peak detection and for 'on the fly' values.
bool thisdir = 0;
//new ripple vu
// Modes
enum
{
} MODE;
// bool reverse = true;
int BRIGHTNESS_MAX = 80;
int brightness = 20;
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
reading,
vol[SAMPLES], // Collection of prior volume samples
lvl = 10, // Current "dampened" audio level
minLvlAvg = 0, // For dynamic adjustment of graph low & high
maxLvlAvg = 512;
float
greenOffset = 30,
blueOffset = 150;
// cycle variables
int CYCLE_MIN_MILLIS = 2;
int CYCLE_MAX_MILLIS = 1000;
int cycleMillis = 20;
bool paused = false;
long lastTime = 0;
bool boring = true;
bool gReverseDirection = false;
int myhue = 0;
//vu ripple
uint8_t colour;
uint8_t myfade = 255; // Starting brightness.
#define maxsteps 16 // Case statement wouldn't allow a variable.
int peakspersec = 0;
int peakcount = 0;
uint8_t bgcol = 0;
int thisdelay = 20;
uint8_t max_bright = 255;
unsigned int sample;
//Samples
#define NSAMPLES 64
unsigned int samplearray[NSAMPLES];
unsigned long samplesum = 0;
unsigned int sampleavg = 0;
int samplecount = 0;
//unsigned int sample = 0;
unsigned long oldtime = 0;
unsigned long newtime = 0;
//Ripple variables
int color;
int center = 0;
int step = -1;
int maxSteps = 16;
float fadeRate = 0.80;
int diff;
//vu 8 variables
int
origin = 0,
color_wait_count = 0,
scroll_color = COLOR_MIN,
last_intensity = 0,
intensity_max = 0,
origin_at_flip = 0;
uint32_t
draw[DRAW_MAX];
boolean
growing = false,
fall_from_left = true;
//background color
uint32_t currentBg = random(256);
uint32_t nextBg = currentBg;
TBlendType currentBlending;
const int buttonPin = 0; // the number of the pushbutton pin
byte peak = 16; // Peak level of column; used for falling dots
// unsigned int sample;
byte dotCount = 0; //Frame counter for peak dot
byte dotHangCount = 0; //Frame counter for holding peak dot
void setup() {
// analogReference(EXTERNAL);
pinMode(buttonPin, INPUT);
//initialize the buttonPin as output
digitalWrite(buttonPin, HIGH);
// Serial.begin(9600);
strip.begin();
strip.show(); // all pixels to 'off'
strip2.begin();
strip2.show(); // all pixels to 'off'
strip3.begin();
strip3.show(); // all pixels to 'off'
Serial.begin(57600);
delay(100);
LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds,N_PIXELS).setCorrection(TypicalLEDStrip);
LEDS.addLeds<LED_TYPE, LED_PIN2, COLOR_ORDER>(leds,N_PIXELS).setCorrection(TypicalLEDStrip);
LEDS.addLeds<LED_TYPE, LED_PIN3, COLOR_ORDER>(leds,N_PIXELS).setCorrection(TypicalLEDStrip);
LEDS.setBrightness(BRIGHTNESS);
dist = random16(12345); // A semi-random number for our noise generator
}
float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve){
float OriginalRange = 0;
float NewRange = 0;
float zeroRefCurVal = 0;
float normalizedCurVal = 0;
float rangedValue = 0;
boolean invFlag = 0;
// condition curve parameter
// limit range
if (curve > 10) curve = 10;
if (curve < -10) curve = -10;
curve = (curve * -.1) ; // - invert and scale - this seems more intuitive - postive numbers give more weight to high end on output
curve = pow(10, curve); // convert linear scale into lograthimic exponent for other pow function
// Check for out of range inputValues
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}
// Zero Refference the values
OriginalRange = originalMax - originalMin;
if (newEnd > newBegin){
NewRange = newEnd - newBegin;
}
else
{
NewRange = newBegin - newEnd;
invFlag = 1;
}
zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange; // normalize to 0 - 1 float
// Check for originalMin > originalMax - the math for all other cases i.e. negative numbers seems to work out fine
if (originalMin > originalMax ) {
return 0;
}
if (invFlag == 0){
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
}
else // invert the ranges
{
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}
return rangedValue;
}
void loop() {
if(0 < Serial.available()) {
String str = Serial.readString();
char buffer[20];
str.toCharArray(buffer, 20);
int nRead= atoi(buffer);
Serial.println(nRead);
buttonPushCounter = nRead;
}
//for mic
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
// end mic
// Serial.println("loop");
// read the pushbutton input pin:
// buttonState = digitalRead(buttonPin);
// // compare the buttonState to its previous state
// if (buttonState != lastButtonState) {
// // if the state has changed, increment the counter
// if (buttonState == HIGH) {
// // if the current state is HIGH then the button
// // wend from off to on:
// buttonPushCounter++;
// Serial.println("on");
// Serial.print("number of button pushes: ");
// Serial.println(buttonPushCounter);
// if(buttonPushCounter==16) {
// buttonPushCounter=1;
// }
// }
// else {
// // if the current state is LOW then the button
// // wend from on to off:
// Serial.println("off");
// }
// }
// // save the current state as the last state,
// //for next time through the loop
// lastButtonState = buttonState;
switch (buttonPushCounter){
case 1:
buttonPushCounter==1; {
All2(); // NORMAL
break;}
case 2:
buttonPushCounter==2; {
vu(); // NORMAL
break;}
case 3:
buttonPushCounter==3; {
vu1(); // Centre out
break;}
case 4:
buttonPushCounter==4; {
vu2(); // Centre Inwards
break;}
case 5:
buttonPushCounter==5; {
Vu3(); // Normal Rainbow
break;}
case 6:
buttonPushCounter==6; {
Vu4(); // Centre rainbow
break;}
case 7:
buttonPushCounter==7; {
Vu5(0); // Shooting Star
break;}
case 71:
{
Vu5(1); // Shooting Star
break;}
case 72:
{
Vu5(2); // Shooting Star
break;}
case 8:
buttonPushCounter==8; {
Vu6(0); // Falling star
break;}
case 81:
buttonPushCounter==8; {
Vu6(1); // Falling star
break;}
case 82:
buttonPushCounter==8; {
Vu6(2); // Falling star
break;}
// case 9:
// buttonPushCounter==9; {
// vu7(); // Ripple with background
// break;}
case 10:
buttonPushCounter==10; {
vu8(); // Shatter
break;}
case 11:
buttonPushCounter==11; {
vu9(); // Pulse
break;}
case 12:
buttonPushCounter==12; {
vu10(); // stream
break;}
case 13:
buttonPushCounter==13; {
vu11(); // Ripple without Background
break;}
case 14:
buttonPushCounter==14; {
vu12(); // Ripple without Background
break;}
case 15:
buttonPushCounter==15; {
vu13(); // Ripple without Background
break;}
case 16:
buttonPushCounter==16; {
colorWipe(strip.Color(0, 0, 0), 10); // Black
break;}
}
// delay(1);
}
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip2.setPixelColor(i, c);
strip3.setPixelColor(i, c);
strip.show();
strip2.show();
strip3.show();
// if (digitalRead(buttonPin) != lastButtonState) // <------------- add this
// return; // <------------ and this
delay(wait);
}}
#define MAX_LEN 100
int array[MAX_LEN]; // 1sec
int valueOld = 0;
int mic_in() {
// put your main code here, to run repeatedly:
int value = analogRead(2) + 100;
memcpy(array, &array[1], sizeof(array) - sizeof(int));
array[MAX_LEN-1] = abs(value-valueOld);
valueOld = value;
double total = 0;
for(int i = 0; i < MAX_LEN; i++) {
total += array[i];
}
total /= MAX_LEN;
// Serial.println(total);
// Serial.print(',');
// Serial.println(value/4);
return total;
// return value/2;
}
void vu() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
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
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++) {
if(i >= height) {
strip.setPixelColor(i, 0, 0, 0);
strip2.setPixelColor(i, 0, 0, 0);
strip3.setPixelColor(i, 0, 0, 0);
}
else {
strip.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(i,Wheel(map(i,0,strip.numPixels()-1,30,150)));
}
}
// Draw peak dot
if(peak > 0 && peak <= N_PIXELS-1) {
strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
// Every few frames, make the peak pixel drop by 1:
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
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)
}
// Input a value 0 to 255 to get a color value.
// The colors are a transition r - g - b - back to r.
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);
}
}
void vu1() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
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
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS_HALF; i++) {
if(i >= height) {
strip.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip2.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip3.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
strip2.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
strip3.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
}
else {
uint32_t color = Wheel(map(i,0,N_PIXELS_HALF-1,30,150));
strip.setPixelColor(N_PIXELS_HALF-i-1,color);
strip2.setPixelColor(N_PIXELS_HALF-i-1,color);
strip3.setPixelColor(N_PIXELS_HALF-i-1,color);
strip.setPixelColor(N_PIXELS_HALF+i,color);
strip2.setPixelColor(N_PIXELS_HALF+i,color);
strip3.setPixelColor(N_PIXELS_HALF+i,color);
}
}
// Draw peak dot
if(peak > 0 && peak <= N_PIXELS_HALF-1) {
uint32_t color = Wheel(map(peak,0,N_PIXELS_HALF-1,30,150));
strip.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip2.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip3.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip.setPixelColor(N_PIXELS_HALF+peak,color);
strip2.setPixelColor(N_PIXELS_HALF+peak,color);
strip3.setPixelColor(N_PIXELS_HALF+peak,color);
}
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
// Every few frames, make the peak pixel drop by 1:
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
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)
}
void vu2()
{
unsigned long startMillis= millis(); // Start of sample window
float peakToPeak = 0; // peak-to-peak level
unsigned int signalMax = 0;
unsigned int signalMin = 1023;
unsigned int c, y;
while (millis() - startMillis < SAMPLE_WINDOW)
{
sample = mic_in(); // analogRead(MIC_PIN);
if (sample < 1024)
{
if (sample > signalMax)
{
signalMax = sample;
}
else if (sample < signalMin)
{
signalMin = sample;
}
}
}
peakToPeak = signalMax - signalMin;
// Serial.println(peakToPeak);
for (int i=0;i<=N_PIXELS_HALF-1;i++){
uint32_t color = Wheel(map(i,0,N_PIXELS_HALF-1,30,150));
strip.setPixelColor(N_PIXELS-i,color);
strip2.setPixelColor(N_PIXELS-i,color);
strip3.setPixelColor(N_PIXELS-i,color);
strip.setPixelColor(0+i,color);
strip2.setPixelColor(0+i,color);
strip3.setPixelColor(0+i,color);
}
c = fscale(INPUT_FLOOR, INPUT_CEILING, N_PIXELS_HALF, 0, peakToPeak, 2);
if(c < peak) {
peak = c; // Keep dot on top
dotHangCount = 0; // make the dot hang before falling
}
if (c <= strip.numPixels()) { // Fill partial column with off pixels
drawLine(N_PIXELS_HALF, N_PIXELS_HALF-c, strip.Color(0, 0, 0));
drawLine(N_PIXELS_HALF, N_PIXELS_HALF+c, strip.Color(0, 0, 0));
}
y = N_PIXELS_HALF - peak;
uint32_t color1 = Wheel(map(y,0,N_PIXELS_HALF-1,30,150));
strip.setPixelColor(y-1,color1);
strip2.setPixelColor(y-1,color1);
strip3.setPixelColor(y-1,color1);
//strip.setPixelColor(y-1,Wheel(map(y,0,N_PIXELS_HALF-1,30,150)));
y = N_PIXELS_HALF + peak;
strip.setPixelColor(y,color1);
strip2.setPixelColor(y,color1);
strip3.setPixelColor(y,color1);
//strip.setPixelColor(y+1,Wheel(map(y,0,N_PIXELS_HALF+1,30,150)));
strip.show();
strip2.show();
strip3.show();
// Frame based peak dot animation
if(dotHangCount > PEAK_HANG) { //Peak pause length
if(++dotCount >= PEAK_FALL2) { //Fall rate
peak++;
dotCount = 0;
}
}
else {
dotHangCount++;
}
}
void Vu3() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
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
greenOffset += SPEED;
blueOffset += SPEED;
if (greenOffset >= 255) greenOffset = 0;
if (blueOffset >= 255) blueOffset = 0;
// Color pixels based on rainbow gradient
for (i = 0; i < N_PIXELS; i++) {
if (i >= height) {
strip.setPixelColor(i, 0, 0, 0);
strip2.setPixelColor(i, 0, 0, 0);
strip3.setPixelColor(i, 0, 0, 0);
} else {
strip.setPixelColor(i, Wheel(
map(i, 0, strip.numPixels() - 1, (int)greenOffset, (int)blueOffset)
));
strip2.setPixelColor(i, Wheel(
map(i, 0, strip.numPixels() - 1, (int)greenOffset, (int)blueOffset)
));
strip3.setPixelColor(i, Wheel(
map(i, 0, strip.numPixels() - 1, (int)greenOffset, (int)blueOffset)
));
}
}
// Draw peak dot
if(peak > 0 && peak <= N_PIXELS-1) {
strip.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
// Every few frames, make the peak pixel drop by 1:
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
vol[volCount] = n;
if (++volCount >= SAMPLES) {
volCount = 0;
}
// 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)
}
void Vu4() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
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
greenOffset += SPEED;
blueOffset += SPEED;
if (greenOffset >= 255) greenOffset = 0;
if (blueOffset >= 255) blueOffset = 0;
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS_HALF; i++) {
if(i >= height) {
strip.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip2.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip3.setPixelColor(N_PIXELS_HALF-i-1, 0, 0, 0);
strip.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
strip2.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
strip3.setPixelColor(N_PIXELS_HALF+i, 0, 0, 0);
}
else {
uint32_t color = Wheel(map(i,0,N_PIXELS_HALF-1,(int)greenOffset, (int)blueOffset));
strip.setPixelColor(N_PIXELS_HALF-i-1,color);
strip2.setPixelColor(N_PIXELS_HALF-i-1,color);
strip3.setPixelColor(N_PIXELS_HALF-i-1,color);
strip.setPixelColor(N_PIXELS_HALF+i,color);
strip2.setPixelColor(N_PIXELS_HALF+i,color);
strip3.setPixelColor(N_PIXELS_HALF+i,color);
}
}
// Draw peak dot
if(peak > 0 && peak <= N_PIXELS_HALF-1) {
uint32_t color = Wheel(map(peak, 0, N_PIXELS_HALF-1, 30, 150));
strip.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip2.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip3.setPixelColor(N_PIXELS_HALF-peak-1,color);
strip.setPixelColor(N_PIXELS_HALF+peak,color);
strip2.setPixelColor(N_PIXELS_HALF+peak,color);
strip3.setPixelColor(N_PIXELS_HALF+peak,color);
}
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
// Every few frames, make the peak pixel drop by 1:
if(++dotCount >= PEAK_FALL) { //fall rate
if(peak > 0) peak--;
dotCount = 0;
}
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)
}
int vu5_timeout = 0;
void Vu5(int mode)
{
int i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
height = TOP2 * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if(height < 0L) height = 0; // Clip output
else if(height > TOP2) height = TOP2;
if(height > peak) peak = height; // Keep 'peak' dot at top
#ifdef CENTERED
// Color pixels based on rainbow gradient
for(i=0; i<(N_PIXELS/2); i++) {
if(((N_PIXELS/2)+i) >= height)
{
strip.setPixelColor(((N_PIXELS/2) + i), 0, 0, 0);
strip2.setPixelColor(((N_PIXELS/2) + i), 0, 0, 0);
strip3.setPixelColor(((N_PIXELS/2) + i), 0, 0, 0);
strip.setPixelColor(((N_PIXELS/2) - i), 0, 0, 0);
strip2.setPixelColor(((N_PIXELS/2) - i), 0, 0, 0);
strip3.setPixelColor(((N_PIXELS/2) - i), 0, 0, 0);
}
else
{
strip.setPixelColor(((N_PIXELS/2) + i),Wheel(map(((N_PIXELS/2) + i),0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(((N_PIXELS/2) + i),Wheel(map(((N_PIXELS/2) + i),0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(((N_PIXELS/2) + i),Wheel(map(((N_PIXELS/2) + i),0,strip.numPixels()-1,30,150)));
strip.setPixelColor(((N_PIXELS/2) - i),Wheel(map(((N_PIXELS/2) - i),0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(((N_PIXELS/2) - i),Wheel(map(((N_PIXELS/2) - i),0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(((N_PIXELS/2) - i),Wheel(map(((N_PIXELS/2) - i),0,strip.numPixels()-1,30,150)));
}
}
// Draw peak dot
if(peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(((N_PIXELS/2) + peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(((N_PIXELS/2) + peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(((N_PIXELS/2) + peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip.setPixelColor(((N_PIXELS/2) - peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(((N_PIXELS/2) - peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(((N_PIXELS/2) - peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
#else
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++)
{
if(i >= height)
{
strip.setPixelColor(i, 0, 0, 0);
// strip2.setPixelColor(i, 0, 0, 0);
// strip3.setPixelColor(i, 0, 0, 0);
}
else
{
strip.setPixelColor(i,
Wheel(map(i,0,
(mode == 0) ? strip.numPixels()-1 : 30,
(mode == 1) ? strip.numPixels()-1 : 30,
(mode == 2) ? strip.numPixels()-1 : 150
)));
/*
strip2.setPixelColor(i,
Wheel(map(i,0,
(mode == 0) ? strip.numPixels()-1 : 30,
(mode == 1) ? strip.numPixels()-1 : 30,
(mode == 2) ? strip.numPixels()-1 : 150
)));
strip3.setPixelColor(i,
Wheel(map(i,0,
(mode == 0) ? strip.numPixels()-1 : 30,
(mode == 1) ? strip.numPixels()-1 : 30,
(mode == 2) ? strip.numPixels()-1 : 150
))); */
}
}
// Draw peak dot
if(peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(peak,255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
// strip2.setPixelColor(peak,255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
// strip3.setPixelColor(peak,255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
#endif
// Every few frames, make the peak pixel drop by 1:
if (millis() - lastTime >= PEAK_FALL_MILLIS)
{
lastTime = millis();
strip.show(); // Update strip
// strip2.show(); // Update strip
// strip3.show(); // Update strip
vu5_timeout = 2;
//fall rate
if(peak > 0) peak--;
}
else {
if(0 < vu5_timeout) {
// Serial.println("#");
// if(vu5_timeout == 2) strip2.show(); // Update strip
// if(vu5_timeout == 1) strip3.show(); // Update strip
vu5_timeout -= 1;
}
}
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) < TOP2) maxLvl = minLvl + TOP2;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
void Vu6(int mode)
{
int i;
uint16_t minLvl, maxLvl;
int n, height;
n = mic_in(); // 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)
// Calculate bar height based on dynamic min/max levels (fixed point):
height = TOP2 * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if(height < 0L) height = 0; // Clip output
else if(height > TOP2) height = TOP2;
if(height > peak) peak = height; // Keep 'peak' dot at top
#ifdef CENTERED
// Draw peak dot
if(peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(((N_PIXELS/2) + peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip.setPixelColor(((N_PIXELS/2) - peak),255,255,255); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
#else
// Color pixels based on rainbow gradient
for(i=0; i<N_PIXELS; i++)
{
if(i >= height)
{
strip.setPixelColor(i, 0, 0, 0);
strip2.setPixelColor(i, 0, 0, 0);
strip3.setPixelColor(i, 0, 0, 0);
}
else
{
}
}
// Draw peak dot
if(peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(peak,
(mode == 0) ? 255 : 0,
(mode == 1) ? 255 : 0,
(mode == 2) ? 255 : 0); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip2.setPixelColor(peak,
(mode == 0) ? 255 : 0,
(mode == 1) ? 255 : 0,
(mode == 2) ? 255 : 0); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
strip3.setPixelColor(peak,
(mode == 0) ? 255 : 0,
(mode == 1) ? 255 : 0,
(mode == 2) ? 255 : 0); // (peak,Wheel(map(peak,0,strip.numPixels()-1,30,150)));
}
#endif
// Every few frames, make the peak pixel drop by 1:
if (millis() - lastTime >= PEAK_FALL_MILLIS)
{
lastTime = millis();
strip.show(); // Update strip
strip2.show(); // Update strip
strip3.show(); // Update strip
//fall rate
if(peak > 0) peak--;
}
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) < TOP2) maxLvl = minLvl + TOP2;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
void vu7() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue.
peakcount = 0; // Reset the counter every second.
}
soundmems();
EVERY_N_MILLISECONDS(20) {
ripple3();
}
show_at_max_brightness_for_power();
} // loop()
void soundmems() { // Rolling average counter - means we don't have to go through an array each time.
newtime = millis();
int tmp = mic_in() - 512; // analogRead(MIC_PIN) - 512;
sample = abs(tmp);
int potin = map(mic_in(), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array
sampleavg = samplesum / NSAMPLES; // Get an average
samplearray[samplecount] = sample; // Update oldest sample in the array with new sample
samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array
if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak.
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another.
step = -1;
peakcount++;
digitalWrite(13, HIGH);
oldtime = newtime;
}
} // soundmems()
void ripple3() {
for (int i = 0; i < N_PIXELS; i++) leds[i] = CHSV(bgcol, 255, sampleavg*2); // Set the background colour.
switch (step) {
case -1: // Initialize ripple variables.
center = random(N_PIXELS);
colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour.
step = 0;
bgcol = bgcol+8;
break;
case 0:
leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple.
step ++;
break;
case maxsteps: // At the end of the ripples.
// step = -1;
break;
default: // Middle of the ripples.
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller.
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2);
step ++; // Next step.
break;
} // switch step
} // ripple()
void vu8() {
int intensity = calculateIntensity();
updateOrigin(intensity);
assignDrawValues(intensity);
writeSegmented();
updateGlobals();
}
int calculateIntensity() {
int intensity;
reading = mic_in(); // analogRead(MIC_PIN); // Raw reading from mic
reading = abs(reading - 512 - DC_OFFSET); // Center on zero
reading = (reading <= NOISE) ? 0 : (reading - NOISE); // Remove noise/hum
lvl = ((lvl * 7) + reading) >> 3; // "Dampened" reading (else looks twitchy)
// Calculate bar height based on dynamic min/max levels (fixed point):
intensity = DRAW_MAX * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
return constrain(intensity, 0, DRAW_MAX-1);
}
void updateOrigin(int intensity) {
// detect peak change and save origin at curve vertex
if (growing && intensity < last_intensity) {
growing = false;
intensity_max = last_intensity;
fall_from_left = !fall_from_left;
origin_at_flip = origin;
} else if (intensity > last_intensity) {
growing = true;
origin_at_flip = origin;
}
last_intensity = intensity;
// adjust origin if falling
if (!growing) {
if (fall_from_left) {
origin = origin_at_flip + ((intensity_max - intensity) / 2);
} else {
origin = origin_at_flip - ((intensity_max - intensity) / 2);
}
// correct for origin out of bounds
if (origin < 0) {
origin = DRAW_MAX - abs(origin);
} else if (origin > DRAW_MAX - 1) {
origin = origin - DRAW_MAX - 1;
}
}
}
void assignDrawValues(int intensity) {
// draw amplitue as 1/2 intensity both directions from origin
int min_lit = origin - (intensity / 2);
int max_lit = origin + (intensity / 2);
if (min_lit < 0) {
min_lit = min_lit + DRAW_MAX;
}
if (max_lit >= DRAW_MAX) {
max_lit = max_lit - DRAW_MAX;
}
for (int i=0; i < DRAW_MAX; i++) {
// if i is within origin +/- 1/2 intensity
if (
(min_lit < max_lit && min_lit < i && i < max_lit) // range is within bounds and i is within range
|| (min_lit > max_lit && (i > min_lit || i < max_lit)) // range wraps out of bounds and i is within that wrap
) {
draw[i] = Wheel(scroll_color);
} else {
draw[i] = 0;
}
}
}
void writeSegmented() {
int seg_len = N_PIXELS / SEGMENTS;
for (int s = 0; s < SEGMENTS; s++) {
for (int i = 0; i < seg_len; i++) {
strip.setPixelColor(i + (s*seg_len), draw[map(i, 0, seg_len, 0, DRAW_MAX)]);
strip2.setPixelColor(i + (s*seg_len), draw[map(i, 0, seg_len, 0, DRAW_MAX)]);
strip3.setPixelColor(i + (s*seg_len), draw[map(i, 0, seg_len, 0, DRAW_MAX)]);
}
}
strip.show();
strip2.show();
strip3.show();
}
uint32_t * segmentAndResize(uint32_t* draw) {
int seg_len = N_PIXELS / SEGMENTS;
uint32_t segmented[N_PIXELS];
for (int s = 0; s < SEGMENTS; s++) {
for (int i = 0; i < seg_len; i++) {
segmented[i + (s * seg_len) ] = draw[map(i, 0, seg_len, 0, DRAW_MAX)];
}
}
return segmented;
}
void writeToStrip(uint32_t* draw) {
for (int i = 0; i < N_PIXELS; i++) {
strip.setPixelColor(i, draw[i]);
strip2.setPixelColor(i, draw[i]);
strip3.setPixelColor(i, draw[i]);
}
strip.show();
strip2.show();
strip3.show();
}
void updateGlobals() {
uint16_t minLvl, maxLvl;
//advance color wheel
color_wait_count++;
if (color_wait_count > COLOR_WAIT_CYCLES) {
color_wait_count = 0;
scroll_color++;
if (scroll_color > COLOR_MAX) {
scroll_color = COLOR_MIN;
}
}
vol[volCount] = reading; // 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(uint8_t 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) < N_PIXELS) maxLvl = minLvl + N_PIXELS;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6; // Dampen min/max levels
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6; // (fake rolling average)
}
void vu9() {
//currentBlending = LINEARBLEND;
currentPalette = OceanColors_p; // Initial palette.
currentBlending = LINEARBLEND;
EVERY_N_SECONDS(5) { // Change the palette every 5 seconds.
for (int i = 0; i < 16; i++) {
targetPalette[i] = CHSV(random8(), 255, 255);
}
}
EVERY_N_MILLISECONDS(100) { // AWESOME palette blending capability once they do change.
uint8_t maxChanges = 24;
nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges);
}
EVERY_N_MILLIS_I(thistimer,20) { // For fun, let's make the animation have a variable rate.
uint8_t timeval = beatsin8(10,20,50); // Use a sinewave for the line below. Could also use peak/beat detection.
thistimer.setPeriod(timeval); // Allows you to change how often this routine runs.
fadeToBlackBy(leds, N_PIXELS, 16); // 1 = slow, 255 = fast fade. Depending on the faderate, the LED's further away will fade out.
sndwave();
soundble();
}
FastLED.setBrightness(max_bright);
FastLED.show();
} // loop()
void soundble() { // Quick and dirty sampling of the microphone.
int tmp = mic_in() - 512 - DC_OFFSET;
sample = abs(tmp);
} // soundmems()
void sndwave() {
leds[N_PIXELS/2] = ColorFromPalette(currentPalette, sample, sample*2, currentBlending); // Put the sample into the center
for (int i = N_PIXELS - 1; i > N_PIXELS/2; i--) { //move to the left // Copy to the left, and let the fade do the rest.
leds[i] = leds[i - 1];
}
for (int i = 0; i < N_PIXELS/2; i++) { // move to the right // Copy to the right, and let the fade to the rest.
leds[i] = leds[i + 1];
}
addGlitter(sampleavg);
}
void vu10() {
EVERY_N_SECONDS(5) { // Change the target palette to a random one every 5 seconds.
static uint8_t baseC = random8(); // You can use this as a baseline colour if you want similar hues in the next line.
for (int i = 0; i < 16; i++) {
targetPalette[i] = CHSV(random8(), 255, 255);
}
}
EVERY_N_MILLISECONDS(100) {
uint8_t maxChanges = 24;
nblendPaletteTowardPalette(currentPalette, targetPalette, maxChanges); // AWESOME palette blending capability.
}
EVERY_N_MILLISECONDS(thisdelay) { // FastLED based non-blocking delay to update/display the sequence.
soundtun();
FastLED.setBrightness(max_bright);
FastLED.show();
}
} // loop()
void soundtun() {
int n;
n = mic_in(); // analogRead(MIC_PIN); // Raw reading from mic
n = qsuba(abs(n-512), 10); // Center on zero and get rid of low level noise
CRGB newcolour = ColorFromPalette(currentPalette, constrain(n,0,255), constrain(n,0,255), currentBlending);
nblend(leds[0], newcolour, 128);
for (int i = N_PIXELS-1; i>0; i--) {
leds[i] = leds[i-1];
}
} // soundmems()
void vu11() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue.
peakcount = 0; // Reset the counter every second.
}
soundrip();
EVERY_N_MILLISECONDS(20) {
rippled();
}
FastLED.show();
} // loop()
void soundrip() { // Rolling average counter - means we don't have to go through an array each time.
newtime = millis();
int tmp = mic_in() - 512;
sample = abs(tmp);
int potin = map(mic_in(), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array
sampleavg = samplesum / NSAMPLES; // Get an average
Serial.println(sampleavg);
samplearray[samplecount] = sample; // Update oldest sample in the array with new sample
samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array
if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak.
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another.
step = -1;
peakcount++;
oldtime = newtime;
}
} // soundmems()
void rippled() {
fadeToBlackBy(leds, N_PIXELS, 64); // 8 bit, 1 = slow, 255 = fast
switch (step) {
case -1: // Initialize ripple variables.
center = random(N_PIXELS);
colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour.
step = 0;
break;
case 0:
leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple.
step ++;
break;
case maxsteps: // At the end of the ripples.
// step = -1;
break;
default: // Middle of the ripples.
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller.
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2);
step ++; // Next step.
break;
} // switch step
} // ripple()
//Used to draw a line between two points of a given color
void drawLine(uint8_t from, uint8_t to, uint32_t c) {
uint8_t fromTemp;
if (from > to) {
fromTemp = from;
from = to;
to = fromTemp;
}
for(int i=from; i<=to; i++){
strip.setPixelColor(i, c);
strip2.setPixelColor(i, c);
strip3.setPixelColor(i, c);
}
}
void setPixel(int Pixel, byte red, byte green, byte blue) {
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
strip2.setPixelColor(Pixel, strip.Color(red, green, blue));
strip3.setPixelColor(Pixel, strip.Color(red, green, blue));
}
void setAll(byte red, byte green, byte blue) {
for(int i = 0; i < N_PIXELS; i++ ) {
setPixel(i, red, green, blue);
}
strip.show();
strip2.show();
strip3.show();
}
void vu12() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue.
peakcount = 0; // Reset the counter every second.
}
soundripped();
EVERY_N_MILLISECONDS(20) {
rippvu();
}
FastLED.show();
} // loop()
void soundripped() { // Rolling average counter - means we don't have to go through an array each time.
newtime = millis();
int tmp = mic_in() - 512;
sample = abs(tmp);
int potin = map(mic_in(), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array
sampleavg = samplesum / NSAMPLES; // Get an average
Serial.println(sampleavg);
samplearray[samplecount] = sample; // Update oldest sample in the array with new sample
samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array
if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak.
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another.
step = -1;
peakcount++;
oldtime = newtime;
}
} // soundmems()
void rippvu() { // Display ripples triggered by peaks.
fadeToBlackBy(leds, N_PIXELS, 64); // 8 bit, 1 = slow, 255 = fast
switch (step) {
case -1: // Initialize ripple variables.
center = random(N_PIXELS);
colour = (peakspersec*10) % 255; // More peaks/s = higher the hue colour.
step = 0;
break;
case 0:
leds[center] = CHSV(colour, 255, 255); // Display the first pixel of the ripple.
step ++;
break;
case maxsteps: // At the end of the ripples.
// step = -1;
break;
default: // Middle of the ripples.
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2); // Simple wrap from Marc Miller.
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade/step*2);
step ++; // Next step.
break;
} // switch step
addGlitter(sampleavg);
} // ripple()
void vu13() { // The >>>>>>>>>> L-O-O-P <<<<<<<<<<<<<<<<<<<<<<<<<<<< is buried here!!!11!1!
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; // Count the peaks per second. This value will become the foreground hue.
peakcount = 0; // Reset the counter every second.
}
soundripper();
EVERY_N_MILLISECONDS(20) {
jugglep();
}
FastLED.show();
} // loop()
void soundripper() { // Rolling average counter - means we don't have to go through an array each time.
newtime = millis();
int tmp = mic_in() - 512;
sample = abs(tmp);
int potin = map(mic_in(), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount]; // Add the new sample and remove the oldest sample in the array
sampleavg = samplesum / NSAMPLES; // Get an average
Serial.println(sampleavg);
samplearray[samplecount] = sample; // Update oldest sample in the array with new sample
samplecount = (samplecount + 1) % NSAMPLES; // Update the counter for the array
if (newtime > (oldtime + 200)) digitalWrite(13, LOW); // Turn the LED off 200ms after the last peak.
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) { // Check for a peak, which is 30 > the average, but wait at least 60ms for another.
step = -1;
peakcount++;
oldtime = newtime;
// Change the current pattern function periodically.
jugglep();
}
} // loop()
void jugglep() { // Use the juggle routine, but adjust the timebase based on sampleavg for some randomness.
// Persistent local variables
static uint8_t thishue=0;
timeval = 40; // Our EVERY_N_MILLIS_I timer value.
leds[0] = ColorFromPalette(currentPalette, thishue++, sampleavg, LINEARBLEND);
for (int i = N_PIXELS-1; i >0 ; i-- ) leds[i] = leds[i-1];
addGlitter(sampleavg/2); // Add glitter based on sampleavg. By Andrew Tuline.
} // matrix()
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos, float opacity) {
if(WheelPos < 85) {
return strip.Color((WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity, 0);
}
else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color((255 - WheelPos * 3) * opacity, 0, (WheelPos * 3) * opacity);
}
else {
WheelPos -= 170;
return strip.Color(0, (WheelPos * 3) * opacity, (255 - WheelPos * 3) * opacity);
}
}
void addGlitter( fract8 chanceOfGlitter) { // Let's add some glitter, thanks to Mark
if( random8() < chanceOfGlitter) {
leds[random16(N_PIXELS)] += CRGB::White;
}
} // addGlitter()
// List of patterns to cycle through. Each is defined as a separate function below.
// typedef void (*SimplePatternList[])();
// SimplePatternList qPatterns = {vu, vu1, vu2, Vu3, Vu4, Vu5, Vu6, vu7, vu8, vu9, vu10, vu11, vu12, vu13};
// uint8_t qCurrentPatternNumber = 0; // Index number of which pattern is current
// void nextPattern2()
// {
// // add one to the current pattern number, and wrap around at the end
// qCurrentPatternNumber = (qCurrentPatternNumber + 1) % ARRAY_SIZE( qPatterns);
// }
void All2()
{
// Call the current pattern function once, updating the 'leds' array
// qPatterns[qCurrentPatternNumber]();
// EVERY_N_SECONDS( 30 ) { nextPattern2(); } // change patterns periodically
}
음량에 따라 다른 LED 패턴 변경
사운드 음량 표시 - 시리얼 플로터
'임베디드 보드 > ESP32' 카테고리의 다른 글
Raspberry Pico + Ethernet W5500 (0) | 2022.03.07 |
---|---|
ESP32 + Ethernet W5500 (0) | 2022.02.25 |
ESP32 + LED STRIP + 블루투스 제어 (0) | 2021.12.30 |
ESP32 DOWNLOAD (0) | 2021.12.29 |
ESP8266 on thingsboard server (0) | 2021.05.01 |