ESP32 ADC测量电压 arduino

文章介绍了ESP32微控制器的ADC功能,包括模拟信号与数字信号的区别、ADC的采样和量化过程。详细阐述了ESP32的ADC1和ADC2通道,以及不同衰减倍数对应的电压范围。代码示例展示了如何配置ADC通道的衰减和采样,以及进行ADC校准以提高读取精度。然而,ESP32的ADC测试存在精度问题,建议通过软件补偿或修改源码来解决。
摘要由CSDN通过智能技术生成

ADC

ADC(模拟-数字转换器),首先了解模拟信号和数字信号之间的差异。模拟信号是连续的,可以在其范围内取无限个离散值,例如声音、光线等。 数字信号则是离散的,具有一组有限数量的值,通常用于计算机和电子设备中的信息传输。ADC的作用是将模拟信号转换为数字信号,以便计算机或其他电子设备进行处理和分析。
在这里插入图片描述

ADC转换的过程分为两个重要步骤:采样和量化。ADC的输入是模拟信号。当输入的模拟信号被采样时,其值将在设定的时间间隔(采样周期)内以等间隔的方式进行抽样。这样就可以将连续的模拟信号转换为一系列等间隔的采样值。接下来,将每个采样值映射到最接近的离散值(也称为“量化”),并且该离散值将作为ADC的输出。量化可以根据设定的分辨率完成,分辨率表示可以区分的离散值的数量。例如,12位ADC具有2^12(即4096)个可区分的离散值。此外,ADC提供选择衰减器(Attenuator)的功能,该衰减器可以对信号进行放大或消减,以确保输入信号处于ADC可接受的幅度范围内。

ESP32的ADC通道

在这里插入图片描述ESP32具有两个集成的ADC,分别称为ADC1和ADC2。两个12位的ADC,其中ADC1(8个通道,连接到GPIO 32-39)和ADC2(10个通道,连接到GPIO 0、2、4、12-15和25-27)

衰减倍数

不同的衰减倍数对应不同的检测电压范围。

ADC的默认满量程电压为1.1V。要读取更高的电压(最高为引脚最大电压,通常为3.3V),则需要将该ADC通道的信号衰减设置为> 0dB。

当VDD_A为3.3V时:
0dB衰减(ADC_ATTEN_0db)表示参考电压为1.1V
2.5dB衰减(ADC_ATTEN_2_5db)表示参考电压为1.5V
6dB衰减(ADC_ATTEN_6db)表示参考电压为2.2V
11dB衰减(ADC_ATTEN_11db)表示参考电压为3.9V

代码实现

#include <esp_adc_cal.h>
#include <driver/adc.h>

#define DEFAULT_VREF    1100    // 默认1.1V的参考电压
#define NO_OF_SAMPLES   64      // ADC采样次数
#define ADC_WIDTH       ADC_WIDTH_12Bit  // ADC 12位宽度
#define ADC_ATTEN       ADC_ATTEN_6db    // 6dB衰减器
#define ADC_PIN         ADC1_CHANNEL_4

esp_adc_cal_characteristics_t *adc_chars;

void setup() {
    Serial.begin(115200);

    adc1_config_width(ADC_WIDTH);  // 设置ADC为12位宽度
    adc1_config_channel_atten(ADC_PIN, ADC_ATTEN);  // 配置ADC通道为6dB衰减器

    // 使用eFuse校准ADC,并获取校准值
    adc_chars = (esp_adc_cal_characteristics_t *) malloc(sizeof(esp_adc_cal_characteristics_t));
    esp_adc_cal_value_t val_type = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN, ADC_WIDTH, DEFAULT_VREF, adc_chars);
}

void loop() {
    uint32_t adc_reading = 0;
    for (int i = 0; i < NO_OF_SAMPLES; i++) {
        adc_reading += adc1_get_raw((adc1_channel_t) ADC_PIN);
        delay(1);
    }

    adc_reading /= NO_OF_SAMPLES;
    uint32_t voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars);

    Serial.print("ADC Reading: ");
    Serial.print(adc_reading);
    Serial.print("\tVoltage: ");
    Serial.println(voltage);

    delay(1000);
}

说明:本次测量时IO34已做分压处理

adc_chars = new esp_adc_cal_characteristics_t; // 新分配一个存储ADC校准值的指针
esp_adc_cal_characterize(ADC_UNIT_2, ADC_ATTEN_DB_11, ADC_WIDTH, DEFAULT_VREF, adc_chars); // 校准ADC2

在ESP32上使用ADC读取模拟电压时,需要先进行ADC的校准,确保输出结果的准确性和稳定性。在校准过程中,需要使用ESP-IDF中的esp_adc_cal_characterize()函数对ADC进行校准。该函数需要传入ADC的一些基本参数和一个指向存储校准值的首地址赋值给adc_chars指针。sizeof(esp_adc_cal_characteristics_t)获取esp_adc_cal_characteristics_t结构体的大小,malloc()函数会返回一个指向分配的内存块的首地址的指针。这样就成功为存储ADC校准值的结构体分配了一段内存,可供后续的ADC校准过程使用。

接下来,esp_adc_cal_characterize()函数将使用指定的参考电压DEFAULT_VREF和衰减ADC_ATTEN以及ADC的位宽ADC_WIDTH进行ADC的校准。校准完成后,esp_adc_cal_characterize()函数将会返回esp_adc_cal_value_t类型的校准值类型,这个值表示所选的ADC_UNITADC_ATTEN组合所需要的校准选项。同时,校准过程得到的校准值会被保存在之前动态分配内存块中的adc_chars指针所指向的结构体中,在后续的代码中可以直接使用校准值进行ADC读取和转换。

总而言之,使用malloc()函数为存储ADC校准值的结构体变量分配内存,并使用esp_adc_cal_characterize()函数为ADC进行校准,可以确保ADC读取的准确性和稳定性。esp_adc_cal_characteristics_t结构体的指针。

在上述代码中,通过使用malloc()函数在堆内存中动态分配了一段大小为esp_adc_cal_characteristics_t结构体大小的内存,同时将该内存的

精度问题

ESP32的ADC测试存在精度问题!!!解决方法:分段算出偏差,然后进行软件补偿,或者使用ESP源码。由于开发问题补偿代码不贴出参考了。
可参考:https://zhuanlan.zhihu.com/p/540437244

参考链接:https://www.jianshu.com/p/7739b143b41d

  • 4
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值