今天我们来玩儿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.1V
2.5dB --- 1.5V
6dB --- 2.2V
11dB --- 3.9V(实际最大采集到3.3V电压)
* */
static uint8_t __analogAttenuation = 3;//11db
typedef enum {
ADC_0db,
ADC_2_5db,
ADC_6db,
ADC_11db
} adc_attenuation_t;
通过以上介绍一些可能用到的函数,大家了解一下即可,大部分场合都用默认
的就行啦。
完整程序
#define ANALOG_PIN 32
int 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
,这样出来的结果就非常准确,后面我们再展开实际细说。
感谢大家,关于ESP32的学习,希望大家Enjoy
!
老宇哥带你玩转 ESP32:04 串口玩起来是真方便
老宇哥带你玩转ESP32:03 GPIO数字输入与数字输出
老宇哥带你玩转ESP32:02使用VSCode+PlatformIO搭建开发环境
老宇哥带你玩转ESP32:01入门介绍
欢迎 点分享、收藏、点赞、在看。