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值,并返回转换为以毫伏为单位的校准结果。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/280449.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

红黑树的删除

导航链接 红黑树的性质     红黑树的旋转、变色     红黑树的插入     红黑树的删除 文章目录 导航链接二叉搜索树如何删除结点&#xff1f;场景一&#xff1a;删除没有孩子的结点场景二&#xff1a;删除有一个孩子的结点场景三&#xff1a;删除有两个孩子的结点 红…

海康visionmaster-分支字符:控制调试模式开关的方

在图的右边分支字符模块有两个分支&#xff0c;通过 C#代码 GetParamValue 函数可以看到调试模 式的相关参数 ModuleInfoList 的值为&#xff1a;4#1#0KaTeX parse error: Expected EOF, got # at position 3: 10#̲0#0。其中分支 4#1#0$的 4 表示模 块 id&#xff0c;1 表示这…

操作系统:可变分区管理

有作业序列&#xff1a;作业A要求42K&#xff1b;作业B要求27K&#xff0c;作业C要求22K&#xff0c;作业和空闲内存区如下图所示&#xff0c;请画出最佳适应算法空闲队列图&#xff0c;并分析最佳适应算法是否适合该作业系列。 答&#xff1a;最佳适应算法是按照空闲块由小到大…

Harmony全局应用生命周期 EntryAbility.ts 讲解

之前 我们说过 page页面的生命周期 组件的生命周期 其实他和uni一样有一个整个应用的生命周期 我们如下图打开EntryAbility.ts 这是我们整个程序app的状态控制 他这里也有几个全局的生命周期 比如 我们手机 点开当前 App 启动 app 会触发 它的 onCreate 生命周期 当我们从手…

前端 js 基础(2)

js For In for in 循环遍历 person 对象每次迭代返回一个键 (x)键用于访问键的值键的值为 person[x] 如果索引顺序很重要&#xff0c;请不要在数组上使用 for in。 索引顺序依赖于实现&#xff0c;可能不会按照您期望的顺序访问数组值。 当顺序很重要时&#xff0c;最好使用 f…

元旦特辑:Note6---选择排序

目录 前言❌ 1. 基本思想⚠️ 2. 直接选择排序&#x1f7e2; 2.1 思路分析✳️ 2.2 代码实现❎ 2.2.1 sort.h 2.2.2 sort.c 2.2.3 test.c 2.3 问题解决❇️ 2.3.1 sort.c修改 2.4 特性总结✅ 3. 堆排序&#x1f535; 3.1 代码实现&#x1f3e7; 3.2 特性总结&…

Centos安装Kafka(KRaft模式)

1. KRaft引入 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer&#xff0c;以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 由…

c++ 简单实用万能异常捕获

多层捕获异常&#xff0c;逐渐严格。并打印出错信息和位置&#xff1a;哪个文件&#xff0c;哪个函数&#xff0c;具体哪一行代码。 #include <stdexcept> // 包含标准异常类的头文件try {int a 2 / 0; }catch (const std::runtime_error& e) {// 捕获 std::runt…

浅谈 JSON 对象和 FormData 相互转换,打通前端与后端的通信血脉

前言 大家都知道&#xff0c;前端在和后台进行交互联调时&#xff0c;肯定避免不了要传递参数&#xff0c;一般情况下&#xff0c;params 在 get 请求中使用&#xff0c;而 post 请求下&#xff0c;我们有两种常见的传参方式&#xff1a; JSON 对象格式和 formData 格式&#x…

AtCoder Beginner Contest 334 G

G.Christmas Color Grid 2&#xff08;枚举&#xff0c;Tarjan&#xff09; 题意&#xff1a; 本题与问题 E E E类似。有一个 H H H行和 W W W列的网格&#xff0c;每个单元格都被涂成红色或绿色。用 ( i , j ) (i,j) (i,j)表示从上到下第 i i i行、从左到右第 j j j列的单元…

UIToolKit使用心得

起因 因为那个uitoolkit自己写了一套graphView&#xff0c;所以想着来用用但是用完之后发现也不过如此 怎么构建自己的组件 我在继承Node之后想修改node的样式该怎么办呢是这样的。先用pick点击默认的node节点元素- 在pick默认创建的node节点之后&#xff0c;可以把它的uxml…

跨境电商迎来综合竞争力比拼时代 五大趋势解读跨境2024

过去几年&#xff0c;跨境电商成为外贸出口增长的一大亮点&#xff0c;随着年底国务院办公厅《关于加快内外贸一体化发展的若干措施》的发布&#xff0c;跨境电商在促进经济发展、助力内外贸一体化发展方面的价值更加凸显。 这是跨境电商变化最快的时代&#xff0c;也是跨境电…

CCSK认证:开启云安全领域的黄金大门

&#x1f31f;你是否对云安全领域充满热情&#xff1f;是否希望提升自己在云安全领域的专业性和竞争力&#xff1f;CCSK认证是你的不二之选&#xff01; &#x1f525;CCSK简介&#xff1a; CCSK是国际云安全联盟&#xff08;Cloud Security Alliance&#xff0c;CSA&#xff…

Vue3-29-路由-编程式导航的基本使用

补充一个知识点 路由配置中的 name 属性 &#xff1a; 可以给你的 路由 指定 name属性&#xff0c;称之为 命名路由。 这个 name 属性 在 编程式导航 传参时有重要的作用。 命名路由的写法如下 &#xff1a; 像指定 path 一样&#xff0c;直接指定一个 name 属性即可。{path:/d…

【已解决】 ubuntu apt-get update连不上dl.google.com

在终端使用apt-get update时&#xff0c;连接dl.google.com超时&#xff0c;一直卡在0%&#xff0c;原因是当前ip无法ping到google&#xff08;墙&#xff09;。 解决方法&#xff1a; dl.google.com国内可用IP 选一个&#xff0c;然后按以下命令操作&#xff1a; cd ~ vim …

RSA加密解密——用shell加密java解密

功能描述 使用shell opensll对明文进行RSA加密&#xff0c;将密文用java的RSA工具对密文解密。这应该是全网第一个同时用到shell和java的RSA加密解密教程。中间有很多坑&#xff0c;都踩过了&#xff0c;可以放心使用代码。 正确的实现流程 shell端 首先生成公钥私钥 &…

飞企互联-FE企业运营管理平台 登录绕过漏洞复现

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外&#xff0c;支持企业B2B、C2B与O2O等核心需求&#xff0c;为不同行业客户的互联网转型提供支持。 0x02 漏洞概…

大数据Doris(四十五):物化视图选择最优

文章目录 物化视图选择最优 物化视图选择最优 下面详细解释一下第一步最优物化视图是被如何选择出来的。 这里分为两个步骤: 对候选集合进行一个过滤。只要是查询的结果能从物化视图数据计算(取部分行,部分列,或部分行列的聚合)出都可以留在候选集中,过滤完成后候选集合…

图像中的傅里叶变换及低通与高通滤波

傅里叶变换 高频&#xff1a;在图像中变化剧烈的灰度分量&#xff0c;如边界。 低频&#xff1a;在图像中变化缓慢的灰度分量。 OpenCV中函数为cv2.dft()和cv2.idft()&#xff0c;输入图像要先转换成np.float32格式。得到的结果频率为0的部分会在左上角&#xff0c;为方便处理…

【yolofastest上手】

一、前言 yolofastest网上资料比较少&#xff0c;也没有视频教学&#xff0c;所以想要使用参考了很多资料&#xff0c;只能说各资料都不尽全&#xff0c;让刚接触的小白无从下手。 参考资料: github地址 yolo-fastest 快速上手 修改参数遇到的问题 能在ARM-CPU上实时识别图像的…