# LED(WS2812B)+Sound Senser V
###### tags:`專題實作`
## models
### Step 1:呼吸燈
```cpp=
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 4
#define NUMPIXELS 30 // Popular NeoPixel ring size
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
// NEO_KHZ800 800 KHz 比特流
// NEO_KHZ400 400 KHz 使用於“v1”(不是 v2)FLORA 像素,WS2811 驅動程序
// NEO_GRB 像素為 GRB 比特流連接
// NEO_RGB 像素連接到 RGB 比特流(v1 FLORA 像素,不是 v2)
// NEO_RGBW 像素連接到 RGBW 比特流
#define DELAYVAL 500 // 在像素之間暫停的時間(以毫秒為單位)
void NeoFade(int FadeSpeed)
{
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, 165, 242, 243);//設置像素顏色RGB
}
for (int j = 230; j > 0; j = j - 2) {
pixels.setBrightness(j);//設置亮度
pixels.show();
delay(FadeSpeed);
}
}
void setup() {
pixels.begin();
}
void loop() {
NeoFade(100);
}
```
### Step 2:七彩漸變色
```cpp=
#include <Adafruit_NeoPixel.h>
#define PIN 4
#define LED_NUM 30//LED燈數
Adafruit_NeoPixel ledtape = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
ledtape.begin();//初始化函數
ledtape.show(); //進行輸出,否則無現象
}
void loop() {
uint16_t i, j;
for(j=0; j <256; j++) {
for(i=0; i < ledtape.numPixels(); i++) {//累加燈的數量
ledtape.setPixelColor(i, rotateColor((((i) * 256 / ledtape.numPixels()) + j) & 255));//設置像素顏色RGB
}
ledtape.show();
delay(20);
}
}
uint32_t rotateColor(byte WheelPos) {//數值範圍0 ~ 255 (ASCII碼)
if(WheelPos < 85) {
return ledtape.Color(WheelPos * 3, 255 - WheelPos * 3, 0);//乘的倍數>3(各顏色的長度較長)、乘的倍數<3(各顏色的長度較短)以上狀況皆可看出明顯色差
} else if(WheelPos < 170) {
WheelPos -= 85;//ex C -= A , C = C - A
return ledtape.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return ledtape.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
```
### Step 3:進階版
:::info
:bulb: **解題思路:**
:::
```cpp=
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define PIN 4
#define LED_NUM 30//LED燈數
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(LED_NUM, PIN, NEO_GRB + NEO_KHZ800);
int FadeSpeed = 50; //燈滅時間
uint16_t addlightnum, addcolor;
void setup() {
pixels.begin();
pixels.show(); //進行輸出,否則無現象
}
uint32_t rotateColor(byte WheelPos) {//數值範圍0 ~ 255 (ASCII碼)
if (WheelPos < 85) {
return pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);//乘的倍數>3(各顏色的長度較長)、乘的倍數<3(各顏色的長度較短)以上狀況皆可看出明顯色差
} else if (WheelPos < 170) {
WheelPos -= 85;//ex C -= A , C = C - A
return pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
void loop() {
for (addlightnum = 0; addlightnum < 256; addlightnum++) {//累加燈的數量
for (addcolor = 0; addcolor < pixels.numPixels(); addcolor++) { //累加顏色
pixels.setPixelColor(addcolor, rotateColor((((addcolor) * 256 / pixels.numPixels()) + addlightnum) & 255));//設置像素顏色RGB
for (int light = 230; light > 0; light = light - 2) {
pixels.setBrightness(light);//設置亮度
pixels.show();
delay(FadeSpeed);
}
}
}
}
```
```cpp=
#include<FastLED.h>
#include<MegunoLink.h>
#include<Filter.h>
// 定義必要的參數
#define N_PIXELS 30//LED數量
#define MIC_PIN 15//音頻接口
#define LED_PIN 4 //LED接口
// the following parameters can be tweaked according to your audio levels
#define NOISE 350//降噪(越高降噪功能越明顯)
#define TOP (N_PIXELS+2) // allow the max level to be slightly off scale
#define LED_TYPE WS2812
#define BRIGHTNESS 25
#define COLOR_ORDER GRB
// 聲明 LED 陣列
CRGB leds[N_PIXELS];
// 定義音頻電平所需的變量
int lvl = 0, minLvl = 0, maxLvl = 250; //律動效果的敏感度(依照傳感器的敏感度高低做調整;ex高敏感度可調高)
// instantiate the filter class for smoothing the raw audio signal
ExponentialFilter<long> ADCFilter(5, 0);
void setup() {
Serial.begin(115200);
// 初始化 LED object
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);//模擬讀取
// remove the MX9614 bias of 1.25VDC
n = abs(1023 - n);
// hard limit noise/hum
n = (n <= NOISE) ? 0 : abs(n - NOISE);//降噪
// apply the exponential filter to smooth the raw signal
ADCFilter.Filter(n);
lvl = ADCFilter.Current();
// // plot the raw versus filtered signals
// Serial.print(n);
// Serial.print(" ");
// Serial.println(lvl);
// calculate the number of pixels as a percentage of the range
// TO-DO: can be done dynamically by using a running average of min/max audio levels
height = TOP * (lvl - minLvl) / (long)(maxLvl - minLvl);
if (height < 0L) height = 0;
else if (height > TOP) height = TOP;
// turn the LEDs corresponding to the level on/off
for (uint8_t i = 0; i < N_PIXELS; i++) {
// turn off LEDs above the current level
if (i >= height) leds[i] = CRGB(0, 0, 0);
else leds[i] = Wheel( map( i, 0, N_PIXELS - 3, 30, 150 ) );//使用map函數設定i數值(1.原始值最低值2.原始值最高值3.轉換最低值4.轉換最高值)
}
FastLED.show();
}
CRGB Wheel(byte WheelPos) {
// 根據 0 到 255 之間的輸入值返回顏色值
if (WheelPos < 85)
return CRGB(WheelPos * 4, 255 - WheelPos * 4, 0);
else if (WheelPos < 170) {
WheelPos -= 85;
return CRGB(255 - WheelPos * 4, 0, WheelPos * 4);
} else {
WheelPos -= 170;
return CRGB(0, WheelPos * 4, 255 - WheelPos * 4);
}
}
```
- LED參考資料
[Adafruit_NeoPixel常用庫函數詳解]
https://tw511.com/a/01/10825.html
[Adafruit NeoPixel Library]
https://adafruit.github.io/Adafruit_NeoPixel/html/class_adafruit___neo_pixel.html
[顏色變化]
https://processing.org/examples/lineargradient.html
[fastLED库函数介绍]
https://blog.csdn.net/acktomas/article/details/114634985
[Ai_Demos_ESP32]
https://github.com/acrobotic/Ai_Demos_ESP32
-