ESP32学习笔记:ADC

今天我们来玩儿adc。
概述esp32 芯片有2 个 12位的sar(逐次逼近)adc,最多可以读取18个不同的模拟通道输入,由5个专用转换控制器管理,2个支持高性能多通道扫描,2个支持deep-sleep低功耗模式下运行,还有一个专门用于功率检测和峰值监测。
主要特性如下:
采用 2 个 sar adc,可支持同时采样与转换采用 5 个专用 adc 控制器,可支持不同应用场景(比如,高性能、低功耗,或功率检测和峰值检测)支持 18 个模拟输入管脚1个内部电压 vdd33 通道、 2 个 pa_pkdet 通道(部分控制器支持)可配置 12 位、 11 位、 10 位、 9 位多种分辨率支持 dma(1 个控制器支持)支持多通道扫描模式(2 个控制器支持)支持 deep-sleep 模式运行(1 个控制器支持)支持 ulp 协处理器控制(2 个控制器支持)硬件adc1支持8个通道(gpio32-gpio39),adc2支持10个通道(gpio0、gpio2、gpio4、gpio12-gpio15、gpio25-gpio27),这里有两点需要注意:
adc2的一些引脚比如gpio0、gpio2、gpio15为芯片的strapping 管脚,使用的时候要特别注意adc2只能在wifi功能未启动的情况下使用
adc模拟输入引脚可承受最高3.3v的电压,如果需要测试更高的电压,需要通过分压之类的方式进行降压之后再进行采集。
esp32 adc 对噪声敏感,从而导致 adc 读数出现较大差异。为了尽量减少噪声,可以在使用中的 adc 输入端连接一个 0.1uf 的电容,多重采样也可用于进一步减轻噪声的影响。
软件关于adc的一些概念,比如时钟,分辨率,采样周期,衰减,量程等大家自行了解,下面我们讲一下基础的使用:
模拟电压读取
adc使用不需要初始化引脚了,直接使用下面的函数读取引脚电压,使用默认的参数进行配置,这个参数配置能满足绝大部分的需求了。这里还有一点注意的是这里是阻塞的,直到采集结束。
analogread(32);分辨率设置
如上文中说的,esp32的adc是12位的,我们读取的范围默认是0-4095,如果想改也是可以的,通过下面你函数更改,一般用默认就好了。
/** sets the conversion resolution* default is 12bit (0 - 4095)* range is 9 - 12* */void analogsetwidth(uint8_t bits);adc时钟
adc根据选择的分辨率在多个时钟周期内进行转换,时钟速率越快,转换过程就越快,通过更改时钟分频系数来控制频率,分频越大速率越慢,默认就是1,最快的速率。
/** set the divider for the adc clock.* default is 1* range is 1 - 255* */void analogsetclockdiv(uint8_t clockdiv);adc参考电压
adc的参考电压vref,在不同的esp型号可能是不一样的,我们这里esp32参考电压为1.1v,一般用内部的就可以,要求高的需要校准一下,当然,也可以设置外置的引脚当做参考电压。
/** set pin to use for adc calibration if the esp is not already calibrated (25, 26 or 27)* */void analogsetvrefpin(uint8_t pin);adc衰减倍数
对应不同的电压检测范围,我们可以设置引脚的衰减倍数,默认就是11db,实际检测范围为0-3.3v,下面两个函数,一个设置所有通道的,一个设置特定通道的。
/** set the attenuation for all channels* default is 11db* */void analogsetattenuation(adc_attenuation_t attenuation); /** set the attenuation for a particular pin* default is 11db* */void analogsetpinattenuation(uint8_t pin, adc_attenuation_t attenuation);/*0db --- 1.1v2.5db --- 1.5v6db --- 2.2v11db --- 3.9v(实际最大采集到3.3v电压)* */static uint8_t __analogattenuation = 3;//11dbtypedef enum { adc_0db, adc_2_5db, adc_6db, adc_11db} adc_attenuation_t;通过以上介绍一些可能用到的函数,大家了解一下即可,大部分场合都用默认的就行啦。
完整程序
#define analog_pin 32int analog_value = 0;void setup(){ serial.begin(115200); serial.println(adc demo!); } void loop(){ analog_value = analogread(analog_pin); serial.println(adc value on pin(%d) is %d!,analog_pin,analog_value); delay(1000);}我们直接在loop中读取adc的值,然后把结果通过串口打印出来,adc都使用的默认参数,没有进行配置。
打印结果
使用平均数字滤波器降噪
实际采集中,我们一般使用多次采集取平均值的办法,这样出来的结果可以避免一些错误的噪声影响准确性,方法有多种,具体就是采集多次求平均值,或者去掉最大最小求平均值,大家可以试一下。
对于精度较高的场合,我们可以校准adc,这样出来的结果就非常准确,后面我们再展开实际细说。

什么是软屏/硬屏
smt贴片生产制造要素介绍
花16万买老牌豪车?大众辉腾?单这个标识就比奔驰有面子
【vsan数据恢复】VSAN超融合基础架构数据恢复案例
双向触发二极管用什么可以代换
ESP32学习笔记:ADC
西部数据最新推出了分区存储技术
美国籍的曹敏通过审查,归化成为台湾人
这五款内存销量火爆 到底有什么特别的地方
2021年将是5G换机潮的关键一年
浅谈装配系统中的数字孪生
JESD204B:高达12.5Gbps高速数据采集的新替代方案
人工智能进入2.0时代 将给我们的生活带来很多新的变化
怎样使用一对Nordic NRF24L01无线电在两个单独的Arduino之间进行通信
继电器的高阶应用及起火预防
2009德国汉诺威CeBIT电子展/汉诺威电子产品展CeBI
为何越来越多的LED企业选择在马来西亚设厂呢?
VR全景将造就一个不一样的主题公园
GPIO是什么?
Metaverse降临,寻找永不宕机的真实“虚拟世界”