自己动手制作一个声控的闪电云吧!

这是一个这是一个DIY云灯,如果听到一个巨大的噪音,会像现实的闪电一样闪烁。

视频加载中...

纸灯

胶水

一个面包板

Arduino Uno.

USB线

手机充电器块(5v,2A最好使用,我使用的是5V,1A iPhone充电器)

用于arduino的声音传感器/麦克风模块.

Adafruit NeoPixel数字RGB LED灯带

枕头填充(棉花或者人造纤维如果您没有任何旧枕头,您可在某宝或手工艺店购买这些)

喷胶

(也可能需要焊枪和焊锡。)

  • 步骤1:焊接(可选)

如果NeoPixel线在电线上有一个特殊的连接器,那就没有必要在LED上焊接电线。但是,如果您没有连接器,您将需要进行一些焊接(老实说,我发现这比尝试找出哪个接地线,Din或+ 5V)更容易。另外,如果你像我一样,你可能需要将两股NeoPixel焊接在一起。只需确保将LED的Din侧焊接到LED的Dout侧(在我的股线上,股线上有小箭头显示信息的流动,所以只要所有箭头指向与您相同的方向好的。)

  • 步骤2:创建结构

打开所有的纸灯,然后将它们粘在一起,形成一个你认为像云的形状。然后将NeoPixel线缠绕在结构周围(我使用的线条有一个粘合剂回到他们身上,但如果你不这样做,你可以将大量的喷雾粘合剂应用到线的背面)。正如你所看到的那样,我水平地包裹了我,但是我建议以一种螺旋状的方式将它们包围,以使NeoPixels中包含所有方面(包括顶部和底部)。只要确保在顶部放一个开口,把面包板,arduino和麦克风放在灯笼里。

  • 步骤3:添加绒毛

使用喷胶,将枕头(或聚酯纤维填充物)粘在纸灯上。只需确保您可一找到NeoPixels的起始端(Din侧),以便您可以将其连接到其他组件。我建议在这些部分喷涂结构,而不是立即喷涂整个物体,并在干燥之前加紧填充纤维。不要太担心均匀地应用你的绒毛; 使用纤维填料越不平衡,云越看越亮。

  • 步骤4:接线

这是事情变得有点复杂的地方。我们从布线开始吧。做任何接线时,不要让Arduino连接电源。如果您弄错了了接线并连接电源,则可能会烧了LED,因此,当安装电线时,请始终与电源断开连接。就这样说。

绿色和红色的线是传输电力的,黑色电线是传输信息的。红线与布线的正面部分有关,所以任何时候都有Vin,5V或+,需要连接到面板板上的(+)列。绿色电线与负极或接地相关,所以任何时候都有一个GND端口或电线,它连接到面包板的( - )列。

在我的项目中,我将NeoPixels的Din部分连接到Arduino上的7个。您可以选择Arduino标签为“数字”一侧的任何编号端口,如果最终使用我为您提供的代码,请务必更改代码。

  • 步骤5:编码

如果不太了解编码(像我一样),并且使用了与我完全相同的资源(包括使用120个LED),并且完成了与我完全相同的接线,那么这个代码应该可以工作,而无需做任何调整

/*

Lighting Cloud Mood Lamp By James Bruce

View the full tutorial and build guide at http://www.makeuseof.com/

Sound sampling code originally by Adafruit Industries. Distributed under the BSD license.

This paragraph must be included in any redistribution.

*/

#include <Wire.h>

#include "FastLED.h"

// How many leds in your strip?

#define NUM_LEDS 120

#define DATA_PIN 7

// Mode enumeration - if you want to add additional party or colour modes, add them here; you'll need to map some IR codes to them later;

// and add the modes into the main switch loop

enum Mode { CLOUD,ACID,OFF,ON,RED,GREEN,BLUE,FADE};

Mode mode = CLOUD;

Mode lastMode = CLOUD;

// Mic settings, shouldn't need to adjust these.

#define MIC_PIN 0 // Microphone is attached to this analog pin

#define DC_OFFSET 0 // DC offset in mic signal - if unusure, leave 0

#define NOISE 10 // Noise/hum/interference in mic signal

#define SAMPLES 10 // Length of buffer for dynamic level adjustment

byte

volCount = 0; // Frame counter for storing past volume data

int

vol[SAMPLES]; // Collection of prior volume samples

int n, total = 30;

float average = 0;

// used to make basic mood lamp colour fading feature

int fade_h;

int fade_direction = 1;

// Define the array of leds

CRGB leds[NUM_LEDS];

void setup() {

// this line sets the LED strip type - refer fastLED documeantion for more details https://github.com/FastLED/FastLED

FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);

// starts the audio samples array at volume 15.

memset(vol, 15, sizeof(vol));

Serial.begin(115200);

Wire.begin(9); // Start I2C Bus as a Slave (Device Number 9)

Wire.onReceive(receiveEvent); // register event

}

void receiveEvent(int bytes) {

// Here, we set the mode based on the IR signal received. Check the debug log when you press a button on your remote, and

// add the hex code here (you need 0x prior to each command to indicate it's a hex value)

while(Wire.available())

{

unsigned int received = Wire.read();

Serial.print("Receiving IR hex: ");

Serial.println(received,HEX);

lastMode = mode;

switch(received){

case 0x3F:

mode = ON; break;

case 0xBF:

mode = OFF; break;

case 0x2F:

mode = CLOUD; break;

case 0xF:

mode = ACID; break;

case 0x37:

mode = FADE; break;

case 0x9F:

mode = BLUE; break;

case 0x5F:

mode = GREEN; break;

case 0xDF:

mode = RED; break;

}

}

}

void loop() {

// Maps mode names to code functions.

switch(mode){

case CLOUD: detect_thunder();reset();break;

case ACID: acid_cloud();reset();break;

case OFF:reset();break;

case ON: constant_lightning();reset();break;

case RED: single_colour(0);break;

case BLUE: single_colour(160);break;

case GREEN: single_colour(96);break;

case FADE: colour_fade();break;

default: colour_fade(); reset();break;

}

}

// Makes all the LEDs a single colour, see https://raw.githubusercontent.com/FastLED/FastLED/gh-pages/images/HSV-rainbow-with-desc.jpg for H values

void single_colour(int H){

for (int i=0;i<NUM_LEDS;i++){

leds[i] = CHSV( H, 255, 255);

}

//avoid flickr which occurs when FastLED.show() is called - only call if the colour changes

if(lastMode != mode){

FastLED.show();

lastMode = mode;

}

delay(50);

}

void colour_fade(){

//mood mood lamp that cycles through colours

for (int i=0;i<NUM_LEDS;i++){

leds[i] = CHSV( fade_h, 255, 255);

}

if(fade_h >254){

fade_direction = -1; //reverse once we get to 254

}

else if(fade_h < 0){

fade_direction = 1;

}

fade_h += fade_direction;

FastLED.show();

delay(100);

}

void detect_thunder() {

n = analogRead(MIC_PIN); // Raw reading from mic

n = abs(n - 512 - DC_OFFSET); // Center on zero

n = (n <= NOISE) ? 0 : (n - NOISE); // Remove noise/hum

vol[volCount] = n; // Save sample for dynamic leveling

if(++volCount >= SAMPLES) volCount = 0; // Advance/rollover sample counter

total = 0;

for(int i=0; i<SAMPLES; i++) {

total += vol[i];

}

// If you're having trouble getting the cloud to trigger, uncomment this block to output a ton of debug on current averages.

// Note that this WILL slow down the program and make it less sensitive due to lower sample rate.

for(int t=0; t<SAMPLES; t++) {

//initial data is zero. to avoid initial burst, we ignore zero and just add the current l

Serial.print("Sample item ");

Serial.print(t);

Serial.print(":");

Serial.println(vol[t]);

}

Serial.print("total");

Serial.println(total);

Serial.print("divided by sample size of ");

Serial.println(SAMPLES);

Serial.print("average:");

Serial.println(average);

Serial.print("current:");

Serial.println(n);

average = (total/SAMPLES)+2;

if(n>average){

Serial.println("TRIGGERED");

reset();

//I've programmed 3 types of lightning. Each cycle, we pick a random one.

switch(random(1,3)){

//switch(3){

case 1:

thunderburst();

delay(random(10,500));

Serial.println("Thunderburst");

break;

case 2:

rolling();

Serial.println("Rolling");

break;

case 3:

crack();

delay(random(50,250));

Serial.println("Crack");

break;

}

}

}

// utility function to turn all the lights off.

void reset(){

for (int i=0;i<NUM_LEDS;i++){

leds[i] = CHSV( 0, 0, 0);

}

FastLED.show();

}

void acid_cloud(){

// a modification of the rolling lightning which adds random colour. trippy.

//iterate through every LED

for(int i=0;i<NUM_LEDS;i++){

if(random(0,100)>90){

leds[i] = CHSV( random(0,255), 255, 255);

}

else{

leds[i] = CHSV(0,0,0);

}

}

FastLED.show();

delay(random(5,100));

reset();

//}

}

void rolling(){

// a simple method where we go through every LED with 1/10 chance

// of being turned on, up to 10 times, with a random delay wbetween each time

for(int r=0;r<random(2,10);r++){

//iterate through every LED

for(int i=0;i<NUM_LEDS;i++){

if(random(0,100)>90){

leds[i] = CHSV( 0, 0, 255);

}

else{

//dont need reset as we're blacking out other LEDs her

leds[i] = CHSV(0,0,0);

}

}

FastLED.show();

delay(random(5,100));

reset();

}

}

void crack(){

//turn everything white briefly

for(int i=0;i<NUM_LEDS;i++) {

leds[i] = CHSV( 0, 0, 255);

}

FastLED.show();

delay(random(10,100));

reset();

}

void thunderburst(){

// this thunder works by lighting two random lengths

// of the strand from 10-20 pixels.

int rs1 = random(0,NUM_LEDS/2);

int rl1 = random(10,20);

int rs2 = random(rs1+rl1,NUM_LEDS);

int rl2 = random(10,20);

//repeat this chosen strands a few times, adds a bit of realism

for(int r = 0;r<random(3,6);r++){

for(int i=0;i< rl1; i++){

leds[i+rs1] = CHSV( 0, 0, 255);

}

if(rs2+rl2 < NUM_LEDS){

for(int i=0;i< rl2; i++){

leds[i+rs2] = CHSV( 0, 0, 255);

}

}

FastLED.show();

//stay illuminated for a set time

delay(random(10,50));

reset();

delay(random(10,50));

}

}

// basically just a debug mode to show off the lightning in all its glory, no sound reactivity.

void constant_lightning(){

switch(random(1,10)){

case 1:

thunderburst();

delay(random(10,500));

Serial.println("Thunderburst");

break;

case 2:

rolling();

Serial.println("Rolling");

break;

case 3:

crack();

delay(random(50,250));

Serial.println("Crack");

break;

}

}

步骤6:调整声音灵敏度



用螺丝刀调整声音传感器上的蓝色部分

将云连接到电源,并调整声音传感器的灵敏度。请参阅声音传感器图像上的注释。这个步骤在播放所需音量的雷暴记录并使云距离扬声器所需的距离时最容易。我建议当您发现声音传感器位于云端之外的完美灵敏度时,您应该使其更加敏感,因为它将被纤维填充物包围,从而可以消除到达麦克风的声音的强度。

  • 步骤7:最后步骤

将Arduino连接起来,把它放在灯笼里面。然后用鱼线连接到纸灯的金属条上,以便挂起。(我建议把钓鱼线和所有的灯笼挂在一起,而不只是中心,以减少灯笼在吊挂时分离的可能性;换句话说,把云的重量均匀地分布到其所有部位。 )

你有它!你自己的声控闪电云灯!享受自己的模拟风暴坠入睡眠:)

举报
评论 0