一个基于ESP32S3和INMP441麦克风实现音频强度控制RGB灯带律动的代码示例,使用Arduino语言:
硬件连接
- INMP441 VCC → ESP32的3.3V
- INMP441 GND → ESP32的GND
- INMP441 SCK → ESP32的GPIO 17
- INMP441 WS → ESP32的GPIO 18
- INMP441 SD → ESP32的GPIO 16
- RGB LED灯带 → ESP32的GPIO 2
代码示例
#include <Arduino.h>
#include <driver/i2s.h>
#include <Adafruit_NeoPixel.h> // RGB灯带库
// 定义I2S引脚
#define I2S_WS 18
#define I2S_SD 16
#define I2S_SCK 17
#define I2S_LED_BCK I2S_SCK
#define I2S_LED_WS I2S_WS
#define I2S_LED_SD I2S_SD
#define I2S_PORT I2S_NUM_0
// 灯带定义
#define LED_PIN 2 // 灯带连接的GPIO引脚
#define LED_COUNT 30 // 灯带LED数量
Adafruit_NeoPixel pixels(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800); // 初始化灯带
// I2S配置
const i2s_port_t i2s_port = I2S_PORT; // 使用I2S端口0
#define I2S_SAMPLE_RATE (48000) // 采样率
#define I2S_DMA_BUF_LEN (100) // DMA缓冲区长度
#define I2S_DMA_BUF_CNT (16) // DMA缓冲区计数
// 变量声明
int16_t audioBuffer[100]; // 音频缓冲区
uint32_t audioStrength = 0; // 音频强度
// 初始化I2S
void initI2S() {
i2s_config_t i2s_config = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = I2S_SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = I2S_DMA_BUF_CNT,
.dma_buf_len = I2S_DMA_BUF_LEN,
.use_apll = false,
.tx_desc_auto_clear = false,
.fixed_mclk = 0
};
i2s_pin_config_t pin_config = {
.bck_io_num = I2S_LED_BCK,
.ws_io_num = I2S_LED_WS,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_LED_SD
};
i2s_driver_install(i2s_port, &i2s_config, 0, NULL);
i2s_set_pin(i2s_port, &pin_config);
i2s_start(i2s_port);
}
// 获取音频强度
void getAudioStrength() {
size_t bytes_read;
i2s_read(i2s_port, (void*)&audioBuffer, 50 * sizeof(int16_t), &bytes_read, portMAX_DELAY);
// 计算音频强度
audioStrength = 0;
for (size_t i = 0; i < 50; i++) {
audioStrength += abs(audioBuffer[i]);
}
audioStrength /= 50; // 取平均值
}
// 控制灯带根据音频强度律动
void controlPixels() {
static uint32_t lastUpdate = 0;
uint32_t currentMillis = millis();
// 每100毫秒更新一次
if (currentMillis - lastUpdate >= 1) {
lastUpdate = currentMillis;
getAudioStrength(); // 获取音频强度
// 根据音频强度点亮灯带
for (int i = 0; i < LED_COUNT; i++) {
if (i < (audioStrength / 20)) { // 根据音频强度调整点亮范围
//pixels.setPixelColor(i, pixels.Color(255, 0, 0)); // 红色
// 设置所有LED为彩虹色
uint8_t r, g, b;
// 计算当前LED在颜色轮盘中的位置
int wheelPos = (i * 256 / pixels.numPixels()); // 获得0-255的值
Wheel(wheelPos, r, g, b); // 转换为RGB值
pixels.setPixelColor(i, pixels.Color(r, g, b)); // 设置颜色
} else {
pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // 关闭
}
}
pixels.show(); // 更新灯带
}
}
// Wheel函数根据颜色轮盘的位置返回对应的颜色
void Wheel(byte pos, byte &r, byte &g, byte &b) {
if (pos < 85) {
r = 255 - pos * 3;
g = pos * 3;
b = 0;
} else if (pos < 170) {
pos -= 85;
r = 0;
g = 255 - pos * 3;
b = pos * 3;
} else {
pos -= 170;
r = pos * 3;
g = 0;
b = 255 - pos * 3;
}
}
void setup() {
Serial.begin(115200);
pixels.begin(); // 初始化灯带
initI2S(); // 初始化I2S
}
void loop() {
controlPixels(); // 控制灯带律动
}
代码说明
-
I2S初始化:
- 配置I2S以读取麦克风音频数据。
- 采样率为48000Hz,16位深度,单声道。
-
音频强度计算:
- 使用麦克风采集的音频数据计算平均强度。
- 通过绝对值平均法计算音频强度。
-
灯带控制:
- 根据音频强度动态调整点亮的LED数量。
- 音频强度越高,点亮的LED越多。
可调参数
LED_COUNT
:灯带的LED数量,根据实际硬件调整。LED_PIN
:灯带连接的GPIO引脚。- 音频强度映射公式(
audioStrength / 50
)可以根据实际情况调整,以达到最佳效果。
注意事项
- 确保RGB灯带连接到ESP32的正确GPIO引脚,并供电充足。
- 调试时可通过
Serial.println(audioStrength)
打印音频强度值,观察效果并调整参数。 - 可以进一步优化音频强度计算和灯带控制,实现更复杂的律动效果。
实验结果:
视频效果