玩转物联网人工智能小车(ESP32):详解65模数转换器DAC的使用方法

摘要:本文介绍模数转换器DAC的使用方法

之前已经了解过ESP32芯片ADC功能的使用,它可以把模拟的电压信号转换成数字量。今天来看一下DAC(Digital to analog converter)功能是如何使用的,这个功能的作用是将数字量转换为模拟量。在控制电机的时候也需要将模拟量转换为数字量,那和这个有什么区别呢?这个DAC是真正的将数字量转换成模拟电压量,我可以真正的得到某个稳定的电压值。而PWM是用了一种能量等效的办法,通过占空比控制输出的能量来达到控制电机转速的目的,并不是真正的电压调节来调整电机的转速。

ESP32有两个8位数模转换器(DAC)通道,分别连接到GPIO25(通道1)和GPIO26(通道2)。在这里需要注意的是,由于模拟量输出的特殊性,DAC所使用的引脚是固定的,不能像其它功能一样任意选择所使用的GPIO引脚。ESP32的每个DAC通道可以将数字值0~255转换成模拟电压0~Vref(此处的Vref为VDD3P3_RTC引脚输入的参考电压,一般来说其输入的电压值应等于电源电压VDD)。输出电压可按以下方式计算:

out_voltage = Vref * digi_val / 255

由于DAC只支持8位数模转换,因此可以看到DAC的精度是远低于ADC的最高精度的。

在ESP32中,DAC转换器支持以下列方式输出模拟信号:

  1. 直接输出电压。DAC通道持续输出某一指定电压。
  2. 通过DMA输出连续模拟信号。DAC以某一特定频率转换缓冲器中的数据。
  3. 通过余弦波发生器输出余弦波。DAC通道可以输出特定频率和振幅的余弦波。

今天将介绍一下如何使用DAC通道直接输出电压。在Arduino中,乐鑫科技为大家提供了dacWrite()方法来方便的使用DAC输出电压功能。该方法的定义如下:

void dacWrite(uint8_t pin, uint8_t value)

其中,第一个参数为所用的引脚,这个参数的值只能是25或者26,否则程序会报错。value是8位表示输出电压的值。前面有计算公式了。

先来做一个呼吸灯的例子。找出之前使用的RGB LED模块,如下图所示:

具体接线方法如下表所示:

RGB LED模块

ESP32扩展板

GND

R

P25

G

P26

这个程序所要实现的功能是红绿LED交替亮起、熄灭。具体程序代码如下所示:

#define LED_R_PIN 25

#define LED_G_PIN 26

void setup() {

  // put your setup code here, to run once:

}

bool flag = true;

unsigned char volt = 0;       // 输出电压

void loop() {

  // put your main code here, to run repeatedly:

  if (flag) {

    dacWrite(LED_R_PIN, volt);        // 输出DAC

    dacWrite(LED_G_PIN, 255 – volt);  // 输出DAC

  } else {

    dacWrite(LED_R_PIN, 255 – volt);  // 输出DAC

    dacWrite(LED_G_PIN, volt);        // 输出DAC

  }

  if (volt == 255) flag = !flag;

  volt++;

  delay(10);

}

在这个程序中,直接使用了loop()函数作为循环的主体,因为它本身在运行中就是被循环调用的。volt变量代表输出的电压值,将其定义为unsigned char类型,那么在循环中是从0~255不断的循环。flag变量代表P25引脚的输出电压是0~255还是255~0的变化,P26引脚的电压则与P25引脚的变化趋势相反。

好了,编译、上传程序,看一下红绿LED交替渐亮渐暗的变化吧。接下来再来看一个利用DAC控制器实现声音播放的功能。大家都知道,在弹性介质中,只要波源所激起的纵波的频率在20-20000 Hz之间,就能引起人的听觉,这一频率范围内的振动称为声振动,由声振动所激起的纵波称为声波。所以说声波是一种典型的模拟信号。那么我们日常电脑中的声音文件,都是经过一定频率的采样之后,将模拟信号转换成了数字信号。那么播放这些声音文件的时候,就需要一个相反的过程,就是按照一定的频率,将代表声波的数字信号转换为模拟信号,经扬声器还原成震动之后,就又变成了我们能听见的声音。所以,播放声音的数模转换是必不可少的。今天就来使用这个DAC来完成这个数模转换,实现声音播放的功能。

如果从头开始,分析声音文件,再用DAC将声音转换成电压信号,那恐怕是要耗费不少的力气,所以还是使用成熟的库函数来实现这个功能。这里所使用的库的名称是:XT_DAC_Audio,不过这个库不在Arduino的库列表中,需要我们自己下载和安装后才能使用。

XT_DAC_Audio库的官方网站的下载地址为:https://www.xtronical.com/the-dacaudio-library-download-and-installation/,打开这个网址,页面如下图所示:

单击“Download”即可以得到XT_DAC_Audio的安装文件,该文件为zip格式,然后单击Arduino IDE的“项目”、“导入库”、“添加.ZIP库…”功能,选择刚才下载的文件,XT_DAC_Audio库就安装到Arduino IDE中了。

接下来看一个XT_DAC_Audio的示例程序,该程序的名字叫“PlayWav”,是一个简单的播放声音的小程序,代码如下所示:

#include "SoundData.h"

#include "XT_DAC_Audio.h"

XT_Wav_Class ForceWithYou(Force);     // 创建一个XT_Wav_Class对象的实例,参数为“wav”声音数组 

XT_DAC_Audio_Class DacAudio(25,0);    // 创建一个播放声音对象的实例,参数为DAC引脚和定时器序号

uint32_t DemoCounter=0;               // 计数器变量

void setup() {

  Serial.begin(115200);              

}

void loop() {

  DacAudio.FillBuffer();              

  if(ForceWithYou.Playing==false)      

    DacAudio.Play(&ForceWithYou);      

  Serial.println(DemoCounter++);        

}

在编译、运行该示例程序之前,先来看一下喇叭,我使用的是这种8欧姆的小喇叭,如下图所示,因为ESP32的GPIO驱动能力非常的有限,因此声音很小,几乎要贴到耳朵上才能听见,和一般的耳机声音大小差不多。

将小喇叭的两个引脚一根线接到ESP32扩展板的P25引脚,另一根线接到GND就可以了。如果觉得这个声音太小,可以增加一个LM386声音放大器模块,如下图所示:

LM386的绿色接线柱,是连接喇叭的两端。四个排针中,VCC是供电的电源,电压在5~12V,IN为输入线,可以直接接ESP32的GPIO引脚,比如P25。GND有两个,一个接外部供电的地,一个接ESP32单片机的地就可以了。LM386可以将声音放大200倍,板子上的可变电阻可以调节放大倍数(或者说输出声音)的大小。

好了,接好线就可以编译、上传程序,然后你是不是听到了声音呢?

最后,再来简单的看一下声音是保存在哪里的吧。在这里的声音被转换成了一个数组,定义在了头文件“SoundData.h”文件中了。现在打开来看一下,如下图所示:

这个数组是由声音文件转换成的,在这里我简单的介绍一下处理的过程。

首先需要将声音文件转换成编码为“Unsigned 8-bit PCM”的wav格式的文件。这可以使用免费的软件Audacity(利用“文件”菜单中的“导出”、“导出为WAV”功能,导出时注意编码的格式),其下载网址为:https://www.audacityteam.org/。

利用WinHEX软件打开上一步导出生成的文件,然后利用“Edit”菜单中的“Copy All”、“C Source”功能,就将整个声音文件转换成一个C语言的数组,然后拷贝到剪贴板中了。

最后,打开SoundData.h文件,替换数组中定义的初始化的数据就可以了。另外,数组的大小也要修改一下,修改成新的声音文件的大小。或者,干脆去掉数组大小的指定,让编译器自己去计算。

好了,关于声音文件的处理过程就简单的介绍到这里了。

物联沃分享整理
物联沃-IOTWORD物联网 » 玩转物联网人工智能小车(ESP32):详解65模数转换器DAC的使用方法

发表评论