💡 划重点

  • 本项目围绕卧室睡眠场景,利用 INMP441 高精度数字麦克风采集呼吸声,通过 ESP32-S3 运行 FFT 频谱分析提取呼吸频率与幅度,动态驱动 WS2812 幻彩灯带实现柔光渐变反馈。异常呼吸事件(如暂停、过缓)可触发灯光警示并预留数据上报通道。整体成本控制在 90 元以内,适合卧室安静环境,帮助用户实时感知自身或家人睡眠呼吸状态。

需求洞察

目标用户包括打鼾人群、轻度睡眠呼吸暂停关注者、婴幼儿父母以及需要照护的老年人。真实痛点在于夜间不易察觉呼吸异常,尤其打鼾低通气或呼吸暂停直接关联健康风险。传统医用睡眠监测设备昂贵且连接繁琐,而普通夜灯缺乏生理感知能力。本项目将呼吸声监测与夜灯自然融合,在不干扰睡眠的前提下提供直观的光效反馈,门槛低、易部署,值得作为个人健康关怀的入门硬件实现。

方案设计

整个系统划分为感知层、控制层、执行层和日志层。感知层由 INMP441 数字 MEMS 麦克风通过 I2S 接口输入原始音频流。控制层以 ESP32-S3 为核心,利用 ESP-IDF 或 Arduino 框架下的 FFT 库对音频片段进行频谱分析,提取 200–1500 Hz 范围内呼吸声能量包络,进而推算呼吸频次和强度。执行层采用 WS2812 LED 灯带,根据呼吸速率驱动柔光渐变:正常呼吸时灯光缓慢律动,呼吸过缓或暂停时改变色温并闪烁提醒。日志层通过板载 Wi-Fi 将异常事件和时间戳上报到本地 MQTT 服务器或串口调试,方便后续健康数据回顾。

信号处理上采用双阈值方法:短时能量低于静音阈值判定为安静,高于呼吸阈值则触发计数并更新灯光节奏。同时加入异常检测,若连续数秒无有效呼吸峰值,则判定为潜在暂停事件,灯光转为警示橙红色并保持至呼吸恢复。

电源使用 5V 适配器直接供电,ESP32-S3 板上稳压为 3.3V,麦克风与灯带共用 5V 电源,整体功耗约 2.5 W,适合整夜运行。

物料清单

序号 名称 规格/型号 数量 用途 估算单价(元)
1 主控板 ESP32-S3-DevKitC-1 1 核心控制与运算 35
2 I2S 麦克风 INMP441 模块 1 呼吸声采集 12
3 幻彩灯带 WS2812B 30颗/米 1米 柔光反馈 18
4 电源适配器 5V 2A 带 DC 接口 1 系统供电 10
5 杜邦线+排母 母对母 20cm 若干 接线 3
6 柔光罩/外壳 亚克力磨砂管 1m 1 光效柔化 8

合计:86 元,在 90 元预算内。

接线与结构

接线依据初始建议并微调:麦克风 I2S 接口 SCK 接 GPIO4,SD 接 GPIO5,WS 接 GPIO6,另外 VCC 接 3.3V,GND 共地。WS2812 数据线接 GPIO10,灯带 5V 和 GND 直接取自电源适配器。由于 GPIO2 或 GPIO8 可能影响板载启动,故选择 GPIO10 避免冲突,该引脚在大部分 ESP32-S3 开发板上无特殊功能。ESP32-S3 的 USB 供电与适配器供电共地,注意不要同时使用两个 USB 口以防倒灌。

物理结构:将灯带粘贴于磨砂亚克力管内侧,主控板和麦克风模块封装在底座内。麦克风通过开孔对准床榻方向,避免遮挡。整体呈圆柱形夜灯造型,灯体向上出光,通过反射实现柔和光环境。

核心代码

基于 Arduino 框架与 ESP32-S3 平台,提供可编译的骨架。需安装 FastLEDarduinoFFT 库。


#include <driver/i2s.h>
#include <FastLED.h>
#include <arduinoFFT.h>

#define LED_PIN     10
#define NUM_LEDS    30
#define SAMPLE_RATE 16000
#define BUFFER_SIZE 1024

i2s_config_t i2s_config = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = SAMPLE_RATE,
    .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S),
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 4,
    .dma_buf_len = BUFFER_SIZE
};

i2s_pin_config_t pin_config = {
    .bck_io_num = 4,
    .ws_io_num = 6,
    .data_out_num = I2S_PIN_NO_CHANGE,
    .data_in_num = 5
};

CRGB leds[NUM_LEDS];
arduinoFFT FFT = arduinoFFT();

double vReal[BUFFER_SIZE];
double vImag[BUFFER_SIZE];
int32_t samples[BUFFER_SIZE];
float breathEnergy = 0;
unsigned long lastBreath = 0;
bool breathDetected = false;

void setup() {
    Serial.begin(115200);
    i2s_driver_install(I2S_NUM_0, &i2s;_config, 0, NULL);
    i2s_set_pin(I2S_NUM_0, &pin;_config);

    FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(80);
}

void loop() {
    size_t bytesRead;
    i2s_read(I2S_NUM_0, samples, sizeof(samples), &bytesRead;, portMAX_DELAY);
    int sampleCount = bytesRead / 4;

    for(int i = 0; i < BUFFER_SIZE && i < sampleCount; i++) {
        vReal[i] = samples[i] >> 14;
        vImag[i] = 0;
    }

    float sum = 0;
    for(int i = 0; i < BUFFER_SIZE/2; i++) {
        if(i > (200 * BUFFER_SIZE / SAMPLE_RATE) && i < (1500 * BUFFER_SIZE / SAMPLE_RATE)) {
            sum += vReal[i];
        }
    }
    breathEnergy = sum / (BUFFER_SIZE/2);

    float brightness = map(breathEnergy, 10, 200, 0, 100);
    brightness = constrain(brightness, 0, 100);

    if(breathEnergy > 50) {
        if(!breathDetected) {
            lastBreath = millis();
            breathDetected = true;
        }
    } else {
        breathDetected = false;
        if(millis() - lastBreath > 10000) {
        } else {
        }
    }

    FastLED.show();
    delay(50);
}

代码通过 I2S 读取麦克风数据,执行 1024 点 FFT 后提取呼吸频带能量,根据能量阈值控制灯光颜色与亮度,并在检测到长时间无有效呼吸时触发橙色警示。

调试步骤

  1. 硬件连接检查:用万用表确认 3.3V、5V 无短路,GPIO4/5/6/10 对应正确。
  2. 上传程序后打开串口监视器,观察 breathEnergy 数值波动。安静环境能量应在 10 左右,轻吹气或模拟呼吸可升至 80 以上。
  3. 调整阈值:若检测过于灵敏或迟钝,修改 breathEnergy > 50 以及 map 范围,直至灯光律动与呼吸同步。
  4. 放置麦克风角度:确保开孔指向呼吸区,可用胶带调整内部防震棉。
  5. 整夜测试:记录异常事件,观察误报率,再微调 10 秒无呼吸告警时长。

设计图

睡眠呼吸声监测夜灯结构flow
1
感知输入 (INMP441 I2S麦克风采集呼吸声)
2
控制处理 (ESP32-S3 FFT频谱分析 呼吸能量提取)
3
执行反馈 (WS2812柔光渐变 正常律动/异常警示)
4
数据上报 (Wi-Fi MQTT 异常事件与日志)