💡 划重点

  • 项目定位:基于ESP32-S3与INMP441麦克风阵列的卧室睡眠呼吸声监测夜灯,通过FFT频谱分析识别呼吸节律,以WS2812灯带输出柔光渐变反馈。
  • 核心能力:非接触式呼吸声采集、实时频谱分析、灯光情绪化响应、Wi-Fi数据上报。
  • 目标成本:90元以内(不含运费)。
  • 关键参数:I2S采样率16kHz、FFT点数512、灯带亮度可调、呼吸检测周期5秒滑动窗口。
  • 适用场景:卧室夜灯、睡眠辅助、呼吸健康初筛、智能家居联动。
  • 技术栈:Arduino框架、I2S音频、FFT(arduinoFFT库)、WS2812(FastLED库)、Wi-Fi(WiFiManager)、HTTP上报。

需求洞察

目标用户

真实痛点

为什么值得做

方案设计

感知层

控制层

执行层

日志/联网层

物料清单

编号 名称 数量 用途 估算单价(元)
1 ESP32-S3-DevKitC-1 1 主控芯片及开发板 45.0
2 INMP441 I2S麦克风模块 1 音频采集 12.0
3 WS2812灯带(30灯/米,0.5米) 1 柔光呼吸反馈 15.0
4 5V 2A USB电源适配器 1 供电 8.0
5 杜邦线 / 跳线(若干) 1 接线 3.0
6 亚克力灯罩(定制或手工制作) 1 柔光扩散 5.0
7 33Ω电阻 1 WS2812数据线保护 0.2
8 1000μF/10V电解电容 1 电源滤波 0.8
9 轻触按键 1 手动调节模式 0.5
合计 89.5

接线与结构

ESP32-S3引脚 外设引脚 说明
GPIO 4 (I2S SCK) → INMP441 SCK 串行位时钟 原方案SCK=4,保持不变
GPIO 5 (I2S SD) → INMP441 SD 串行数据输出 原方案SD=5,保持不变
GPIO 6 (I2S WS) → INMP441 WS 声道选择 原方案WS=6,保持不变
GPIO 10 → WS2812 DIN 灯带数据输入 原方案WS2812=10,保持不变
3.3V → INMP441 VDD, GND → GND 麦克风供电 麦克风工作电压3.3V
5V → WS2812 VCC, GND → GND 灯带供电 灯带需5V供电,注意共地

接线微调说明:原方案GPIO分配无需改动,但在灯带供电端增加1000μF电容可有效防止峰值电流导致复位。INMP441的LOW POWER模式引脚直接拉高至3.3V,以启用低功耗模式。

结构建议

核心代码

以下为Arduino框架下可编译的骨架代码(PlatformIO / Arduino IDE均可):


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

// 常量定义
#define I2S_WS       6
#define I2S_SCK      4
#define I2S_SD       5
#define LED_PIN      10
#define NUM_LEDS     15
#define SAMPLE_RATE  16000
#define FFT_SIZE     512

// 全局对象
arduinoFFT FFT = arduinoFFT();
CRGB leds[NUM_LEDS];
float real[FFT_SIZE];
float imag[FFT_SIZE];
volatile bool breathDetected = false;
float breathFreqEstimate = 0.2f; // Hz

// I2S初始化
void setupI2S() {
  i2s_config_t i2sConfig = {
    .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_I2S,
    .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
    .dma_buf_count = 8,
    .dma_buf_len = 256,
    .use_apll = false,
    .tx_desc_auto_clear = false,
    .fixed_mclk = 0
  };
  i2s_pin_config_t pinConfig = {
    .bck_io_num = I2S_SCK,
    .ws_io_num = I2S_WS,
    .data_out_num = -1,
    .data_in_num = I2S_SD
  };
  i2s_driver_install(I2S_NUM_0, &i2sConfig;, 0, NULL);
  i2s_set_pin(I2S_NUM_0, &pinConfig;);
}

// 采集音频数据
bool readAudioBlock(int32_t* buffer, int len) {
  size_t bytesRead = 0;
  i2s_read(I2S_NUM_0, buffer, len * 4, &bytesRead;, portMAX_DELAY);
  return bytesRead == len * 4;
}

// FFT频谱分析
void analyzeFFT(int32_t* audioData) {
  for (int i = 0; i < FFT_SIZE; i++) {
    real[i] = (float)(audioData[i] >> 14) / 32768.0f;
    imag[i] = 0.0f;
  }
  float peakFreq = FFT.MajorPeak(real, FFT_SIZE, SAMPLE_RATE);
  // 限制在呼吸频段 0.1~0.8 Hz
  if (peakFreq > 0.1f && peakFreq < 0.8f) {
    breathFreqEstimate = peakFreq;
    breathDetected = true;
  } else {
    breathDetected = false;
  }
}

// 灯光渐变反馈
void updateLights() {
  int breathPhase = (millis() % 5000) / 10; // 0~500 对应 5秒周期
  uint8_t brightness = map(breathPhase, 0, 250, 30, 200);
  // 吸气渐亮(前2.5秒),呼气渐暗(后2.5秒)
  if (breathPhase > 250) brightness = map(breathPhase, 250, 500, 200, 30);
  uint8_t hue = 160; // 浅蓝色调
  FastLED.show();
}

// WiFi连接
void setupWiFi() {
  WiFiManager wm;
  bool res = wm.autoConnect("SleepLamp");
  if (!res) {
    // 无法连接时使用默认配置
  }
}

void setup() {
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
  setupI2S();
  setupWiFi();
  Serial.begin(115200);
}

void loop() {
  int32_t audioBuffer[FFT_SIZE];
  if (readAudioBlock(audioBuffer, FFT_SIZE)) {
    analyzeFFT(audioBuffer);
  }
  updateLights();
  // 每6秒上报一次呼吸频率(简化)
  static unsigned long lastReport = 0;
  if (millis() - lastReport > 6000 && breathDetected) {
    Serial.print("Breath Freq: ");
    // TODO: HTTP POST 上报数据
    lastReport = millis();
  }
  delay(10);
}

调试步骤

  1. I2S音频测试:先注释FFT和灯带逻辑,使用Serial Plotter查看实时音频波形,确认麦克风有信号且无明显直流偏置。
  2. FFT功能验证:播放已知频率音频(如手机App发出0.5Hz的脉冲音),验证peakFreq输出是否接近设定值。
  3. 呼吸检测校准:在安静卧室环境下,呼吸平稳时观察呼吸频率是否落在0.15~0.35Hz(即每分钟9~21次)范围内;若偏大,检查高通滤波参数或FFT窗口。
  4. 灯带同步测试:将呼吸频率估计值映射到灯光渐变速度,确认画面变化平滑、无闪烁。
  5. Wi-Fi上报测试:确认WiFiManager连接成功,使用手机热点验证上报数据是否可见。
  6. 整机联调:模拟仰卧与侧卧不同睡姿,验证麦克风角度调整后仍能有效捕捉呼吸声。
  7. 功耗与发热验证:连续运行24小时,检查ESP32-S3和灯带温度是否正常,确保不发生热降频。

设计图

睡眠呼吸声监测夜灯结构flow
1
感知输入
2
控制处理
3
执行反馈
4
数据上报