当前位置:网站首页>[flower carving hands-on] fun music visualization series small project (12) -- meter tube fast rhythm light
[flower carving hands-on] fun music visualization series small project (12) -- meter tube fast rhythm light
2022-07-26 13:14:00 【Lvyou flower carving】
Accidental whim , I want to do a series of topics of sound visualization . This topic is a little difficult , It also covers a wide range , dependent FFT and FHT And other algorithms are also quite complex , But I still plan to start with the simplest , Experiment with hands-on , Try various schemes patiently , Gradually accumulate some useful music spectrum visualization data , We will also strive to form some practical and fun music visualizer projects .
Flower carving hands-on 】 Interesting music visualization project (12)— Meter tube fast rhythm lamp
Discarded lamp tubes found , Prepare to use , Make a one meter two fast-paced lamp

Saw off both heads , Pull out the inside LED Lamp sheet

I found two flowerpot chassis , When the lamp socket

Use multi-stage reaming drill

The lamp base is expanded in three seconds 28mm

The development board uses universal CORE ESP32-C3

Main features
(1) Strong function , Widely used
Hezhou ESP32-C3 Development board highly integrated design , On board Wi-Fi/BLE The antenna 、4MB Flash, Support UART、GPIO、SPI、I2C、ADC、PWM Such as the interface , Meet most applications ; On board CH343P The chip can achieve higher rate USB To serial port , Firmware downloads are faster and more stable .
(2) Enough material , Good signal
Hezhou ESP32-C3 Development board adopts 4 layer PCB, On board 2.4G The antenna , After debugging, it has achieved a better effect . Actually measured 2.38 To 2.48GHz Standing wave ratio in the range (VSWR) The value is better. , It can effectively radiate the transmission power to the wireless space .
(3) Diversified development is more convenient
Hezhou ESP32-C3 Currently supported by the development board :LuatOS/ Lexin IDF/Arduino/MicroPython And other diversified development methods , Easier to use .LuatOS With the efforts of the community God Mengcheng, the firmware now supports the following functions , Other content is constantly updated .
ESP32-C3 Core board IO Pin figure 
1 road SPI FLASH, On board 4MB, Support the highest 16MB
2 road UART Interface ,UART0~UART1, The download port is UART0
6 road 12 The bit ADC, The highest sampling rate 100KSPS
1 The road is slow SPI Interface , Support main mode
1 road IIC controller
4 road PWM Interface
GPIO External pins 15 road , Reusable
2 Road patch LED Indicator light
1 Channel reset button +1 road BOOT Key
1 road USB turn TTL Download debug port
2.4G PCB Onboard antenna
The sound module uses MAX9814
MAX9814 It is a low-cost high-performance microphone amplifier , With automatic gain control (AGC) And low noise microphone offset . The device has a low-noise front-end amplifier 、 Variable gain amplification (VGA)、 Output amplifier 、 Microphone bias voltage generator and AGC Control circuit .
● Automatic gain control (AGC)
●3 Kinds of gain settings (40dB、50dB、60dB)
● Programmable action time
● Programmable action and release time ratio
● Power supply voltage range 2.7V~5.5V
● low THD:0.04% ( Typical values )
● Low power shutdown mode
● built-in 2V Low noise microphone offset
Use colored lights WS2812B

Its main characteristics are
Intelligent reverse connection protection , The reverse connection of power supply will not damage IC.
IC Control circuit and LED Point lights share a common power supply .
Control circuit and RGB The chip is integrated in a 5050 In the encapsulated components , Form a complete external control pixel .
Built in signal shaping circuit , After any pixel receives the signal, it will be output after waveform shaping , Ensure that the line waveform distortion will not accumulate .
Built in power on reset and power off reset circuits .
The three primary colors of each pixel can realize 256 Level brightness display , complete 16777216 Full color display of two colors , The scanning frequency is not less than 400Hz/s.
Serial cascade interface , It can receive and decode data through a signal line .
The transmission distance between any two points shall not exceed 5 There is no need to add any circuit when measuring meters .
When the refresh rate 30 frame / seconds , The number of cascades shall not be less than 1024 spot .
The data transmission speed can reach 800Kbps.
The color of light is highly consistent , High cost performance .
Main application fields
LED Full color luminous word lamp string ,LED Full color module , LED Full color soft light bar hard light bar ,LED Guardrail tube .
LED Point source ,LED Pixel screen ,LED Profiled screen , All kinds of electronic products , Electrical equipment, running lights .
WS2812B The light band is selected per meter 60 Bare board with black background

WS2812 Electrical schematic diagram of the module

WS2812B It is a combination of control circuit and light-emitting circuit LED Light source element , Its control IC by WS2812B, The light-emitting element is 5050RGBLED, Voltage is 5V, The peak current per unit is 60ma, The light band is made of three wires ,VCC GND DIN They are power supply +、 Power Supply -、 The signal , When using external power , External power supply - Need to be connected with SCM GND Connected to a .



Put the lamp belt into the lamp tube ( I cut it here 70 A lamp bead )

Lamp base counterweight , Later, the marble plan was adopted , Zero cost and high cost performance

Project use Arduino IDE Burn program

The detailed configuration of the development board is shown in the figure

Install the relevant drive library



【 Flower carving hands-on 】 Interesting music visualization (12)– Meter tube fast rhythm lamp
Relevant procedures :MegunoLink Musical reaction LED Lamp with
Module wiring :WS2812B Pick up D9
MAX9814 ESP32_C3
VCC 5V
GND GND
OUT D4(ADC4)
/* 【 Flower carving hands-on 】 Interesting music visualization (12)-- Meter tube fast rhythm lamp Relevant procedures :MegunoLink Musical reaction LED Lamp with Module wiring :WS2812B Pick up D9 MAX9814 ESP32_C3 VCC 5V GND GND OUT D4(ADC4) */
#include<FastLED.h>
#include<MegunoLink.h>
#include<Filter.h>
#define N_PIXELS 70
#define MIC_PIN 4
#define LED_PIN 9
#define NOISE 150
#define TOP (N_PIXELS+2)
#define LED_TYPE WS2811
#define BRIGHTNESS 18
#define COLOR_ORDER GRB
CRGB leds[N_PIXELS];
int lvl = 0, minLvl = 0, maxLvl = 100;
ExponentialFilter<long> ADCFilter(5,0);
void setup() {
Serial.begin(115200);
FastLED.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,N_PIXELS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
}
void loop() {
int n, height;
n = analogRead(MIC_PIN);
n = abs(1023 - n);
n = (n <= NOISE) ? 0 : abs(n - NOISE);
ADCFilter.Filter(n);
lvl = ADCFilter.Current();
height = TOP * (lvl - minLvl) / (long)(maxLvl - minLvl);
if(height < 0L) height = 0;
else if(height > TOP) height = TOP;
for(uint8_t i = 0; i < N_PIXELS; i++) {
if(i >= height) leds[i] = CRGB(0,0,0);
// otherwise, turn them on!
else leds[i] = Wheel( map( i, 0, N_PIXELS-1, 30, 150 ) );
}
FastLED.show();
}
CRGB Wheel(byte WheelPos) {
if(WheelPos < 85)
return CRGB(WheelPos * 3, 255 - WheelPos * 3, 0);
else if(WheelPos < 170) {
WheelPos -= 85;
return CRGB(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return CRGB(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
Experimental scene

Experimental scene Dynamic graph
https://img.mydigit.cn/forum/202207/24/155142ahnctgez2npccenr.gif
Video recording of the experiment (4 branch 57 second )
https://v.youku.com/v_show/id_XNTg4ODE1MTAwOA==.html?spm=a2hcb.playlsit.page.1
Experimental scene

Experimental scene Dynamic graph
https://img.mydigit.cn/forum/202207/25/092209rcucyzgrntvcz5cy.gif
Video recording of the experiment
https://v.youku.com/v_show/id_XNTg4ODE4NTY0MA==.html?spm=a2hcb.playlsit.page.1
Video recording of the experiment 2
https://v.youku.com/v_show/id_XNTg4OTMxMTUyOA==.html?spm=a2hcb.playlsit.page.1
Video recording of the experiment 3
https://v.youku.com/v_show/id_XNTg4OTMxMTk3Mg==.html?spm=a2hcb.playlsit.page.1
Video recording of the experiment 4
https://v.youku.com/v_show/id_XNTg4OTMxMTcxMg==.html?spm=a2hcb.playlsit.page.5
【 Flower carving hands-on 】 Interesting music visualization (12)– Meter tube fast rhythm lamp
Related procedure II :SoftwareSerial Meter tube music spectrum lamp
Module wiring :WS2812B Pick up D6
MAX9814 UNO
VCC 5V
GND GND
OUT A0
/* 【 Flower carving hands-on 】 Interesting music visualization (12)-- Meter tube fast rhythm lamp Related procedure II :SoftwareSerial Meter tube music spectrum lamp Module wiring :WS2812B Pick up D6 MAX9814 UNO VCC 5V GND GND OUT A0 */
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
#include <math.h>
#include <SoftwareSerial.h>
#define N_PIXELS 70
#define N_PIXELS_HALF (N_PIXELS/2)
#define MIC_PIN A0
#define LED_PIN 6
#define SAMPLE_WINDOW 10
#define PEAK_HANG 24
#define PEAK_FALL 20
#define PEAK_FALL2 8
#define INPUT_FLOOR 10
#define INPUT_CEILING 300
#define DC_OFFSET 0
#define NOISE 10
#define SAMPLES 60
#define TOP (N_PIXELS + 2)
#define SPEED .20
#define TOP2 (N_PIXELS + 1)
#define LAST_PIXEL_OFFSET N_PIXELS-1
#define PEAK_FALL_MILLIS 10
#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
#define COLOR_ORDER GRB
#define COLOR_MIN 0
#define COLOR_MAX 255
#define DRAW_MAX 100
#define SEGMENTS 4
#define COLOR_WAIT_CYCLES 10
#define qsubd(x, b) ((x>b)?b:0)
#define qsuba(x, b) ((x>b)?x-b:0)
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
struct CRGB leds[N_PIXELS];
Adafruit_NeoPixel strip = Adafruit_NeoPixel(N_PIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
static uint16_t dist;
uint16_t scale = 30;
uint8_t maxChanges = 48;
CRGBPalette16 currentPalette(OceanColors_p);
CRGBPalette16 targetPalette(CloudColors_p);
uint8_t timeval = 20;
uint16_t loops = 0;
bool samplepeak = 0;
uint16_t oldsample = 0;
bool thisdir = 0;
enum
{
} MODE;
bool reverse = true;
int BRIGHTNESS_MAX = 80;
int brightness = 20;
byte
// peak = 0,
// dotCount = 0,
volCount = 0;
int
reading,
vol[SAMPLES],
lvl = 10,
minLvlAvg = 0,
maxLvlAvg = 512;
float
greenOffset = 30,
blueOffset = 150;
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;
uint8_t colour;
uint8_t myfade = 255;
#define maxsteps 16
int peakspersec = 0;
int peakcount = 0;
uint8_t bgcol = 0;
int thisdelay = 20;
uint8_t max_bright = 255;
unsigned int sample;
#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;
int color;
int center = 0;
int step = -1;
int maxSteps = 16;
float fadeRate = 0.80;
int diff;
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;
uint32_t currentBg = random(256);
uint32_t nextBg = currentBg;
TBlendType currentBlending;
const int buttonPin = 0;
int buttonPushCounter = 0;
int buttonState = 0;
int lastButtonState = 0;
byte peak = 16;
byte dotCount = 0;
byte dotHangCount = 0;
void setup() {
analogReference(EXTERNAL);
pinMode(buttonPin, INPUT);
digitalWrite(buttonPin, HIGH);
// Serial.begin(9600);
strip.begin();
strip.show(); // all pixels to 'off'
Serial.begin(57600);
delay(3000);
LEDS.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, N_PIXELS).setCorrection(TypicalLEDStrip);
LEDS.setBrightness(BRIGHTNESS);
dist = random16(12345);
}
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;
if (curve > 10) curve = 10;
if (curve < -10) curve = -10;
curve = (curve * -.1) ;
curve = pow(10, curve);
if (inputValue < originalMin) {
inputValue = originalMin;
}
if (inputValue > originalMax) {
inputValue = originalMax;
}
OriginalRange = originalMax - originalMin;
if (newEnd > newBegin) {
NewRange = newEnd - newBegin;
}
else
{
NewRange = newBegin - newEnd;
invFlag = 1;
}
zeroRefCurVal = inputValue - originalMin;
normalizedCurVal = zeroRefCurVal / OriginalRange;
if (originalMin > originalMax ) {
return 0;
}
if (invFlag == 0) {
rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
}
else
{
rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
}
return rangedValue;
}
void loop() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter++;
Serial.println("on");
Serial.print("number of button pushes: ");
Serial.println(buttonPushCounter);
if (buttonPushCounter == 16) {
buttonPushCounter = 1;
}
}
else {
Serial.println("off");
}
}
lastButtonState = buttonState;
switch (buttonPushCounter) {
case 1:
buttonPushCounter == 1; {
All2();
break;
}
case 2:
buttonPushCounter == 2; {
vu();
break;
}
case 3:
buttonPushCounter == 3; {
vu1();
break;
}
case 4:
buttonPushCounter == 4; {
vu2();
break;
}
case 5:
buttonPushCounter == 5; {
Vu3();
break;
}
case 6:
buttonPushCounter == 6; {
Vu4();
break;
}
case 7:
buttonPushCounter == 7; {
Vu5();
break;
}
case 8:
buttonPushCounter == 8; {
Vu6();
break;
}
case 9:
buttonPushCounter == 9; {
vu7();
break;
}
case 10:
buttonPushCounter == 10; {
vu8();
break;
}
case 11:
buttonPushCounter == 11; {
vu9();
break;
}
case 12:
buttonPushCounter == 12; {
vu10();
break;
}
case 13:
buttonPushCounter == 13; {
vu11();
break;
}
case 14:
buttonPushCounter == 14; {
vu12();
break;
}
case 15:
buttonPushCounter == 15; {
vu13();
break;
}
case 16:
buttonPushCounter == 16; {
colorWipe(strip.Color(0, 0, 0), 10);
break;
}
}
}
void colorWipe(uint32_t c, uint8_t wait) {
for (uint16_t i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
if (digitalRead(buttonPin) != lastButtonState)
return;
delay(wait);
}
}
void vu() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP) height = TOP;
if (height > peak) peak = height;
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)));
}
if (peak > 0 && peak <= N_PIXELS - 1) strip.setPixelColor(peak, Wheel(map(peak, 0, strip.numPixels() - 1, 30, 150)));
strip.show();
if (++dotCount >= PEAK_FALL) {
if (peak > 0) peak--;
dotCount = 0;
}
vol[volCount] = n;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
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 = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP) height = TOP;
if (height > peak) peak = height;
for (i = 0; i < N_PIXELS_HALF; i++) {
if (i >= height) {
strip.setPixelColor(N_PIXELS_HALF - i - 1, 0, 0, 0);
strip.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);
strip.setPixelColor(N_PIXELS_HALF + i, color);
}
}
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);
strip.setPixelColor(N_PIXELS_HALF + peak, color);
}
strip.show();
if (++dotCount >= PEAK_FALL) {
//fall rate
if (peak > 0) peak--;
dotCount = 0;
}
vol[volCount] = n;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void vu2()
{
unsigned long startMillis = millis();
float peakToPeak = 0;
unsigned int signalMax = 0;
unsigned int signalMin = 1023;
unsigned int c, y;
while (millis() - startMillis < SAMPLE_WINDOW)
{
sample = analogRead(MIC_PIN);
if (sample < 1024)
{
if (sample > signalMax)
{
signalMax = sample;
}
else if (sample < signalMin)
{
signalMin = sample;
}
}
}
peakToPeak = signalMax - signalMin;
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);
strip.setPixelColor(0 + i, color);
}
c = fscale(INPUT_FLOOR, INPUT_CEILING, N_PIXELS_HALF, 0, peakToPeak, 2);
if (c < peak) {
peak = c;
dotHangCount = 0;
}
if (c <= strip.numPixels()) {
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);
y = N_PIXELS_HALF + peak;
strip.setPixelColor(y, color1);
strip.show();
if (dotHangCount > PEAK_HANG) {
if (++dotCount >= PEAK_FALL2) {
peak++;
dotCount = 0;
}
}
else {
dotHangCount++;
}
}
void Vu3() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP) height = TOP;
if (height > peak) peak = height;
greenOffset += SPEED;
blueOffset += SPEED;
if (greenOffset >= 255) greenOffset = 0;
if (blueOffset >= 255) blueOffset = 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, (int)greenOffset, (int)blueOffset)
));
}
}
if (peak > 0 && peak <= N_PIXELS - 1) strip.setPixelColor(peak, Wheel(map(peak, 0, strip.numPixels() - 1, 30, 150)));
strip.show();
if (++dotCount >= PEAK_FALL) {
if (peak > 0) peak--;
dotCount = 0;
}
strip.show();
vol[volCount] = n;
if (++volCount >= SAMPLES) {
volCount = 0;
}
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];
}
}
if ((maxLvl - minLvl) < TOP) {
maxLvl = minLvl + TOP;
}
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void Vu4() {
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP) height = TOP;
if (height > peak) peak = height;
greenOffset += SPEED;
blueOffset += SPEED;
if (greenOffset >= 255) greenOffset = 0;
if (blueOffset >= 255) blueOffset = 0;
for (i = 0; i < N_PIXELS_HALF; i++) {
if (i >= height) {
strip.setPixelColor(N_PIXELS_HALF - i - 1, 0, 0, 0);
strip.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);
strip.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);
strip.setPixelColor(N_PIXELS_HALF + peak, color);
}
strip.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;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < TOP) maxLvl = minLvl + TOP;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void Vu5()
{
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP2 * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP2) height = TOP2;
if (height > peak) peak = height;
#ifdef CENTERED
for (i = 0; i < (N_PIXELS / 2); i++) {
if (((N_PIXELS / 2) + i) >= height)
{
strip.setPixelColor(((N_PIXELS / 2) + i), 0, 0, 0);
strip.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)));
strip.setPixelColor(((N_PIXELS / 2) - i), Wheel(map(((N_PIXELS / 2) - i), 0, strip.numPixels() - 1, 30, 150)));
}
}
if (peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(((N_PIXELS / 2) + peak), 255, 255, 255);
strip.setPixelColor(((N_PIXELS / 2) - peak), 255, 255, 255);
}
#else
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)));
}
}
if (peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(peak, 255, 255, 255);
}
#endif
if (millis() - lastTime >= PEAK_FALL_MILLIS)
{
lastTime = millis();
strip.show();
if (peak > 0) peak--;
}
vol[volCount] = n;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < TOP2) maxLvl = minLvl + TOP2;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void Vu6()
{
uint8_t i;
uint16_t minLvl, maxLvl;
int n, height;
n = analogRead(MIC_PIN);
n = abs(n - 512 - DC_OFFSET);
n = (n <= NOISE) ? 0 : (n - NOISE);
lvl = ((lvl * 7) + n) >> 3;
height = TOP2 * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
if (height < 0L) height = 0;
else if (height > TOP2) height = TOP2;
if (height > peak) peak = height;
#ifdef CENTERED
if (peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(((N_PIXELS / 2) + peak), 255, 255, 255);
strip.setPixelColor(((N_PIXELS / 2) - peak), 255, 255, 255);
}
#else
// Color pixels based on rainbow gradient
for (i = 0; i < N_PIXELS; i++)
{
if (i >= height)
{
strip.setPixelColor(i, 0, 0, 0);
}
else
{
}
}
// Draw peak dot
if (peak > 0 && peak <= LAST_PIXEL_OFFSET)
{
strip.setPixelColor(peak, 0, 0, 255);
}
#endif
// Every few frames, make the peak pixel drop by 1:
if (millis() - lastTime >= PEAK_FALL_MILLIS)
{
lastTime = millis();
strip.show(); // Update strip
//fall rate
if (peak > 0) peak--;
}
vol[volCount] = n;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < TOP2) maxLvl = minLvl + TOP2;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void vu7() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount;
peakcount = 0;
}
soundmems();
EVERY_N_MILLISECONDS(20) {
ripple3();
}
show_at_max_brightness_for_power();
}
void soundmems() {
newtime = millis();
int tmp = analogRead(MIC_PIN) - 512;
sample = abs(tmp);
int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount];
sampleavg = samplesum / NSAMPLES;
samplearray[samplecount] = sample;
samplecount = (samplecount + 1) % NSAMPLES;
if (newtime > (oldtime + 200)) digitalWrite(13, LOW);
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) {
step = -1;
peakcount++;
digitalWrite(13, HIGH);
oldtime = newtime;
}
}
void ripple3() {
for (int i = 0; i < N_PIXELS; i++) leds[i] = CHSV(bgcol, 255, sampleavg * 2);
switch (step) {
case -1:
center = random(N_PIXELS);
colour = (peakspersec * 10) % 255;
step = 0;
bgcol = bgcol + 8;
break;
case 0:
leds[center] = CHSV(colour, 255, 255);
step ++;
break;
case maxsteps:
break;
default:
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
step ++;
break;
}
}
void vu8() {
int intensity = calculateIntensity();
updateOrigin(intensity);
assignDrawValues(intensity);
writeSegmented();
updateGlobals();
}
int calculateIntensity() {
int intensity;
reading = analogRead(MIC_PIN);
reading = abs(reading - 512 - DC_OFFSET);
reading = (reading <= NOISE) ? 0 : (reading - NOISE);
lvl = ((lvl * 7) + reading) >> 3;
intensity = DRAW_MAX * (lvl - minLvlAvg) / (long)(maxLvlAvg - minLvlAvg);
return constrain(intensity, 0, DRAW_MAX - 1);
}
void updateOrigin(int intensity) {
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;
if (!growing) {
if (fall_from_left) {
origin = origin_at_flip + ((intensity_max - intensity) / 2);
} else {
origin = origin_at_flip - ((intensity_max - intensity) / 2);
}
if (origin < 0) {
origin = DRAW_MAX - abs(origin);
} else if (origin > DRAW_MAX - 1) {
origin = origin - DRAW_MAX - 1;
}
}
}
void assignDrawValues(int intensity) {
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 (
(min_lit < max_lit && min_lit < i && i < max_lit)
|| (min_lit > max_lit && (i > min_lit || i < max_lit))
) {
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)]);
}
}
strip.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]);
}
strip.show();
}
void updateGlobals() {
uint16_t minLvl, maxLvl;
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;
if (++volCount >= SAMPLES) volCount = 0;
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];
}
if ((maxLvl - minLvl) < N_PIXELS) maxLvl = minLvl + N_PIXELS;
minLvlAvg = (minLvlAvg * 63 + minLvl) >> 6;
maxLvlAvg = (maxLvlAvg * 63 + maxLvl) >> 6;
}
void vu9() {
currentPalette = OceanColors_p;
currentBlending = LINEARBLEND;
EVERY_N_SECONDS(5) {
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);
}
EVERY_N_MILLIS_I(thistimer, 20) {
uint8_t timeval = beatsin8(10, 20, 50);
thistimer.setPeriod(timeval);
fadeToBlackBy(leds, N_PIXELS, 16);
sndwave();
soundble();
}
FastLED.setBrightness(max_bright);
FastLED.show();
}
void soundble() {
int tmp = analogRead(MIC_PIN) - 512 - DC_OFFSET;
sample = abs(tmp);
}
void sndwave() {
leds[N_PIXELS / 2] = ColorFromPalette(currentPalette, sample, sample * 2, currentBlending);
for (int i = N_PIXELS - 1; i > N_PIXELS / 2; i--) {
leds[i] = leds[i - 1];
}
for (int i = 0; i < N_PIXELS / 2; i++) {
leds[i] = leds[i + 1]; } addGlitter(sampleavg); } void vu10() {
EVERY_N_SECONDS(5) {
static uint8_t baseC = random8(); 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); } EVERY_N_MILLISECONDS(thisdelay) {
soundtun(); FastLED.setBrightness(max_bright); FastLED.show(); } } void soundtun() {
int n; n = analogRead(MIC_PIN); n = qsuba(abs(n - 512), 10); 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]; } } void vu11() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; peakcount = 0; } soundrip(); EVERY_N_MILLISECONDS(20) {
rippled(); } FastLED.show(); } void soundrip() {
newtime = millis(); int tmp = analogRead(MIC_PIN) - 512; sample = abs(tmp); int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60); samplesum = samplesum + sample - samplearray[samplecount]; sampleavg = samplesum / NSAMPLES; Serial.println(sampleavg); samplearray[samplecount] = sample; samplecount = (samplecount + 1) % NSAMPLES; if (newtime > (oldtime + 200)) digitalWrite(13, LOW);
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) {
step = -1;
peakcount++;
oldtime = newtime;
}
}
void rippled() {
fadeToBlackBy(leds, N_PIXELS, 64);
switch (step) {
case -1:
center = random(N_PIXELS);
colour = (peakspersec * 10) % 255;
step = 0;
break;
case 0:
leds[center] = CHSV(colour, 255, 255);
step ++;
break;
case maxsteps:
break;
default:
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
step ++;
break;
}
}
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); } } void setPixel(int Pixel, byte red, byte green, byte blue) {
strip.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(); } void vu12() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount; peakcount = 0; } soundripped(); EVERY_N_MILLISECONDS(20) {
rippvu(); } FastLED.show(); } void soundripped() {
newtime = millis(); int tmp = analogRead(MIC_PIN) - 512; sample = abs(tmp); int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60); samplesum = samplesum + sample - samplearray[samplecount]; sampleavg = samplesum / NSAMPLES; Serial.println(sampleavg); samplearray[samplecount] = sample; samplecount = (samplecount + 1) % NSAMPLES; if (newtime > (oldtime + 200)) digitalWrite(13, LOW); if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) {
step = -1;
peakcount++;
oldtime = newtime;
}
}
void rippvu() {
fadeToBlackBy(leds, N_PIXELS, 64);
switch (step) {
case -1:
center = random(N_PIXELS);
colour = (peakspersec * 10) % 255;
step = 0;
break;
case 0:
leds[center] = CHSV(colour, 255, 255);
step ++;
break;
case maxsteps:
break;
default:
leds[(center + step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
leds[(center - step + N_PIXELS) % N_PIXELS] += CHSV(colour, 255, myfade / step * 2);
step ++;
break;
}
addGlitter(sampleavg);
}
void vu13() {
EVERY_N_MILLISECONDS(1000) {
peakspersec = peakcount;
peakcount = 0;
}
soundripper();
EVERY_N_MILLISECONDS(20) {
jugglep();
}
FastLED.show();
}
void soundripper() {
newtime = millis();
int tmp = analogRead(MIC_PIN) - 512;
sample = abs(tmp);
int potin = map(analogRead(POT_PIN), 0, 1023, 0, 60);
samplesum = samplesum + sample - samplearray[samplecount];
sampleavg = samplesum / NSAMPLES;
Serial.println(sampleavg);
samplearray[samplecount] = sample;
samplecount = (samplecount + 1) % NSAMPLES;
if (newtime > (oldtime + 200)) digitalWrite(13, LOW);
if ((sample > (sampleavg + potin)) && (newtime > (oldtime + 60)) ) {
step = -1;
peakcount++;
oldtime = newtime;
jugglep();
}
}
void jugglep() {
static uint8_t thishue = 0;
timeval = 40;
leds[0] = ColorFromPalette(currentPalette, thishue++, sampleavg, LINEARBLEND);
for (int i = N_PIXELS - 1; i > 0 ; i-- ) leds[i] = leds[i - 1];
addGlitter(sampleavg / 2);
}
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) {
if ( random8() < chanceOfGlitter) {
leds[random16(N_PIXELS)] += CRGB::White;
}
}
typedef void (*SimplePatternList[])();
SimplePatternList qPatterns = {
vu, vu1, vu2, Vu3, Vu4, Vu5, Vu6, vu7, vu8, vu9, vu10, vu11, vu12, vu13};
uint8_t qCurrentPatternNumber = 0;
void nextPattern2()
{
qCurrentPatternNumber = (qCurrentPatternNumber + 1) % ARRAY_SIZE( qPatterns);
}
void All2()
{
qPatterns[qCurrentPatternNumber]();
EVERY_N_SECONDS( 30 ) {
nextPattern2();
}
}
Experimental scene

Experimental scene Dynamic graph

Video recording of the experiment (3 branch 37 second )
https://v.youku.com/v_show/id_XNTg4OTUzNzQ1Mg==.html?spm=a2hcb.playlsit.page.1
边栏推荐
- 12 brand management of commodity system in gulimall background management
- 子组件触发父组件自定义事件(defineEmits):子组件传值给父组件
- 一笔画问题(中国邮递员问题)
- postgresql官网下载出错
- Why do you want to make "secret comments"?
- pomerium
- Can I take your subdomain? Exploring Same-Site Attacks in the Modern Web
- Elementary notes of binary tree
- Use float to realize left, middle and right layout, and the middle content is adaptive
- PostgreSQL official website download error
猜你喜欢

基于C#开放式TCP通信建立与西门子PLC的socket通信示例

Kubelet CRI container runtime

如何面对科技性失业?

基于ASP.NET的某高校学院档案管理系统

解决方案丨5G技术助力搭建智慧园区

Emotion analysis model based on Bert

Today's sleep quality record 75 points

SLAM 02.整体框架

Food safety | what food can be heated in a microwave oven? You should know these potential safety hazards

华为年内二度招聘“天才少年”;540万Twitter账号信息泄露,卖价3万美元;谷歌解雇了相信AI有意识的工程师|极客头条...
随机推荐
C#把Type当做泛型T,来作为方法的泛型进行使用
Hcip day 11 comparison (BGP configuration and release)
StreamNative 团队文化:一家“透明”的公司
Flutter dart generates a list of random numbers that are not repeated in n intervals
1-6月中国ADAS供应商占比9% 又一家零部件巨头全面布局智驾新赛道
Mysql数据目录(3)---表数据结构myISAM(二十六)
[applet] why can't the onreachbottom event be triggered? (one second)
LeetCode 2119. 反转两次的数字
Kubernetes - Introduction to PV and PVC of advanced storage
HCIP第十一天比较(BGP的配置、发布)
MySQL可以自定义变参存储函数吗?
[typescript] typescript common types (Part 2)
【上位机教程】CANopen通信下一体化步进电机与台达PLC(AS228T)的应用
The child component triggers the defineemits of the parent component: the child component passes values to the parent component
[5gc] what is 5g slice? How does 5g slice work?
0基础编程资源大全(先收藏~慢慢看~)
Use grid to realize left, middle and right layout, and the middle content is adaptive
LeetCode 263.丑数
基于Bézier曲线的三维造型与渲染
The parent component accesses the methods or parameters of the child component (the child component exposes the method defineexpose)