资讯详情

【花雕动手做】有趣好玩的音乐可视化系列小项目(12)---米管快速节奏灯

偶然心血来潮,想做一系列声音可视化的话题。这个话题有点难,涉及面广,相关FFT和FHT算法也很复杂,但我仍然计划从最简单的开始,实际做实验,耐心尝试各种解决方案,逐渐积累一些有用的音乐频谱可视化数据,并努力形成一些实用和有趣的音乐可视器项目。

找到的报废灯管,准备用,做一米二的快节奏灯

在这里插入图片描述

两个头都锯掉了,把里面拿出来LED灯片

找到两个花盆底盘,当灯管座

采用多级扩孔钻头

灯管座位3秒扩孔288mm

合宙用于开发板CORE ESP32-C3

主要特色 (1)功能强,应用广泛 合宙ESP32-C3开发板高集成设计,板载设计 Wi-Fi/BLE天线、4MB Flash,支持UART、GPIO、SPI、I2C、ADC、PWM等接口,满足大多数应用;板载CH343P芯片实现更高的速率USB固件下载更快更稳定。 (2)材料充足,信号好 合宙ESP32-C4层开发板PCB,板载2.4G调试后,天线达到了较好的使用效果。.38到2.48GHz驻波比在范围内(VSWR)值较好,能有效地将发射功率辐射到无线空间。 (3)多元化发展更方便 合宙ESP32-C目前支持3开发板:LuatOS/乐鑫IDF/Arduino/MicroPython等多样化开发方式,使用更便捷。LuatOS在社区大神梦的努力下,固件支持以下功能,其他内容不断更新。

ESP32-C3核心板 IO引脚图

1路SPI FLASH,板载4MB,支持最高 16MB 2路UART接口,UART0~UART1.下载口为UART0 6 路 12 比特 ADC,最高采样率 100KSPS 1路低速SPI支持主模式的接口 1路IIC控制器 4路PWM接口 GPIO外管脚15路,可复用 2路贴片LED指示灯 1路复位按键 1路BOOT按键 1路USB转TTL下载调试口 2.4G PCB板载天线

使用声音模块MAX9814

MAX9814是一种自动增益控制的低成本高性能麦克风放大器(AGC)偏离低噪声麦克风。该装置具有低噪声前端放大器和可变增益放大器(VGA)、输出放大器、麦克风偏置电压发生器和AGC控制电路。 ●自动增益控制(AGC) ●三种增益设置(40)dB、50dB、60dB) ●可编程动作时间 ●可编程动作和释放时间比 ●电源电压范围2.7V~5.5V ●低THD:0.04% (典型值) ●低功耗关闭模式 ●内置2V低噪声麦克风偏置

彩灯使用WS2812B

其主要特点 智能反接保护,电源反接不会损坏IC。 IC控制电路与LED点光源公用一个电源。 控制电路与RGB芯片集成在5050包装元件中,形成完整的外部控制像素点。 内置信号整形电路,任何像素点收到信号后通过波形整形输出,确保线路波形畸变不会累积。 内置上电复位和下电复位电路。 每个像素点的三基色可显示256亮度,1677216种颜色的全真色可显示,扫描频率不低于400Hz/s。 串行级联接口可以通过信号线接收和解码数据。 当传输距离不超过5米时,不需要增加任何电路。 当刷新速率30帧/秒时,级联数不小于1024点。 数据发送速度可达8000Kbps。 光的颜色高度一致,性价比高。

主要应用领域 LED全彩发光字灯串,LED全彩模组, LED全彩软灯条硬灯条,LED护栏管。 LED点光源,LED像素屏,LED异形屏幕,各种电子产品,电气设备跑马灯。

WS2812B灯带选用每米60灯黑底裸板

WS2812模块电原理图

WS2812B集控制电路和发光电路于一体LED控制光源元件IC为WS2812B,发光元件是5050RGBLED,电压为5V,各单位峰值电流为60ma,灯带为三线制,VCC GND DIN分别为电源 、当使用外部电源时,外部电源-需要单片机GND相连。

把灯带放进灯管里(这里我剪了70颗灯珠)

灯管底座配重后采用大理石方案,零成本,性价比高

项目使用Arduino IDE烧录程序

开发板的详细配置如图所示

安装相关驱动库

有趣有趣的音乐可视化(12)–米管快节奏灯 相关程序:MegunoLink音乐反应式LED灯带 模块接线:WS2812B接D9 MAX9814 ESP32_C3 VCC 5V GND GND OUT D4(ADC4)

/* 有趣有趣的音乐可视化(12)-米管快节奏灯 相关程序:MegunoLink音乐反应式LED灯带 模块接线:WS2812B接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);
  }
}

实验场景图

实验场景图 动态图

https://img.mydigit.cn/forum/202207/24/155142ahnctgez2npccenr.gif

实验的视频记录(4分57秒)

https://v.youku.com/v_show/id_XNTg4ODE1MTAwOA==.html?spm=a2hcb.playlsit.page.1

实验场景图

实验场景图 动态图

https://img.mydigit.cn/forum/202207/25/092209rcucyzgrntvcz5cy.gif

实验的视频记录

https://v.youku.com/v_show/id_XNTg4ODE4NTY0MA==.html?spm=a2hcb.playlsit.page.1

实验的视频记录2

https://v.youku.com/v_show/id_XNTg4OTMxMTUyOA==.html?spm=a2hcb.playlsit.page.1

实验的视频记录3

https://v.youku.com/v_show/id_XNTg4OTMxMTk3Mg==.html?spm=a2hcb.playlsit.page.1

实验的视频记录4

https://v.youku.com/v_show/id_XNTg4OTMxMTcxMg==.html?spm=a2hcb.playlsit.page.5

【花雕动手做】有趣好玩音乐可视化(12)–米管快速节奏灯 相关程序之二:SoftwareSerial米管音乐频谱灯 模块接线:WS2812B接D6 MAX9814 UNO VCC 5V GND GND OUT A0

/* 【花雕动手做】有趣好玩音乐可视化(12)--米管快速节奏灯 相关程序之二:SoftwareSerial米管音乐频谱灯 模块接线:WS2812B接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();
        bre

标签: 集成电路true

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台