【2024 DigiKey 创意大赛】ESP-32-S3- 入门雷达检测 + 语音播报
[复制链接]
本帖最后由 御坂10032号 于 2024-10-29 01:09 编辑
简介
本章节主要完成客厅入门检测的功能。 具体则为采用雷达模块来进行检测是否存在人员移动, 当如果有人员移动的话,雷达将会发送一个高电平给ESP32S3-devkit,之后这个高电平信号将会被中断给捕获到,从而点亮红色LED灯, 并且驱动MX98357模块来播放音频。
接线图如下:
在这里非常感谢群友提供的I2S的配置指导。
后经过群友的帮助之后,成功的自定义并且初始化了I2S的特定PIN,并且播放了一个简单的音调。具体的demo 来自下图。
如果你的板子接线正确的话, 那么你可以听到一个“嘟~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~”的声音。
那么现在还需要解决一个问题就是如何来读取WAV格式。这里其实有很多种方式,比如说通过网络或者是通过SD卡来存取SD卡内保存的音频文件都可以完成播放。 但是由于我这个是检测客厅人员回家的,所以仅仅需要播放一个”欢迎回家“即可。 于是我使用AI语音生成的网站生成了一个"欢迎回家"的语音
这里wav语音转换的时候我踩了很多坑。 我不贴上没有解决的bug, 我这里发现了一个很好的解决方案。 请参考这个帖子
具体的步骤为, 首先使用Audacity 把数据转换为unsigned 8 bit的wav格式。然后通过使用Freeware Hex Editor and Disk Editor打开 wav格式的数据,将数据全选并且拷贝为c语言数组。
如下图所示
修改原本播放音调的代码如下图所示(删除掉播放音频数据的代码)
#include <ESP_I2S.h>
#include <Adafruit_NeoPixel.h>
#define LED_PIN 38 // Pin connected to the data input of SK68XXMINI-HS
#define NUMPIXELS 1 // Number of LEDs (set to 1 if using a single SK68XXMINI-HS)
#define INTERRUPT_PIN 1 // Pin connected to IO1 for detecting high/low signal
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
bool ledOn = false; // LED state
void IRAM_ATTR handleInterrupt() {
// Toggle LED state based on the level of INTERRUPT_PIN
ledOn = digitalRead(INTERRUPT_PIN); // Read the state of the pin (HIGH or LOW)
}
unsigned char rawData[66044] = {
};
const size_t wavDataSize = sizeof(rawData) / sizeof(rawData[0]);
i2s_data_bit_width_t bps = I2S_DATA_BIT_WIDTH_16BIT;
i2s_mode_t mode = I2S_MODE_STD;
i2s_slot_mode_t slot = I2S_SLOT_MODE_MONO;
I2SClass i2s;
void setup() {
Serial.begin(115200);
Serial.println("I2S playback from array");
pinMode(INTERRUPT_PIN, INPUT); // Set INTERRUPT_PIN (IO1) as input
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), handleInterrupt, CHANGE); // Trigger on any change in level (HIGH or LOW)
i2s.setPins(41, 42, 40); // BCLK, LRC, DIN
// 启动 I2S,设置采样率和每个样本的位宽
if (!i2s.begin(mode, 30000, bps, slot)) { // 假设采样率为 48000 Hz
Serial.println("Failed to initialize I2S!");
while (1)
; // 不执行任何操作
}
pixels.begin(); // 初始化 LED
}
void loop() {
if (ledOn) {
// 点亮红色 LED
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // 设置为红色
pixels.show(); // 更新 LED 显示
// 播放 WAV 数据
for (size_t i = 0; i < wavDataSize; i++) {
i2s.write(rawData[i]); // 写入样本到 I2S
}
} else {
// 关闭 LED
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // 关闭 LED
pixels.show(); // 更新 LED 显示
}
delay(5000); // 添加一个小延迟,避免过于频繁的读取
}
并且将你拷贝的音频数组放到rawData处。 同时绑定IO中断用来读取雷达的反馈。这里需要注意的是, 可能需要你自己手动调整采样率。 我这个音频文件下载下来的时候经过查看采样率应该是在48KHZ的,但是如果这个地方使用48KHZ进行播放的时候,音频会出现失帧情况。 所以我在这里调整了好久的采样率以及播放完每一个数组元素的延迟。 最后得到了上面的代码。
完整的播放音频代码如下:
|