0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于Arduino DIY音頻反應臺燈

pecron ? 來源:電路一點通 ? 2023-04-17 09:10 ? 次閱讀
這是個會使你驚訝其妙的 RGB LED 臺燈。它將對周圍的聲音和音樂做出反應,并將像可視化器一樣播放。
在這個項目構建中,我們將使用簡單的組件和一些基本的Arduino編程來制作一個與所有聲音和音樂共舞的漂亮燈。站在桌子上玩游戲、播放音樂和其他任何真正能發(fā)出聲音的東西時,它都會產生令人驚嘆的效果。讓我們開始吧!
第 1 步:主要用品首先要做的事情是:規(guī)劃我們需要什么樣的用品,它們的成本是多少?它們在很大程度上是可選的,并且可以通過所需功能進行變動。但雖然如此,還是有一些關鍵的東西是必需的:
  • Arduino Nano(或任何同樣小的 Arduino 類型)
  • 聲音檢測模塊(RM 5.90 購買鏈接)
  • 5伏電源(或12伏降壓模塊)
  • 每個可單獨尋址的 LED 燈條 60 個 LED
根據您想要的外觀,您可能希望以不同的方式排列條帶或以其他方式漫射光。這是你可以發(fā)揮創(chuàng)造力的地方。如果您喜歡我的方法,我使用了以下項目:
  • 最高的宜家 Droppar 罐
  • 一小段PVC管。
  • 泡沫板
  • 熱膠槍
第 2 步:為組件供電為組件供電將是一種直接的方法。我只是使用 Arduino Nano 的 USB 線直接插入電腦。如果您使用 ACDC 電源等外部電源,您將需要一個降壓模塊來幫助您減少流向電路的電流量。否則,如果您不使用它,您可能很有可能會燒毀 Arduino,包括連接的組件。

該部分的核心是聲音檢測器模塊。這將為 Arduino 提供模擬信號,我們可以用它巧妙地點亮 RGB 燈。為了能夠做到這一點,我們需要為這兩個設備供電。(關注公眾號 電路一點通)幸運的是,它們都需要 5 伏輸入。我正在使用降壓模塊從 12 伏降到 5 伏,但直接使用 5 伏電源會更容易。將 Arduino 和聲音檢測器板上的 VIN 連接到正極輸入。然后將 Arduino 上的 GND 和檢測器連接到負極。我們還需要將 LED 燈條上的正負輸入連接到電源。
第 3 步:檢測器和條帶

將所有三個部分連接到電源后,我們需要將它們相互連接。聲音檢測器模塊將通過模擬輸入引腳與 Arduino 通信。在這種情況下,我將使用 0 號引腳。
LED 燈條需要一個數(shù)字脈沖才能了解我們要處理的 LED。因此,我們需要將數(shù)字輸出引腳連接到 Arduino nano。我將使用 6 號引腳。
在選擇區(qū)域使用收縮管,這樣電纜以后就不會在狹窄的空間內相互碰撞。太棒了,現(xiàn)在我們大部分都完成了電子設備!
第 4 步:上傳代碼這個構建中最重要的部分可以說是代碼。它可以將這個構建從非??嶙?yōu)榉浅0簟V饕硎菍⑽覀儚?a href="http://ttokpm.com/v/tag/117/" target="_blank">傳感器獲得的模擬值映射到要顯示的 LED 數(shù)量。
第 5 步:準備外殼

一開始我以為蓋子是亞克力做的,后來我買了罐子,發(fā)現(xiàn)它不是亞克力而是玻璃。所以我需要重新調整我的計劃,制作一個易于戳和安裝 Arduino 和 LED 的蓋子。所以我選擇了泡沫板。
第一步,我需要切割泡沫板,使其完全呈圓形,并且與罐子的玻璃蓋具有相同的直徑。我沒有合適的測量直徑工具,所以我使用濕記號筆即興創(chuàng)作了該方法,并標記了玻璃的直徑并將其印在一張紙上。之后,我將紙粘貼到泡沫板上,但沿著紙上圓圈的邊緣粘貼到板上。它并不完美,但應該足以容納所有 Arduino 和 LED 組件。
第二步,我需要打破罐蓋上的玻璃。警告!請用厚塑料袋蓋住罐子,以防止玻璃散落在房間周圍,并在空曠的地方進行。了解您的周圍環(huán)境。打碎玻璃后,請確保所有粘在罐蓋側面裂縫處的玻璃都被清除。這是為了防止您或其他人因將它們自己切割到卡住的玻璃上而受傷。
第三步,將圓形泡沫板放在罐蓋的中心。確保泡沫是緊的,不要太松,它們正好適合罐子。

第四步,我才意識到我需要改變這個項目的布局。我想讓用戶在出現(xiàn)故障時可以輕松訪問 Arduino 組件。所以,我決定使用迷你面包板并將其放在蓋子的中心。不僅如此,我還為聲音模塊上的電纜剪了兩個孔,我將把它們放在罐蓋的底部,進入罐子和面包板上,還有一個孔讓 Arduino 與 USB 電纜連接以發(fā)揮作用作為電路的電源。

第五步,我用膠帶標記pvc管并在膠帶的中心畫線。然后,我把它貼在 pvc 管上。標記是我均勻切割 pvc 管并嘗試干凈切割的指標。
在測量了我需要使用的 pvc 長度后,我按照我提供的標記仔細切割它。pvc 管的長度取決于您的罐子高度。你可以使用任何你想要的長度。

第六步,我將用 LED 燈條切割的 PVC 管翹曲,使其略微傾斜并螺旋到 PVC 的頂部。我確保為多余的電纜長度創(chuàng)建一個小孔,以便將其隱藏在 PVC 罐內以進行電纜管理。然后我需要找到一種方法將 PVC 放在面包板上。使用熱膠槍或雙面膠帶,我可以將 PVC 管粘在額外的泡沫板上,然后將其粘貼到面包板上未使用的區(qū)域。在這一步中,我能夠將一些組件連接到面包板。面包板的左側區(qū)域為正極,面包板的右側區(qū)域為負極。

第七步,我把聲音模塊放在罐蓋的外面。這樣做是為了便于模塊稍后在 jar 外拾取聲音。放置模塊后,將其與電纜連接并按照給出的示意圖進行匹配。然后,將所有電纜與傳感器和 Arduino 連接到面包板。Arduino 是垂直安裝的,因此用于為電路供電的電纜將能夠通過泡沫板輕松地與 Arduino 板連接。

到此,這個項目就完成了。我花了一段時間加上嘗試和錯誤,但最終我依舊設法完成了它。

Coding For the Arduino:

#include

/** BASIC CONFIGURATION **/

//The amount of LEDs in the setup
#define NUM_LEDS 60
//The pin that controls the LEDs
#define LED_PIN 6
//The pin that we read sensor values form
#define ANALOG_READ 0

//Confirmed microphone low value, and max value
#define MIC_LOW 0.0
#define MIC_HIGH 200.0
/** Other macros */
//How many previous sensor values effects the operating average?
#define AVGLEN 5
//How many previous sensor values decides if we are on a peak/HIGH (e.g. in a song)
#define LONG_SECTOR 20

//Mneumonics
#define HIGH 3
#define NORMAL 2

//How long do we keep the "current average" sound, before restarting the measuring
#define MSECS 30 * 1000
#define CYCLES MSECS / DELAY

/*Sometimes readings are wrong or strange. How much is a reading allowed
to deviate from the average to not be discarded? **/
#define DEV_THRESH 0.8

//Arduino loop delay
#define DELAY 1

float fscale( float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve);
void insert(int val, int *avgs, int len);
int compute_average(int *avgs, int len);
void visualize_music();

//How many LEDs to we display
int curshow = NUM_LEDS;

/*Not really used yet. Thought to be able to switch between sound reactive
mode, and general gradient pulsing/static color*/
int mode = 0;

//Showing different colors based on the mode.
int songmode = NORMAL;

//Average sound measurement the last CYCLES
unsigned long song_avg;

//The amount of iterations since the song_avg was reset
int iter = 0;

//The speed the LEDs fade to black if not relit
float fade_scale = 1.2;

//Led array
CRGB leds[NUM_LEDS];

/*Short sound avg used to "normalize" the input values.
We use the short average instead of using the sensor input directly */
int avgs[AVGLEN] = {-1};

//Longer sound avg
int long_avg[LONG_SECTOR] = {-1};

//Keeping track how often, and how long times we hit a certain mode
struct time_keeping {
unsigned long times_start;
short times;
};

//How much to increment or decrement each color every cycle
struct color {
int r;
int g;
int b;
};

struct time_keeping high;
struct color Color;

void setup() {
Serial.begin(9600);
//Set all lights to make sure all are working as expected
FastLED.addLeds(leds, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++)?
leds[i] = CRGB(0, 0, 255);
FastLED.show();
delay(1000);

//bootstrap average with some low values
for (int i = 0; i < AVGLEN; i++) { ?
insert(250, avgs, AVGLEN);
}

//Initial values
high.times = 0;
high.times_start = millis();
Color.r = 0;
Color.g = 0;
Color.b = 1;
}

/*With this we can change the mode if we want to implement a general
lamp feature, with for instance general pulsing. Maybe if the
sound is low for a while? */
void loop() {
switch(mode) {
case 0:
visualize_music();
break;
default:
break;
}
delay(DELAY); // delay in between reads for stability
}

/**Funtion to check if the lamp should either enter a HIGH mode,
or revert to NORMAL if already in HIGH. If the sensors report values
that are higher than 1.1 times the average values, and this has happened
more than 30 times the last few milliseconds, it will enter HIGH mode.
TODO: Not very well written, remove hardcoded values, and make it more
reusable and configurable. */
void check_high(int avg) {
if (avg > (song_avg/iter * 1.1)) {
if (high.times != 0) {
if (millis() - high.times_start > 200.0) {
high.times = 0;
songmode = NORMAL;
} else {
high.times_start = millis();
high.times++;
}
} else {
high.times++;
high.times_start = millis();

}
}
if (high.times > 30 && millis() - high.times_start < 50.0)
songmode = HIGH;
else if (millis() - high.times_start > 200) {
high.times = 0;
songmode = NORMAL;
}
}

//Main function for visualizing the sounds in the lamp
void visualize_music() {
int sensor_value, mapped, avg, longavg;

//Actual sensor value
sensor_value = analogRead(ANALOG_READ);

//If 0, discard immediately. Probably not right and save CPU.
if (sensor_value == 0)
return;

//Discard readings that deviates too much from the past avg.
mapped = (float)fscale(MIC_LOW, MIC_HIGH, MIC_LOW, (float)MIC_HIGH, (float)sensor_value, 2.0);
avg = compute_average(avgs, AVGLEN);

if (((avg - mapped) > avg*DEV_THRESH)) //|| ((avg - mapped) < -avg*DEV_THRESH))
return;

//Insert new avg. values
insert(mapped, avgs, AVGLEN);
insert(avg, long_avg, LONG_SECTOR);

//Compute the "song average" sensor value
song_avg += avg;
iter++;
if (iter > CYCLES) {
song_avg = song_avg / iter;
iter = 1;
}

longavg = compute_average(long_avg, LONG_SECTOR);

//Check if we enter HIGH mode
check_high(longavg);

if (songmode == HIGH) {
fade_scale = 3;
Color.r = 5;
Color.g = 3;
Color.b = -1;
}
else if (songmode == NORMAL) {
fade_scale = 2;
Color.r = -1;
Color.b = 2;
Color.g = 1;
}

//Decides how many of the LEDs will be lit
curshow = fscale(MIC_LOW, MIC_HIGH, 0.0, (float)NUM_LEDS, (float)avg, -1);

/*Set the different leds. Control for too high and too low values.
Fun thing to try: Dont account for overflow in one direction,
some interesting light effects appear! */
for (int i = 0; i < NUM_LEDS; i++)?
//The leds we want to show
if (i < curshow) {
if (leds[i].r + Color.r > 255)
leds[i].r = 255;
else if (leds[i].r + Color.r < 0)
leds[i].r = 0;
else
leds[i].r = leds[i].r + Color.r;

if (leds[i].g + Color.g > 255)
leds[i].g = 255;
else if (leds[i].g + Color.g < 0)
leds[i].g = 0;
else
leds[i].g = leds[i].g + Color.g;

if (leds[i].b + Color.b > 255)
leds[i].b = 255;
else if (leds[i].b + Color.b < 0)
leds[i].b = 0;
else
leds[i].b = leds[i].b + Color.b;

//All the other LEDs begin their fading journey to eventual total darkness
} else {
leds[i] = CRGB(leds[i].r/fade_scale, leds[i].g/fade_scale, leds[i].b/fade_scale);
}
FastLED.show();
}
//Compute average of a int array, given the starting pointer and the length
int compute_average(int *avgs, int len) {
int sum = 0;
for (int i = 0; i < len; i++)
sum += avgs[i];

return (int)(sum / len);

}

//Insert a value into an array, and shift it down removing
//the first value if array already full
void insert(int val, int *avgs, int len) {
for (int i = 0; i < len; i++) {
if (avgs[i] == -1) {
avgs[i] = val;
return;
}
}

for (int i = 1; i < len; i++) {
avgs[i - 1] = avgs[i];
}
avgs[len - 1] = val;
}

//Function imported from the arduino website.
//Basically map, but with a curve on the scale (can be non-uniform).
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;
}

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • led
    led
    +關注

    關注

    240

    文章

    23062

    瀏覽量

    657060
  • 檢測器
    +關注

    關注

    1

    文章

    857

    瀏覽量

    47623
  • 音頻
    +關注

    關注

    29

    文章

    2830

    瀏覽量

    81257
  • RGB
    RGB
    +關注

    關注

    4

    文章

    796

    瀏覽量

    58336
  • Arduino
    +關注

    關注

    187

    文章

    6457

    瀏覽量

    186502

原文標題:DIY音頻反應臺燈(Arduino 代碼)

文章出處:【微信號:電路一點通,微信公眾號:電路一點通】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    構建一個音頻反應臺燈

    這是個會使你驚訝其妙的 RGB LED 臺燈。它將對周圍的聲音和音樂做出反應,并將像可視化器一樣播放。
    發(fā)表于 09-19 15:29 ?984次閱讀
    構建一個<b class='flag-5'>音頻</b><b class='flag-5'>反應</b><b class='flag-5'>臺燈</b>

    基于AB32的遙控臺燈DIY過程記錄

    1、基于AB32的遙控臺燈DIY  項目描述:  通過手機藍牙方式遙控開發(fā)板控制臺燈的開關及調節(jié)亮度,用PWM控制MOS管控制流過臺燈的電流來控制亮度,HC-05串口模塊與開發(fā)板串口通
    發(fā)表于 10-19 12:00

    用易拉罐環(huán)DIY制作臺燈

    一款易拉環(huán)DIY的漂亮臺燈,雖然取材很另類,但是做出來的效果還真有不少時尚氣息呢!
    發(fā)表于 12-08 10:45 ?9074次閱讀

    DIY Arduino巨型Pcb

    電子發(fā)燒友網站提供《DIY Arduino巨型Pcb.zip》資料免費下載
    發(fā)表于 07-04 11:54 ?11次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b>巨型Pcb

    DIY自己的arduino項目

    電子發(fā)燒友網站提供《DIY自己的arduino項目.zip》資料免費下載
    發(fā)表于 07-27 10:17 ?2次下載
    <b class='flag-5'>DIY</b>自己的<b class='flag-5'>arduino</b>項目

    DIY簡單的Arduino鍵盤

    電子發(fā)燒友網站提供《DIY簡單的Arduino鍵盤.zip》資料免費下載
    發(fā)表于 08-10 11:11 ?4次下載
    <b class='flag-5'>DIY</b>簡單的<b class='flag-5'>Arduino</b>鍵盤

    DIY ARDUINO UNO板

    電子發(fā)燒友網站提供《DIY ARDUINO UNO板.zip》資料免費下載
    發(fā)表于 08-19 09:28 ?7次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>ARDUINO</b> UNO板

    Diy Lillypad Arduino

    電子發(fā)燒友網站提供《Diy Lillypad Arduino.zip》資料免費下載
    發(fā)表于 08-22 16:30 ?25次下載
    <b class='flag-5'>Diy</b> Lillypad <b class='flag-5'>Arduino</b>

    DIY Arduino Nano

    電子發(fā)燒友網站提供《DIY Arduino Nano.zip》資料免費下載
    發(fā)表于 08-22 16:29 ?68次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b> Nano

    DIY Arduino樂器

    電子發(fā)燒友網站提供《DIY Arduino樂器.zip》資料免費下載
    發(fā)表于 11-02 10:44 ?1次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b>樂器

    DIY Arduino角燈

    電子發(fā)燒友網站提供《DIY Arduino角燈.zip》資料免費下載
    發(fā)表于 11-02 10:46 ?1次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b>角燈

    DIY Arduino示波器

    電子發(fā)燒友網站提供《DIY Arduino示波器.zip》資料免費下載
    發(fā)表于 11-11 11:06 ?5次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b>示波器

    基于Arduino平臺的DIY示波器

    電子發(fā)燒友網站提供《基于Arduino平臺的DIY示波器.zip》資料免費下載
    發(fā)表于 11-30 14:23 ?6次下載
    基于<b class='flag-5'>Arduino</b>平臺的<b class='flag-5'>DIY</b>示波器

    Arduino DIY鬧鐘

    電子發(fā)燒友網站提供《Arduino DIY鬧鐘.zip》資料免費下載
    發(fā)表于 12-01 09:23 ?0次下載
    <b class='flag-5'>Arduino</b> <b class='flag-5'>DIY</b>鬧鐘

    DIY Arduino電子沙漏

    電子發(fā)燒友網站提供《DIY Arduino電子沙漏.zip》資料免費下載
    發(fā)表于 02-06 11:09 ?10次下載
    <b class='flag-5'>DIY</b> <b class='flag-5'>Arduino</b>電子沙漏