ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])

在之前的文章中,我们介绍了ESP32在读取模拟信号时出现的误差的软件方面原因,在这一篇中,将会介绍并测试由于硬件或其它方面导致数据出现误差的原因。

一、厂商原因

首先,我们需要知道,在每块EPS32中,在出厂时都带有一个ADC的基准值,我们可以用两种方法来查看到该基准值:

1、安装esptool工具来查看基准值

我们需要下载并安装python:

Python Release Python 3.12.1 | Python.org

ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])_第1张图片

选择合适你电脑的版本,下载并安装,在安装过程中,注意选择安装pip工具和勾选加入环境变量。

安装完成后,打开CMD。我们输入命令:

pip install esptool

等待安装完成

ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])_第2张图片

 安装安成后我们输入命令:

espefuse.exe --port COM5 adc_info

注意这里的COM5需要对应你自已ESP32在电脑上的端口号

ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])_第3张图片

我们可以得到adc的校准值。

2、用esp_adc_cal_characterize()函数获取ADC特性

函数:
esp_adc_cal_characterize()

作用:将描述 ADC 在特定衰减条件下的特性,并以[y=coeff_a * x + coeff_b]的形式生成ADC电压曲线

格式:
	esp_adc_cal_value_t esp_adc_cal_characterize(
		adc_unit_t adc_num, 
		adc_atten_t atten, 
		adc_bits_width_t bit_width, 
		uint32_t default_vref, 
		esp_adc_cal_characteristics_t *chars
		)

参数:
	adc_num		-ADC特征编码(ADC_UNIT_1 or ADC_UNIT_2)可以在官方文档中的引脚定义中查看
	atten		-衰减值(ADC_ATTEN_DB_0 / ADC_ATTEN_DB_2_5 / ADC_ATTEN_DB_6 / ADC_ATTEN_DB_11)
	bit_width		-位宽设置(ADC_WIDTH_BIT_9 / ADC_WIDTH_BIT_10 / ADC_WIDTH_BIT_11 / ADC_WIDTH_BIT_12 / ADC_WIDTH_MAX)
	default_vref	-默认ADC基准电压(mV)
	*chars		-用于存储ADC特征的空结构指针


返回:
	ESP_ADC_CAL_VAL_EFUSE_VREF	- ADC特性为eFuse中存储的Vref值
	ESP_ADC_CAL_VAL_EFUSE_TP	-特性为两点的值(仅用于线性模式)
	ESP_ADC_CAL_VAL_DEFAULT_VREF	-特性为默认Vref值

 代码:

#include "esp_adc_cal.h"
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  delay(500);
  float vref_value;
  esp_adc_cal_characteristics_t adcChar;
  esp_adc_cal_value_t cal_mode = esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, 1100, &adcChar);

  if(cal_mode == ESP_ADC_CAL_VAL_EFUSE_VREF){
    vref_value = adcChar.vref; // 获取参考电压
    Serial.print("参考电压为:");
    Serial.println(vref_value);
  }else if(cal_mode == ESP_ADC_CAL_VAL_DEFAULT_VREF){
    Serial.println("默认参考电压");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

运行后串口可以接收到设备的参考电压,当前测试的板子参考电压为1149

 

这个基准电压之所以和参考电压1100V有所误差,是因为每个板子在生产过程中,因为工艺 原因,导致内部电压和参考电压出现误差,所以,在出 厂时,把这个误差值写入到板子,以便使用者可以测量和消除这个误差, 这个基准值可以生成特性曲线,以反映特定 ESP32 芯片 ADC 基准电压的变化,在上一章中所用到的analogReadMillivolts()函数,就是利用这个基准值来消除读取数据时产生的误差。

二、电压误差

大多数情况下,在使用或测试ESP32的过程中,很少人会用到专业的电源来输出。同时,也因为工艺的原因,所以,我们如果用万用表测量3V3引脚时,很可能测量出来的数据并非3.3V。比如本文 中所用的板子是连接到电脑USB接口上的,在所有引脚都悬空的情况下,用万用表测量到的3v3引脚的电压为3.2V。而在另一块板子上测量到的电压为3.32V。在这种情况下,不管是电源的原因还是生产工艺的原因,都会对读取到的数据造成误差。我们同样以上一章中所用的板子,以同样的代码,但生成的电压设置为3.2V来再次测试读取到的数据:

ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])_第4张图片

 我们把代码中的

float vout = (dac_value) * 3.3  / 255;
//改为
float vout = (dac_value) * 3.2  / 255;
#include 
uint8_t dac_value = 0;                            //DAC值,2^8长度
void setup() {
  Serial.begin(115200);
}
 
void loop() {
  dac_value++;                              //DAC值累加
  float vout = (dac_value) * 3.2  / 255;    //DAC值转为电压值
  Serial.print("vout = ");
  Serial.print(vout);                     //串口输出当前输出的电压值
  dacWrite(25,dac_value);                   //25号引脚输出对应电压
 
  float vin = analogReadMillivolts(4)/1000.0;   //4号引脚读取25号引脚的电压值
  Serial.print(" | ");
  Serial.print("vin = ");
  Serial.print(vin);                      //串口输出当前输入的电压值
  
  Serial.print(" | ");
  Serial.print("deviation = ");
  Serial.println(vout - vin);             //串口输出当前输出与输入的误差
  
  delay(100);
}

可以观察到,误差对比上一章进一步减少了

ESP32入门六(读取引脚的模拟信号[3]:信号出现误差的原因[硬件篇])_第5张图片

你可能感兴趣的:(物联网,单片机,嵌入式硬件,c++)