2026-4-10 11:01:00 [显示全部楼层]
14浏览
查看: 14|回复: 0

[ESP8266/ESP32] 用FireBeetle 2 ESP32 P4做个环境噪音检测器

[复制链接]
本帖最后由 aramy 于 2026-4-10 11:01 编辑

昨天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



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2026 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail