ADC采集
1. 本节介绍
📝本节您将学习如何通过开发板上的 ADC 引脚获取外部电压,注意电压不得超过3.3V,否则可能会导致开发板永久损坏。
🏆学习目标
1️⃣了解 模数转换器【ADC】的基本概念。
2️⃣使用ADC测量板载的ADC模块分压后得到的电压,通过 IDE 的端口打印出来实际电压值。
3️⃣了解滤波的作用,以任务二为基础,通过滤波算法提高数据的稳定度。
2. 了解ADC
什么是ADC
ADC 全称为模拟-数字转换器,是一种用于将模拟信号转换为数字信号的模拟数字转换器。我们知道,模拟信号是连续的,其取值可以在一定范围内任意变化,如声音、光信号等。而数字信号则是离散的二进制信号,如计算机中的数据0和1,仅能取有限的值。
ADC 的工作原理是将模拟信号通过采样转换为离散的数字信号,然后再通过量化、编码等处理,最终得到对应的数字表示。ADC采样的频率越高,得到的数字信号就越接近原来的模拟信号,也就是保真度越高,但是需要更多的资源和计算功耗。
ADC 通常用于从外部模拟传感器中读取模拟信号,并将其转换为数字信号供嵌入式系统或计算机进行处理,例如测量温度、湿度、压力等物理量。
RP2350的ADC介绍
RP2350采用的是逐次逼近型的ADC。
逐次逼近型ADC是一种常见的ADC工作原理,它的思想是通过比较 模拟信号
与 参考电压
之间的大小关系来 逐步逼近输入信号的数字
表示。
在逐次逼近型ADC中,输入信号和参考电压被加入一个差分放大器中,产生一个差分电压。然后,这个差分电压被输入到一个逐步逼近的数字量化器中,该量化器以逐步递减的方式
将其与一系列参考电压进行比较
。
具体来说,在每个逼近阶段,量化器将输入信号与一个中间电压点进行比较,将该电压点上方或下方的参考电压作为下一个逼近阶段的参考电压。这个过程一直持续到量化器逼近到最终的数字输出值为止。
ADC的基本参数
分辨率: 表示ADC转换器的输出精度,通常以位数(bit)表示,比如8位、10位、12位等,位数越高,精度越高。RP2350是12位的分辨率。
采样率: 表示ADC对模拟输入信号进行采样的速率,通常以每秒采样次数(samples per second,SPS)表示,也称为转换速率,表示ADC能够进行多少次模拟到数字的转换。RP2350为500K S/s,表示每秒进行500,000次采样。
采样范围: 指ADC可以采集到的模拟输入信号的电压范围,范围见下:
GND ≤ ADC ≤ IOVDD
其中VREF- 为设置的电压基准负,通常为0V。IOVDD 在开发板上是3.3V。
ADC的引脚
RP2350A对外只支持4个ADC通道,第五个通道是连接到了芯片内部温度传感器。
在开发板上,通过电阻分压的方式给大家预留了一个ADC的验证电路。
理论计算
R15为100K,R16为100K,NMOS-Vth=0.8V,VSYS=4.84V
A = VSYS * (1/2) = 4.84 * 0.5 = 2.42 V
Vadc3 = 2.42V - Vth = 2.42V - 0.8V = 1.62V
数据的滤波
ADC在将模拟信号转换为数字信号的过程中,常常会受到各种噪声和干扰的影响,导致输出数据不稳定或失真。为了提高数据采集的准确性和可靠性,ADC数据滤波成为了不可或缺的一部分。
常见的噪声和干扰
环境因素导致
环境温度的变化可能影响电子元件的参数;
高湿度环境也可能导致电路板绝缘性能下降,引入额外的噪声,影响ADC输出数据
外设本身导致
ADC本身的非线性特性可能导致输入信号与输出数字值之间不是完美的线性关系,造成数据失真,比如1直接跳变到20。
ADC在将模拟信号量化为数字值时存在的固有误差,可能导致输出数据与真实值之间存在微小差异。
电路因素导致
第一个就是电源问题,电源线上存在的纹波可能会被ADC采样,导致输出数据中出现周期性的波动。
电磁的干扰,例如附近的电机、无线设备等产生的电磁波干扰,可能导致ADC输出数据突然跳变或出现异常值。
电路设计时相邻信号线太近,其之间的耦合效应,可能导致ADC采样到的信号中混入了其他信号成分,造成数据失真。
...
那为了削弱或消除这些噪声和干扰,提取出真实的信号成分,我们就可以通过数学或物理方法对ADC输出数据进行处理,抑制噪声频率成分,保留或增强信号频率成分。
这里硬件部分的滤波设计大家自行查询,我们比较讲软件方面滤波。
软件方面的滤波也分有很多种:
常见的软件滤波
平均值滤波
:记录多个采样点求平均值,削弱随机噪声。
中值滤波
:对多个采样点排序后取中值,有效抑制突发噪声。
滑动平均滤波
:采用滑动窗口对数据进行平均,实时性较好。
卡尔曼滤波
:基于最小均方误差准则的递归滤波器,适用于动态系统。
FIR/IIR滤波
:通过设计有限/无限冲激响应滤波器实现特定频率特性的滤波。 ...
3. ADC在Mpy的使用方式
使用machine.ADC
在MicroPython中,使用 machine.ADC
模块可以方便地操作RP2350的adc功能。使用时需要导入该模块。
from machine import ADC
构造函数
machine.ADC(id)
参数说明
访问与 id 标识关联的 ADC 引脚。
示例:
from machine import ADC, Pin
pwm = ADC(Pin(29))
2
方法总结
获取采集到的模拟数值
ADC.read_u16()
获取模拟读数并返回 0-65535 范围内的整数。返回值表示 ADC 获取的原始读数,按比例缩放,最小值为 0,最大值为 65535。
4. ADC采集实验
🏆实验目标
1️⃣使用ADC测量板载的ADC模块分压后得到的电压,通过 IDE 的端口打印出来实际电压值。
2️⃣了解滤波的作用,以任务二为基础,通过滤波算法提高数据的稳定度。
代码验证
使用ADC测量板载的ADC模块分压后得到的电压,通过 IDE 的端口打印出来实际电压值。
from machine import ADC, Pin
import time
# 初始化GPIO29为ADC输入
adc = ADC(Pin(29))
while True:
# 读取ADC值
adc_value = adc.read_u16()
# 将ADC值转换为电压
# 实际电压 = ADC数据 * ( ADC的参考电压 / 能够采集的最大数据 )
voltage = adc_value * (3.3 / 65535.0)
# 打印电压值
print("ADC value:", adc_value, "Voltage:", voltage, "V")
# 等待一段时间再次读取
time.sleep(1)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
效果:
转换的电压结果,与 ADC的引脚
小节的板载ADC验证电路理论计算的数据基本符合。
了解滤波的作用,以任务二为基础,通过滤波算法提高数据的稳定度。
这里使用的是平均值滤波。
from machine import ADC, Pin
import time
# 初始化GPIO29为ADC输入
adc = ADC(Pin(29))
# 定义一个函数来计算平均值
# 默认采样的数据为1000个
def read_adc_average(samples=1000):
total = 0
for i in range(samples):
total += adc.read_u16()
# 稍微延迟以避免连续读取时的干扰
time.sleep_ms(1)
return total / float(samples)
while True:
# 读取ADC值
adc_value = read_adc_average()
# 将ADC值转换为电压
voltage = adc_value * (3.3 / 65535.0)
# 打印电压值
print("ADC value:", adc_value, "Voltage:", voltage, "V")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
效果:
误差与上一个代码比较,降低到了 正负0.001。