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

2023-12-31 01:20

本文主要是介绍ESP32入门六(读取引脚的模拟信号[2]:信号出现误差的原因),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在之前的章节中,我们测试了用ESP32来接收模拟电压信号,在测试中,读取到的数据与现实存在一定的误差,在这一篇中,我们尝试了解出现误差的原因和解决方法。

对于出现的误差,有多种软件和硬件方面的原因:

一、官方设置原因

二、代码原因

三、硬件原因

四、电源原因


我们对应这几个原因,一步一步来测试并尝试解决。

我们所使用的ESP32版本有许多(esp32,esp32-s2,esp32-c3,esp32-s3等),对于ADC的更新和优化也一直在进行。在本系列章节中所使用的版本为esp32,而该版本的ADC功能在使用过程中,体现是比较差的一个版本。

我们在官方文档中可以查到该版本的ADC功能的量程

ADC_ATTEN_DB_0      100 mV ~ 950 mV      (0.1V~0.95V)
ADC_ATTEN_DB_2_5   100 mV ~ 1250 mV   (0.1V~1.25V)
ADC_ATTEN_DB_6      150 mV ~ 1750 mV    (0.15V~1.75V)
ADC_ATTEN_DB_11    150 mV ~ 3100 mV    (0.15V~3.1V)

也就是说,在默认设置下,我们可以读取的电压范围为0.15V~3.1V,但是我们在上一章中所使用的是3.3V的引脚,也就是说,当电压为3.1V时,我们读取到的数据已经等于4095,但电压继续上升时,我们读取到的数据并不会继续增加。

我们可以用代码来测试这个现像,我们用ESP32的DAC功能来生成一个电压,同时用ADC功能来读取这个生成的电压,测试生成的电压和读取的电压是否相同。

#include <esp32-hal-adc.h>
uint8_t dac_value = 0;                            //DAC值,2^8长度
void setup() {Serial.begin(115200);
}void loop() {dac_value++;                              //DAC值累加float vout = (dac_value) * 3.3  / 255;    //DAC值转为电压值Serial.print("vout = ");Serial.print(vout);                     //串口输出当前输出的电压值dacWrite(25,dac_value);                   //25号引脚输出对应电压int adc_value = analogRead(4);            //4号引脚读取25号引脚输出的模拟值float vin = (adc_value*3.3)  / 4095;      //读取到的数据转为电压值Serial.print(" | ");Serial.print("vin = ");Serial.println(vin);                      //串口输出当前输入的电压值delay(1000);
}

 查看串口输出

我们可以观察到

当输出的电压到达0.06V时,读取到的电压为0.01V。误差为0.06

在观察过程中,误差慢慢增加,当输出电压到达2.47V时,读取到的电压为2.12V,误差达到最大误差值,为0.35。

之后,误差慢慢减少,当输出电压到达3.30V时,读取到的电压为3.25V,误差为0.05。

这时,我们发现,这与官方文档所说明的量程为0.15V~3.10V的又出现了偏差。


所以,我们继续尝试用另一个函数:analogReadMillivolts()来读取4号引脚的电压:

#include <esp32-hal-adc.h>
uint8_t dac_value = 0;                            //DAC值,2^8长度
void setup() {Serial.begin(115200);
}void loop() {dac_value++;                              //DAC值累加float vout = (dac_value) * 3.3  / 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);
}

读取的结果同样并不完美,同样出现误差的变化,但对比之前,误差已经在一定的范围内

当读取到的电压到达3.1V时,超量了0.04V,误差最大为0.14。

至此,我们大概已经可以了解到,在代码层面出现误差的原因有两点:

一、官方设置的量程问题

二、与analogRead()相比较,使用analogReadMillivolts()函数能更精确地读取对应的电压值。

        我们在官方文档中详细地了解一下这两个函数:ADC — Arduino-ESP32 2.0.14 documentation

analogRead()函数的作用是用于读取指定引脚的ADC值,返回的结果未经过校准。

        

analogReadMillivolts()函数的作用是用于读取指定引脚的ADC值,并返回转换为以毫伏为单位的校准结果。

至此,我们在本章中已经了解了软件方面导致数据出现误差的原因,在下一章中,我们将介绍在硬件方面导致数据出现误差的原因。

这篇关于ESP32入门六(读取引脚的模拟信号[2]:信号出现误差的原因)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/554562

相关文章

Java Lettuce 客户端入门到生产的实现步骤

《JavaLettuce客户端入门到生产的实现步骤》本文主要介绍了JavaLettuce客户端入门到生产的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录1 安装依赖MavenGradle2 最小化连接示例3 核心特性速览4 生产环境配置建议5 常见问题

Linux下利用select实现串口数据读取过程

《Linux下利用select实现串口数据读取过程》文章介绍Linux中使用select、poll或epoll实现串口数据读取,通过I/O多路复用机制在数据到达时触发读取,避免持续轮询,示例代码展示设... 目录示例代码(使用select实现)代码解释总结在 linux 系统里,我们可以借助 select、

MyBatis Plus大数据量查询慢原因分析及解决

《MyBatisPlus大数据量查询慢原因分析及解决》大数据量查询慢常因全表扫描、分页不当、索引缺失、内存占用高及ORM开销,优化措施包括分页查询、流式读取、SQL优化、批处理、多数据源、结果集二次... 目录大数据量查询慢的常见原因优化方案高级方案配置调优监控与诊断总结大数据量查询慢的常见原因MyBAT

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

java读取excel文件为base64实现方式

《java读取excel文件为base64实现方式》文章介绍使用ApachePOI和EasyExcel处理Excel文件并转换为Base64的方法,强调EasyExcel适合大文件且内存占用低,需注意... 目录使用 Apache POI 读取 Excel 并转换为 Base64使用 EasyExcel 处

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏

从入门到精通详解Python虚拟环境完全指南

《从入门到精通详解Python虚拟环境完全指南》Python虚拟环境是一个独立的Python运行环境,它允许你为不同的项目创建隔离的Python环境,下面小编就来和大家详细介绍一下吧... 目录什么是python虚拟环境一、使用venv创建和管理虚拟环境1.1 创建虚拟环境1.2 激活虚拟环境1.3 验证虚

深度剖析SpringBoot日志性能提升的原因与解决

《深度剖析SpringBoot日志性能提升的原因与解决》日志记录本该是辅助工具,却为何成了性能瓶颈,SpringBoot如何用代码彻底破解日志导致的高延迟问题,感兴趣的小伙伴可以跟随小编一起学习一下... 目录前言第一章:日志性能陷阱的底层原理1.1 日志级别的“双刃剑”效应1.2 同步日志的“吞吐量杀手”

使用Java读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成