用FireBeetle 2 ESP32 P4做个环境噪音检测器

2026-04-101111
精华项目
AI 快速预览详细 收起
本文介绍了如何使用FireBeetle 2 ESP32 P4开发板和集成的MEMS PDM麦克风,结合SSD1306 OLED屏幕制作一个环境噪音监测器。项目通过I2S驱动麦克风,采样率为16000Hz,采集声音强度并将其转换为分贝值。最终,将噪音值映射到OLED屏幕上,以动态显示环境噪音。该项目适合初学者和对环境监测感兴趣的用户。


昨天FireBeetle 2 ESP32 P4开发板驱动了SSD1306的OLED屏幕,绘制了一个油门表的图像。今天在这个项目的基础上结合FireBeetle 2 ESP32 P4开发板上的麦克风制作一个环境噪音监测器。
用FireBeetle 2 ESP32 P4做个环境噪音检测器图1
一、硬件
看官方说明文档可以看见,开发板上有集成一颗MEMS PDM麦克风。连接到ESP32P4板子的12、9脚,使用I2S驱动。显示部分依然是SSD1306主控的OLED屏幕。
用FireBeetle 2 ESP32 P4做个环境噪音检测器图2
二、驱动麦克风
PDM麦克风只需要两个数据线即可驱动。12脚为时钟线;9脚为数据线。在ESP-IDF下使用I2S进行驱动,采样率使用16000,采样深度为16位,采集到的信号为单声道信号。
  1. void init_microphone(void)
  2. {
  3.     i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
  4.     ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, NULL, &rx_handle));
  5.     i2s_pdm_rx_config_t pdm_rx_cfg = {
  6.         .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
  7.         /* The default mono slot is the left slot (whose 'select pin' of the PDM microphone is pulled down) */
  8.         .slot_cfg = I2S_PDM_RX_SLOT_PCM_FMT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
  9.         .gpio_cfg = {
  10.             .clk = PDM_CLK_PIN,
  11.             .din = PDM_DATA_PIN,
  12.             .invert_flags = {
  13.                 .clk_inv = false,
  14.             },
  15.         },
  16.     };
  17.     ESP_ERROR_CHECK(i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg));
  18.     ESP_ERROR_CHECK(i2s_channel_enable(rx_handle));
  19. }
复制代码

三、读取麦克风信息,转换为声强值
麦克风本质上是个ADC转换器,不停地将感知到的声音强度通过AD转换,转为一个具体的数字。采样率使用16000Hz,意味着每秒钟转换16000次,每个数据都是个16位的整形。本项目是测量环境的噪音值,所以这里将收集到一段时间内麦克风的值转换成声音强度信息。
  1. // 计算声音强度
  2. float calculateVolumeRMS(int16_t *buffer, int size)
  3. {
  4.     // 第一步:计算直流偏置(平均值)
  5.     float sum = 0.0f;
  6.     for (int i = 0; i < size; i++)
  7.     {
  8.         sum += buffer[i];
  9.     }
  10.     float dc_offset = sum / size;
  11.     // 第二步:去除 DC 偏置后计算 RMS
  12.     float ac_sum = 0.0f;
  13.     for (int i = 0; i < size; i++)
  14.     {
  15.         float sample = buffer[i] - dc_offset;
  16.         ac_sum += sample * sample;
  17.     }
  18.     float rms = sqrtf(ac_sum / size);
  19.     // 第三步:转换为分贝(使用更合适的参考值)
  20.     if (rms < 1.0f)
  21.         return -100.0f;
  22.     return 20.0f * log10f(rms / 1000.0f); // 参考值改为 1000,可根据实际调整
  23. }
复制代码
这里计算出的结果也是分贝(db),但是这个值和物理声学中的分贝不一样。
  
计算值
  
  
对应环境情况
  
  
-60dB
  
  
绝对安静
  
  
-40dB
  
  
安静
  
  
-20dB
  
  
嘈杂
  
  
0dB
  
  
吵闹
  


四、将声强信息映射到OLED屏幕的角度。
有了噪音值,就需要展示出来。将噪音值映射到0~180度的弧线上。这里取-40dB~0dB进行映射。将映射好的角度通过一条线进行绘制,这样就能够动态地看见环境噪音值了。
  1. // 最小有效音量 (静音): -40 dB
  2. // 最大有效音量 (满载): 0 dB
  3. float map_volume_to_angle(float db) {
  4.     float min_db = -40.0f;
  5.     float max_db = 0.0f;
  6.    
  7.     // 限幅
  8.     if (db < min_db) db = min_db;
  9.     if (db > max_db) db = max_db;
  10.    
  11.     // 归一化到 0.0 ~ 1.0
  12.     float normalized = (db - min_db) / (max_db - min_db);
  13.    
  14.     // 映射到角度: 180度(左) 到 360度(右) -> 范围90度
  15.     // 或者根据你的表盘设计:180度是0%,360度是100%
  16.     float start_angle = 180.0f;
  17.     float end_angle = 360.0f; // 或者 450.0f 如果表盘是半圆以上
  18.    
  19.     return start_angle + (normalized * (end_angle - start_angle));
  20. }
复制代码
五、效果演示用FireBeetle 2 ESP32 P4做个环境噪音检测器图3用FireBeetle 2 ESP32 P4做个环境噪音检测器图4


六、源码
下载附件SSD1306.zip



创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(0)
- 没有更多了 -