当前位置:网站首页>[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
边栏推荐
- Flutter dart generates a list of random numbers that are not repeated in n intervals
- Kubernetes APIServer 限流策略
- mqtt send receive
- Use positioning to realize left, middle and right layout, and the middle content is adaptive
- key&key_ Len & ref & filtered (4) - MySQL execution plan (50)
- Qualcomm once again "bet" on Zhongke Chuangda to challenge the full stack solution of intelligent driving software and hardware
- RMII, smii, gmii, rgmii interfaces of Ethernet Driver
- V01 - XX, record a good life from the log
- Flutter prevents scientific counting and removes mantissa invalid 0
- 12 brand management of commodity system in gulimall background management
猜你喜欢

V00 - do whatever you want when you are old
![[upper computer tutorial] Application of integrated stepping motor and Delta PLC (as228t) under CANopen communication](/img/d4/c677de31f73a0e0a4b8b10b91e984a.png)
[upper computer tutorial] Application of integrated stepping motor and Delta PLC (as228t) under CANopen communication

基于BERT的情感分析模型

Hcip day 12 notes sorting (BGP Federation, routing rules)
![[flower carving hands-on] interesting and fun music visualization series small project (13) -- organic rod column lamp](/img/d4/7b9c7c99d46661e1be2963a342dd18.jpg)
[flower carving hands-on] interesting and fun music visualization series small project (13) -- organic rod column lamp

C regards type as generic type T and uses it as generic type of method

Learn about Pinia state getters actions plugins

1312_适用7z命令进行压缩与解压

Chat system based on webrtc and websocket

Emotion analysis model based on Bert
随机推荐
Slam 02. overall framework
The parent component accesses the methods or parameters of the child component (the child component exposes the method defineexpose)
A college archives management system based on asp.net
12 brand management of commodity system in gulimall background management
基于C#开放式TCP通信建立与西门子PLC的socket通信示例
Flutter dart generates a list of random numbers that are not repeated in n intervals
Qualcomm once again "bet" on Zhongke Chuangda to challenge the full stack solution of intelligent driving software and hardware
Leetcode 1523. count odd numbers within the interval
维度灾难 维数灾难 暂记
Version of NDK matched the requested version 21.0.6113669. versions available locally: 2
Food safety | what food can be heated in a microwave oven? You should know these potential safety hazards
Redis realizes single sign on -- system framework construction (I)
Use grid to realize left, middle and right layout, and the middle content is adaptive
Kubernetes---- installing and deploying NFS servers
Flutter prevents scientific counting and removes mantissa invalid 0
pomerium
Kubelet CRI container runtime
Leetcode 263. ugly number
【5G】5G中的CU和DU是什么?
Remote IP debugger (Practical dry goods)