86|0

12

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第4期】PDM 数据打印及音频波形 [复制链接]

  本帖最后由 garoa 于 2024-12-21 11:58 编辑

    PDM 简介

    PDM(Pulse Density Modulation:脉冲密度调制)是一种数字信号调制方式,通过调整脉冲的密度来表示模拟信号的幅度。与常见的 PWM(脉宽调制)相比,PDM 的工作原理更加精简,它是通过不同的 “1” 和 “0” 信号密度来表示音频信号的强度。

    PDM 的工作原理

    在 PDM 中,音频信号被转换为一系列的脉冲,脉冲的数量和频率对应音频信号的强弱。举个例子,如果音频信号的幅度较大,那么 PDM 信号中 “1” 的脉冲会比较频繁;如果音频信号的幅度较小,则 “1” 的脉冲密度较低。

    与传统的模拟信号相比,PDM 信号优点

        易于数字化处理:PDM 信号本身已经是数字信号,可以直接送入数字处理器进行后续处理。

        抗噪能力强:由于信号是通过高频率的脉冲来传输,PDM 对噪声的抗干扰能力较强。

        低功耗:通常,PDM 麦克风的功耗较低,适合于便携式设备。

 

 

    MP34DT06JTR 简介

    Arduino Nano RP2040 Connect 板载的麦克风 ST MP34DT06JTR 是一颗单声道麦克风,由意法半导体(STMicroelectronics)生产。详细资料见 ST 官方数据手册 Datasheet - MP34DT06J

    特点

        传感器类型:基于MEMS(微机电系统)技术,拥有高灵敏度和低功耗。

        输出格式:提供PDM(脉冲密度调制)信号输出,这种格式适合直接接入微控制器的PDM解码接口。

        频率范围:能够捕捉20Hz到20kHz的声音,非常适合用于语音识别、音频采集等场景。

        供电电压:支持 1.8V 到 3.6V 的宽电压范围。

        方向性:全向(Omnidirectional),意味着它能够均匀捕捉来自各方向的声音。

    工作原理

    MP34DT06JTR 通过拾取声波振动,生成对应的数字PDM信号。微控制器通过解码PDM信号,转换为音频样本。

 

 

    在 Arduino 平台上使用 PDM 麦克风

    Arduino Nano RP2040 Connect 提供了对 PDM 麦克风的支持,Arduino 官方有专门的 PDM 库,文档参考 PDM Library

    初始化

    \small PDM.begin(channels, sampleRate):PDM初始化

     注:channels 为通道数量,1 为单声道,2 为立体声;sampleRate 为采样率。

    获取数据:

    \small PDM.available():获取可读字节数

    \small PDM.read(buffer, size):接收 PDM 数据

     注:buffer 为用于存储 PDM 数据的数组;size 为读取的字节数。

 

 

    演示视频

 


 

 

    示例代码

    因为板载的麦克风是一颗单声道麦克风,所以 channels = 1。PDM 采样率为 20000 Hz。

#include <PDM.h>

// 声道数量(仅支持单声道,固定为 1)
static const char channels = 1;

// PDM 数据的采样率(单位:Hz)
static const int frequency = 20000;

// 用于存储音频样本的缓冲区,每个样本是 16 位
short sampleBuffer[512];

// 读取到的音频样本数量,使用 volatile 修饰以确保线程安全
volatile int samplesRead;

void setup() {
  // 初始化串口,用于调试和打印信息
  Serial.begin(9600);

  // 等待串口连接(仅用于调试模式)
  while (!Serial);

  // 配置 PDM 麦克风的数据接收回调函数
  PDM.onReceive(onPDMdata);

  // 初始化 PDM 麦克风
  if (!PDM.begin(channels, frequency)) {
    Serial.println("PDM 初始化失败!");
    while (1); // 如果初始化失败,则进入死循环
  }
}

void loop() {
  // 检查是否有新的音频样本
  if (samplesRead > 0) {
    // 遍历并打印读取到的样本数据
    for (int i = 0; i < samplesRead; i++) {
      Serial.println(sampleBuffer[i]); // 打印单声道样本值
    }

    // 清除样本读取计数
    samplesRead = 0;
  }
}

/**
 * 回调函数,用于处理 PDM 麦克风采集的数据。
 * 注意:该函数在中断服务程序(ISR)中执行,必须保持简洁高效。
 */
void onPDMdata() {
  // 查询缓冲区中可用字节数
  int bytesAvailable = PDM.available();

  // 从缓冲区读取音频数据到样本缓冲区
  PDM.read(sampleBuffer, bytesAvailable);

  // 每个样本为 16 位(2 字节),计算样本数量
  samplesRead = bytesAvailable / 2;
}

 

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表