
开源协议
:Public Domain
(未经作者授权,禁止转载)描述
首先这是一个律动灯,其次他能电人!!!
灯板部分采用WS2812B
关于电容问题说明一下,并不是每个灯珠都需要加电容,我一颗都没加,并没有出问题,手焊毕竟贴片元件挺累的,64个灯珠已经很累了是吧,不出问题就可以省点事,出现问题咱再加也可以
控制板使用立创推出的ESP32R8N8
拾音电路采用max9814方案
当然焊接困难的小伙伴可以采用模块接口
通过选择跳线来决定使用模块还是板载焊接,选择权交给你,可以使用MX9814(稍微有点贵),max4464(中等价格),某宝基于lm393的mic模块(最便宜)。看钱包巨鼎模块,反正接口都留好了
使用模块注意供电别反接
使用模块注意供电别反接
使用模块注意供电别反接
重要的事说三遍
因为是愚乐主题,整人是少不了的
电击模块
万能芯片NE555,产生脉冲 ,推动三极管,进而推动三脚电感(自耦升压),拨动开关与背板之间产生一个高压(放心,不致命,小时候的电人口香糖都玩过吧,原理是一样的),因为这个产生高压,担心损害其他模块(主要是开发板,作为一个待女子爱好者,是很爱护开发板的),所以独立供电(建议6V以上12V以下)
H5 与 拨动开关,电池形成回路
H3 连接拨动快关的拨动金属和背板
H4 可选直插式的三脚电感(因为EDA没有直插三脚电感的封装)
示波器衰减10倍后测到的电击波形
放心,电流很小,这是安全的
代码如下
/*
本项目应用于LC-ESP32R8N8开发板
修改IO口可以应用于其他ESP32开发板
以及 Arduino 开发板
学习自GitHub:https://github.com/Fudan-EGA/LEDSpectrum/tree/master
*/
#include //为程序提供计时功能 请安装1.6.1
#include //控制WS2812, LPD8806等led的Arduino第三方库 请安装3.5.0
#include "arduinoFFT.h" //傅里叶变换的开源库 请安装1.6.2
arduinoFFT FFT = arduinoFFT(); //创建FFT对象
const uint16_t samples = 64; //采样点数
const double samplingFrequency = 8000; // 声音采样频率
unsigned int sampling_period_us;
unsigned long microseconds;
double vReal[samples]; //FFT采样输入样本数组
double vImag[samples]; //FFT运算输出数组
//FFT默认参数
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02
#define SCL_PLOT 0x03
//接口与灯板
#define CHANNEL 4 //音频输入IO口序号为4
#define LED_PIN 1 //灯板输入IO口选择
#define LED_NUM 64 //灯珠数量
#define BRIGHTNESS 10 //默认背光亮度
#define LED_TYPE WS2812 //灯珠类型
#define COLOR_ORDER GRB //色彩顺序
CRGB leds[LED_NUM]; //定义LED对象
void setup() {
sampling_period_us = round(1000000 * (1.0 / samplingFrequency)); //计算采样频率
pinMode(CHANNEL, INPUT); //初始化麦克风接口为输入模式,表示读取麦克风数据
FastLED.addLeds(leds, LED_NUM); //初始化LED灯带
FastLED.setBrightness(BRIGHTNESS); //LED亮度设置,取值范围为0-255
}
void loop() {
static uint32_t t = 0, dt = 5;
static uint8_t flag = 0;
/*采样*/
microseconds = micros();
for (int i = 0; i < samples; i++) {
vReal[i] = analogRead(CHANNEL); //读取模拟值,信号采样
vImag[i] = 0;
while (micros() - microseconds < sampling_period_us) {
//empty loop
}
microseconds += sampling_period_us;
}
//傅里叶变换
FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
fill_rainbow((leds), 64 /*数量*/, 0 /*开始色值*/, 4 /*递增值*/); //设置彩虹渐变,先填充满,然后根据取值大小填充黑色,表示熄灭灯
for (int i = 0; i < 8; i++) { //循环遍历八列LED
drawBar(i, (vImag[i * 3 + 2] + vImag[i * 3 + 3] + vImag[i * 3 + 4]) / 3 / 200, &flag); //选取频谱中取平均后的8个值,传递时间标志到绘制函数
}
FastLED.show(); //显示灯条
if ((millis() - t) > dt) { //读取时间,判断是否达到掉落时长
flag = 1; //达到则标记为1
t = millis(); //更新时间
}
}
//绘制函数,根据频率绘制长度
void drawBar(int idx, int16_t value, uint8_t *flag)
{
static int16_t volume[8]; //保存下降数据
constrain(value, 0, 8); //幅度限制在0-8范围内
if (volume[idx] < value) //采集到的数据比之前大则更新,实现上冲效果
volume[idx] = value;
if (idx % 2) { //余2运算判断序号是否为奇数
for (int i = 0; i < 8 - volume[idx]; i++) leds[idx * 8 + i] = CRGB::Black;
} else {
for (int i = volume[idx]; i < 8; i++) leds[idx * 8 + i] = CRGB::Black;
}
if (*flag) {
volume[idx] -= 1; //达到时间则减小1,表示下落
if (idx == 7) *flag = 0; //第0-7列均更新完毕则清除标记
}
}
整人注意安全,包括但不限于挨揍
整人注意安全,包括但不限于挨揍
整人注意安全,包括但不限于挨揍
设计图

BOM


评论