ESP32入门六(读取引脚的模拟信号[1]:信号的误差)

在之前的文章,我们介绍了模拟信号,在本章中,我们用实例来详细介绍如何用ESP32来读取一个电压信号。

模拟信号的读取对于很多传感器来说是十分重要的知识点,在之前的文章也介绍了,模拟信号存在一些缺点,如容易受到外界的干扰,信号传输的质量难以控制等。ESP32内置的ADC功能在官方文档中,也明确说明了该功能在精度和防干扰方面是比较差的。所以,ESP32的模拟信号读取功能在硬件和软件上都存在一定的问题,我们需要一定的了解才能正确地解决这个问题,所以,本篇会分成几章来介绍。

我们首先需要了解读取模拟值的函数:

analogRead()函数

函数格式:
analogRead(pin);
参数:
pin - 引脚号码
读取pin引脚的模拟值。

ESP32的ADC通道的分辨率一般为12位,因为每个位可以对应2个值,所以,可以计算出,它的分辨率转换为十进制数值可以用2的12次方(2^12)来计算,结果就是2^12 = 4096。范围为0~4095。

我们也可以用analogReadResolution(bits)函数来定义ADC的分辨率。参数bits范围为9-12(默认为12),对应的分辨率如下:

参数为9时:2^9 = 512,范围为0~511

参数为10时:2^10 = 1024,范围为0~1023

参数为11时:2^11 = 2048,范围为0~2047

参数为12时:2^12 = 4096,范围为0~4095

就是说,在默认设置下,当该引脚接收到的电压为3.3V时,该引脚接收到的值为4095,当接收到的电压为0时,接收到的值为0。

该文,我们用分压电阻的原理来测试读取一个电压的值,我们先介绍一下分压电阻的原理。

ESP32入门六(读取引脚的模拟信号[1]:信号的误差)_第1张图片

分压电阻的原理是指与某一电路串联的导体的电阻,在总电压不变的情况下,在某一电路上串联一个分压电阻,将能起分压的作用,一部分电压将降在分压电阻上,使该部分电路两端的电压减小。

我们来看上面的三个电路,三个电路中,都有一个电源,两个电阻,两个电压计。在这三个电路中,所有电源都设置为5V,但电阻各有区别,我们分别看这三个电路:

电路一:两个电阻的阻值相同。

        电阻1  = 1K,电阻两端电压为2.5V

        电阻2 = 1K,电阻两端电压为2.5V

电路二:电阻1阻值>电阻2阻值。

        电阻1  = 3K,电阻两端电压为3V

        电阻2 = 2K,电阻两端电压为2V

电路三:电阻1阻值<电阻2阻值。

        电阻1  = 1K,电阻两端电压为1V

        电阻2 = 4K,电阻两端电压为4V

我们可以用一个公式来计算出某个电阻两端的电压值。

                电阻1电压=(电阻1电阻/(电阻1电阻+电阻2电阻)×总电压

                U1 = R1/(R1+R2)XU

我们尝试计算一下电路二中电阻一的电压是否如图所示:

        3000Ω/(3000Ω+2000Ω)*5V = 3V

下面,我们尝试用ESP32来测试分压电阻原理是否正确。

电路:

ESP32入门六(读取引脚的模拟信号[1]:信号的误差)_第2张图片

程序代码:

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

void loop() {
  int value =  analogRead(4);      //读取4号引脚的模拟值
  Serial.println(value);
  delay(1000);
}

串口监视器查看运行结果:

ESP32入门六(读取引脚的模拟信号[1]:信号的误差)_第3张图片

结果十分奇怪,因为如果按照分压电阻原理,正常的结果应该为4096/2=2048附近的值。

我们用analogSetAttenuation()函数给引脚设置衰减值,引脚会对输入的电压进行一定的减弱,以防止电压过大造成单片机损坏,衰减程度越大,测量的电压范围越大。

void setup() {
  Serial.begin(115200);
  analogSetAttenuation(ADC_11db);
}

void loop() {
  int value =  analogRead(4);      //读取4号引脚的模拟值
  Serial.println(value);
  delay(1000);
}

ESP32入门六(读取引脚的模拟信号[1]:信号的误差)_第4张图片

就结果来看,是没有任何效果的,因为引脚衰减设置的默认值,就是11db。

目前为止,我们可以读取到引脚的模拟值,但读取到的数据与现实有一定的误差,我们会在之后的章节中慢慢了解出现这种情况的原因。

虽然结果有所误差,但很多情况下,我们并不需要过于精确的数据,比如下面要介绍的一个实例,在这个实例中,我们将设计一个以模拟值来控制一个LED亮度的实例:

ESP32入门六(读取引脚的模拟信号[1]:信号的误差)_第5张图片

在这个实例中,我们先用pwm模式(pwm的介绍可以在之前的文章中找到:ESP32入门三(ESP32的引脚(GPIO)信号)_esp32 gpio-CSDN博客)来控制LED的亮度,所以我们首先要做的是把接收到的模拟信号精度和pwm的精度设置为相同的2^8=256。

  analogReadResolution(8);                      //模拟信号分辨率设为2^8=256
  ledcSetup(0,1000,8);                          //设置pwm频道,频率,精度2^8=256

我们选择的是用4号脚来接收模拟信号,25号脚来输出pwm信号,下面是完整代码:

void setup() {
  analogReadResolution(8);                      //模拟信号分辨率设为2^8=256
  ledcSetup(0,1000,8);                          //设置pwm频道,频率,精度2^8=256
  ledcAttachPin(25,0);                          //25号引脚与0号pwm频道绑定
}

void loop() {
  int adc_value =  analogRead(4);                 //读取4号引脚的模拟值
  ledcWrite(0,adc_value);                         //0号pwm频道绑定的25号引脚pwm输出
  delay(1000);
}

上传代码后,可以观察到,25号引脚上的LED会随着电位器的扭动改变LED的亮度。

在下一章中,我们将详细测试和介绍模拟信号出现误差的原因,尝试消除出现的误差。

你可能感兴趣的:(ESP32开发入门,物联网,c语言,经验分享)