💡 划重点
- 用 ESP32-S3 做主控,搭配 INMP441 数字麦克风采集睡眠呼吸声,通过 FFT 分析频段能量,识别呼吸、打鼾与异常静默。WS2812 灯环输出柔光渐变,既当夜灯又做状态反馈。整机成本控制在 90 元内,卧室无感佩戴,可联网记录睡眠呼吸趋势。
需求洞察
目标用户是关注睡眠质量的年轻人、轻度打鼾者、独居老人及家属。真实痛点有三:传统睡眠监测设备需要佩戴指夹或胸带,异物感强;起夜时普通夜灯骤亮刺眼,打断睡意;呼吸暂停或异常呼吸难以被本人察觉。为什么值得做?呼吸声是低成本、非接触的生理信号,麦克风不接触皮肤,适合长期卧室使用。夜灯是卧室刚需,叠加监测功能后不增加使用负担。90 元内方案让健康监测从医疗设备变成日用硬件,具备可复制性。
方案设计
感知层:INMP441 通过 I2S 输出 24 位数字音频,采样率 16kHz,捕捉呼吸声、鼾声与环境噪声。麦克风朝上放置,避免灯体遮挡。
控制层:ESP32-S3 双核运行。I2S 读取 512 点音频帧,加汉宁窗后做 FFT。呼吸声能量集中在 100-500Hz,打鼾集中在 50-300Hz,环境高频噪声可被频段比过滤。计算低频能量占比与时间包络,判断呼吸节律。若连续多帧能量低于阈值,判定呼吸暂停风险。
执行层:WS2812 12 位灯环。正常呼吸时暖橙微光,亮度随呼吸包络缓慢起伏;打鼾时淡蓝渐变;疑似呼吸暂停时红色柔光呼吸提示;起夜时轻触或声控渐亮至暖白。
日志/联网层:ESP32-S3 通过 WiFi 将每分钟呼吸率、打鼾次数、异常事件上传 MQTT 或 HTTP 接口。本地串口输出调试日志,关键数据可存 Flash。夜间断网时缓存,恢复后补传。
物料清单
| 物料 | 数量 | 用途 | 估算单价 | 合计 |
|---|---|---|---|---|
| ESP32-S3 开发板 | 1 | 主控与联网 | 30 元 | 30 元 |
| INMP441 麦克风模块 | 1 | 呼吸声采集 | 10 元 | 10 元 |
| WS2812 灯环 12 位 | 1 | 柔光夜灯与反馈 | 8 元 | 8 元 |
| Type-C 电源与线材 | 1 | 5V 供电 | 8 元 | 8 元 |
| 亚克力柔光罩 | 1 | 漫射光线 | 10 元 | 10 元 |
| 3D 打印底座 | 1 | 固定与散热 | 10 元 | 10 元 |
| 杜邦线、电阻、电容 | 1 套 | 接线与滤波 | 4 元 | 4 元 |
| 麦克风防尘网 | 1 | 防尘与声学 | 5 元 | 5 元 |
| 合计 | 85 元 |
接线与结构
INMP441:VDD 接 3.3V,GND 接地,L/R 接地选择左声道。I2S 引脚按给定:SCK=4,SD=5,WS=6。WS2812:DIN 接 GPIO10,5V 供电,GND 共地,数据线串 330Ω 电阻,电源并 1000μF 电容。结构上麦克风置于底座顶部开孔处,灯环套在柔光罩内侧,柔光罩磨砂处理,避免直射眼睛。
核心代码
#include <driver/i2s.h>
#include <arduinoFFT.h>
#include <FastLED.h>
#define I2S_SCK 4
#define I2S_WS 6
#define I2S_SD 5
#define LED_PIN 10
#define LED_NUM 12
CRGB leds[LED_NUM];
arduinoFFT FFT = arduinoFFT();
double vReal[512], vImag[512];
void setupI2S() {
i2s_config_t cfg = {
.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = 16000,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 4,
.dma_buf_len = 512,
.use_apll = false
};
i2s_driver_install(I2S_NUM_0, &cfg;, 0, NULL);
i2s_pin_config_t pins = {
.bck_io_num = I2S_SCK,
.ws_io_num = I2S_WS,
.data_out_num = I2S_PIN_NO_CHANGE,
.data_in_num = I2S_SD
};
i2s_set_pin(I2S_NUM_0, &pins;);
}
void setup() {
Serial.begin(115200);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM);
setupI2S();
}
void loop() {
size_t bytesRead;
int32_t raw[512];
i2s_read(I2S_NUM_0, raw, sizeof(raw), &bytesRead;, portMAX_DELAY);
for (int i = 0; i < 512; i++) {
vReal[i] = (double)(raw[i] >> 8) / 8388608.0;
vImag[i] = 0;
}
double lowEnergy = 0, totalEnergy = 0;
for (int i = 1; i < 256; i++) {
double freq = i * 16000.0 / 512.0;
double mag = vReal[i];
totalEnergy += mag;
if (freq >= 50 && freq <= 500) lowEnergy += mag;
}
double ratio = lowEnergy / (totalEnergy + 1e-6);
if (ratio > 0.55) {
} else if (ratio > 0.35) {
} else {
}
FastLED.setBrightness(60);
FastLED.show();
delay(50);
}
调试步骤
- 烧录 I2S 测试程序,串口打印原始值,确认 INMP441 有数据。
- 安静环境采集 10 秒,记录本底噪声与低频能量基线。
- 模拟呼吸声和打鼾声,观察 FFT 频段比变化,调整阈值。
- 测试 WS2812 灯效,确认柔光渐变不刺眼,亮度阶梯平滑。
- 整机联调,连续运行 30 分钟,检查发热与丢帧。
- 连接 WiFi,验证呼吸率与异常事件上报。
- 放入卧室实测,根据实际环境微调麦克风增益与灯效颜色。