news 2026/9/9 10:35:07

树莓派Pico ADC采集与PWM控制:从电位器到SerialPlot可视化实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
树莓派Pico ADC采集与PWM控制:从电位器到SerialPlot可视化实战

1. 项目概述与硬件准备

1.1 这个项目到底在做什么

手头有一块树莓派 Pico 开发板,想玩点模拟量采集?这应该是很多嵌入式初学者绕不开的一关。Pico 作为一块功能极其丰富但价格相当友好的开发板,官方资料里最容易被忽略却又最实用的功能之一就是 ADC(模数转换)。这次的项目核心很简单:通过 Pico 的 ADC 接口读取一个模拟电位器(旋钮变阻器)的电压值,把电压值映射为 LED 的亮度变化,同时将采集到的数据通过 USB 串口发送到上位机,用 SerialPlot 这个免费工具把波形画出来,实时观察 ADC 采样的动态响应。

这个看似“三合一”的小项目,其实把嵌入式开发里几个最基础也最重要的环节全串起来了:模拟信号采集、数字量转换、PWM 输出控制、串口通信、上位机数据可视化。把这套流程跑通,后面再去做传感器采集、PID 控制调试、信号分析,基本就会顺手很多。

项目适合谁?如果你是刚接触微控制器、想理解 ADC 原理和实际用法的新手,或者已经玩过 GPIO 点灯、想进一步提升的老手,又或者正在做某个需要采集模拟信号并观察波形的实际项目但不知道从哪里下手,这套流程都能给你一个可以直接复现的完整方案。

1.2 硬件清单与接线方法

实物接线非常简单,任何一个入门的玩家手头基本都有这些零件:

硬件型号/规格数量
主控板Raspberry Pi Pico(RP2040)1
电位器10KΩ 旋转式(也可以用滑动变阻器)1
LED普通 5mm 红/绿/蓝均可1
限流电阻220Ω1
面包板通用 830 孔1
杜邦线公对公/公对母若干若干
数据线Micro USB(注意要支持数据传输)1

接线之前先说清楚 Pico 的 ADC 引脚资源。RP2040 芯片内部集成了一共 5 路 ADC 输入,其中 3 路被引出到排针上,分别是 GPIO26(ADC0)、GPIO27(ADC1)、GPIO28(ADC2),还有一路是 GPIO29(ADC3),它连接到了芯片内部的温度传感器。换句话说,实际可用的外部模拟输入就是前三个引脚。官方 ADC 的分辨率是 12 位,但 MicroPython 封装后返回的是 16 位精度的数值(0~65535),这个细节后面会详细说到。

具体的接线方案:

  • 电位器的 1 脚接 Pico 的 3.3V 输出(物理引脚 36)
  • 电位器的 3 脚接 Pico 的 GND(物理引脚 38)
  • 电位器的 2 脚(中间抽头)接 Pico 的 GPIO26(物理引脚 31)
  • LED 正极通过 220Ω 限流电阻接 GPIO16(物理引脚 21)
  • LED 负极接 GND(物理引脚 23)

这里有个非常关键的细节:Adafruit 版本的 Pico 板卡上引脚丝印会有不同,但标准 Pico 的排针布局是一致的。接线前最好用万用表确认一下电位器中间脚到底是不是活动的那个触点,如果接反了中间抽头和固定端,代码还是能跑,但你拧旋钮的时候会发现 ADC 读数不变,那就是接错位置了。

提示:Pico 的 ADC 输入范围是 0~3.3V,不要直接给超过 3.3V 的电压,否则有可能烧毁引脚。电位器接法刚好是一个可调分压电路,输出的电压范围天然不会超过 VCC,所以这个用法是绝对安全的。

1.3 开发环境搭建与 MicroPython 固件刷写

既然要用 Pico 做开发,绕不开的就是选哪个开发框架。选项主要有三个:官方 C SDK、Arduino 环境、MicroPython。对于 ADC 采集和串口通信这类功能,三个方案都能做,但 MicroPython 优势在于代码量少、实时修改方便、不需要交叉编译器,非常适合快速验证想法和做调试。C SDK 性能更强、实时性更稳,适合产品化开发。Arduino 则介于两者之间。这里我选择 MicroPython,因为它在上位机联调场景下的开发效率是最高的。

刷固件流程不复杂:

  1. 按住 Pico 板子上的 BOOTSEL 按钮不放
  2. 用 Micro USB 数据线连接 Pico 到电脑
  3. 此时电脑会出现一个名为 RPI-RP2 的移动磁盘
  4. 从树莓派官网或 MicroPython 官网下载最新的 .uf2 固件文件(推荐 rp2-pico-w 或 rp2-pico,根据板型选择)
  5. 将 .uf2 文件直接拖入 RPI-RP2 磁盘中
  6. 拖入后磁盘自动消失,板子自动重启,此时固件已刷写完成

刷完固件以后,如果你用的是 Windows 系统,很有可能会遇到一个设备识别问题——设备管理器里看到的是未知设备或没有正确识别出串口。这个几乎可以肯定是 USB 串口驱动的问题。Pico 的 MicroPython 固件默认使用 CDC 协议,在 Windows 上它会被识别成一个虚拟串口,通常不需要额外装驱动就能被识别成 “USB Serial Device”,但如果你的系统是老版本 Windows 或者存在冲突,可能需要检查一下 CH340 芯片驱动。这里插一句,很多 USB 转 TTL 模块用的都是 CH340 芯片,网上搜索“CH340串口驱动”能轻松找到官方驱动包。如果 Pico 直接连接后没识别出串口,先检查驱动;如果识别出的 COM 口带黄色感叹号,就是驱动冲突,手动更新驱动即可。

接下来,连接好板卡之后,我比较推荐使用 Thonny 作为编辑器。它集成了解释器、文件管理、串口终端三个核心功能,在“工具->选项->解释器”里选择 MicroPython (Raspberry Pi Pico),端口会自动列出。或者用 VS Code 加 MicroPico 插件也可以,但 Thonny 对新手的友好程度是无可替代的。

2. ADC 采集原理解析与核心代码实现

2.1 电位器分压与 ADC 采样背后的数学逻辑

很多人会把 ADC 当作一个无需理解内部原理的“黑盒子”,觉得只要调用库函数就可以了。但你要是不知道它在算什么,就很容易在某些场景下犯错。

ADC 的本质是把连续的模拟电压离散成数字量。Pico 的 RP2040 芯片内部 ADC 参考资料明确说明:输入电压范围为 0~3.3V,分辨率为 12 位,也就是输出 0~4095 的整数值。MicroPython 库函数read_u16()返回的不是 12 位,而是将其左移到了 16 位,变为 0~65535。

写成公式就是:

ADC 原始值 / 65535 = 输入电压 / 3.3V

所以当你读取到一个值raw时,对应的实际电压:

电压 (V) = raw * 3.3 / 65535

这一点是很多新手容易踩坑的地方:如果你以为返回值是 12 位的,直接把 4095 作为分母,算出来的结果偏差会非常大。同时官方文档里也指出,RP2040 ADC 的参考电压其实精确值是 3.3V,但如果你需要更高精度的测量,最好用万用表实测一下板子的 3.3V 引脚电压再代入运算。我实测过几块 Pico,3.3V 引脚实际输出多在 3.28V 左右,虽然误差不大,但在精密测量场景下这个因素必须考虑进去。

再说回电位器。电位器的本质是一个可调电阻分压器,一端接 3.3V、另一端接地、中间抽头输出电压。当旋钮转到最左端时,中间抽头相当于接到 GND 上,电压趋近 0V;转到最右端时,相当于直接接到 3.3V,电压趋近满量程。中间位置则按照线性(或对数)规律变化。所以 ADC 读到的数值,本质上就是旋钮角度的映射。

这里再延展一个实际项目里常遇到的问题:ADC 采样值的噪声。由于电磁干扰和电源纹波的影响,ADC 读数并不稳定,尤其在旋钮转到中间位置时,常常能看到采样值在几个甚至几十个 LSB 之间跳动。解决方式一般有两种:硬件上在 ADC 引脚与 GND 之间并联一个 100nF 的电容做低通滤波,软件上做多次采样取平均或滑动滤波。对于这个项目,软件滤波已经足够,后面代码里会体现。

2.2 核心代码:ADC 读取、电压换算与软件滤波

下面给出完整的 MicroPython 代码。这段代码把 LED 亮度控制、电位器读取、串口输出全部整合到一起,逻辑非常清晰,每一段注释在做什么、为什么这么做,都写出来了。

from machine import Pin, ADC, PWM import time import math # ------------------- 引脚初始化 ------------------- # 电位器信号线接 GPIO26,对应 ADC 通道 0 adc_pin = ADC(Pin(26)) # LED 接 GPIO16,必须使用 PWM 模式才能实现亮度渐变 led_pin = PWM(Pin(16)) led_pin.freq(1000) # PWM 频率 1kHz,人眼感受不到闪烁 # ------------------- 滤波相关变量 ------------------- # 滑动窗口滤波,窗口大小可以调节,窗口越大越平滑但响应变慢 FILTER_WINDOW = 10 adc_history = [0] * FILTER_WINDOW history_index = 0 def moving_average_filter(raw_value): """滑动平均滤波:保存最近 N 次采样值并求均值""" global history_index adc_history[history_index] = raw_value history_index = (history_index + 1) % FILTER_WINDOW return sum(adc_history) // FILTER_WINDOW # ------------------- 主循环 ------------------- while True: # 1. 采集原始 ADC 值(16位范围 0~65535) raw_u16 = adc_pin.read_u16() # 2. 软件滤波,降低噪声影响 filtered_u16 = moving_average_filter(raw_u16) # 3. 计算实际电压值,保留三位小数 voltage = filtered_u16 * 3.3 / 65535 # 4. 将 ADC 值映射到 LED 亮度(PWM 也是 0~65535 范围,恰好直接映射) led_pin.duty_u16(filtered_u16) # 5. 通过串口输出数据,SerialPlot 用逗号分隔多个通道 # 这里输出两个通道:原始 ADC 值和电压值 print(f"{filtered_u16},{voltage:.3f}") # 采样间隔:50ms,即约 20Hz 的采样率 time.sleep_ms(50)

代码不长,但有几个细节必须重点说明。

第一,read_u16()返回的是 0~65535,这刚好和 PWM 的duty_u16()输入范围完全一致,所以可以直接把 ADC 读数赋值给 LED 的 PWM 占空比。这是一个非常巧妙的间接映射,你旋动电位器,LED 亮度就跟着线性变化。这里 PWM 频率我设置为 1kHz,没有选更高的 5kHz 或者 10kHz,是因为 1kHz 在不做缓冲驱动的情况下,对普通 LED 来说效果已经够了,而且更低的频率在视觉上更容易察觉到亮度变化的过程。如果你用示波器观察 PWM 波形,1kHz 也能看到明显的方波周期。

第二,滤波窗口大小的选择。10 次滑动平均对于 50ms 采样周期来说,滤波器滞后大约 500ms,在视觉上看到 LED 亮度变化时会感觉“柔顺”了一些,但旋转速度快的时候会有一种“拖尾”阻尼感。如果你希望实时性更高,窗口减到 3 或 5;如果希望曲线更平滑,可以加到 20 甚至 50。这里没有标准答案,完全看你想要的效果。

第三,串口输出的数据格式。SerialPlot 能自动识别逗号分隔的数值流,每一行数据对应一次采样周期。如果数据只有一列,SerialPlot 默认单通道;如果有多个通道,用逗号分隔即可。同时在打印时把电压值格式化成三位小数,避免超长数字占用带宽。

2.3 把代码跑起来:Thonny 运行与常见卡点

直接在 Thonny 里打开刚才的代码文件,点击工具栏上的绿色运行按钮,程序就会在 Pico 上执行。如果一切正常,你会看到 Thonny 的 Shell 窗口不断滚动输出类似这样的内容:

28672,1.445 28750,1.449 28690,1.446

旋动电位器,数字会同步变化。如果数字完全不动,或者只在 0 和 65535 两个极值附近跳变,有几种可能:

  • 电位器接线接错,中间抽头没有连到 GPIO26 —— 用万用表量一下引脚电压
  • 电位器本身损坏或接触不良 —— 换一个试试
  • Pico 引脚损坏 —— 换 GPIO27 或 GPIO28 重新接线

还有一点值得注意:当你用 Thonny 点击“停止”按钮后,Pico 上运行的 MicroPython 脚本会被中断,但如果你拔掉 USB 线再重新插上,程序并不会自动运行。要让代码在板子上电后自动运行,需要把文件保存为main.py。Thonny 里你可以用“文件 -> 另存为”然后选择“MicroPython 设备”,把文件名改为main.py即可。这样 Pico 一上电就会自动执行这段代码。

3. LED 控制与 PWM 渐变实现细节

3.1 为什么用 PWM 而不是直接高低电平

很多新手在控制 LED 亮度时想到的第一个方案是模拟调整电压,但实际上微控制器无法直接输出一个“可变的电压”来驱动 LED,PWM(脉宽调制)就是解决办法。PWM 技术通过固定频率、改变高电平在一个周期内所占的比例(即占空比)来等效改变输出的平均功率。LED 对这种快速开关的光信号存在视觉暂留效应,只要频率足够高,人眼感知到的就是亮度的变化。

用生活化类比来解释:你按电灯开关按得足够快,眼睛看起来灯的亮度就会介于亮和灭之间——PWM 就是把这个操作自动化了,以几千赫兹的频率快速切换电路的通断,从而等效控制亮度。

如果不用 PWM 而直接输出高电平,LED 除了“全亮”就是“全灭”,根本没法体现电位器旋转过程中的连续变化。所以 PWM 是这个项目的必然选择。

3.2 非对称映射:从 ADC 到 PWM 的三种映射策略

前面代码里我把filtered_u16直接赋值给duty_u16,这是一种线性映射:电位器最小 -> LED 全灭,电位器最大 -> LED 全亮。看起来没问题,但实际体验中可能会发现一个问题:旋钮在刚开始旋转时,LED 的亮度变化非常明显,但在高亮度区间变化反而感知不强。原因是人眼对亮度的感知不是线性的,而是接近对数关系。

所以如果想让亮度变化在视觉上更“均匀”,可以考虑用指数映射。代码改为:

# 将 0~65535 映射到 0~1,再取平方 normalized = filtered_u16 / 65535.0 brightness = int((normalized ** 2) * 65535) led_pin.duty_u16(brightness)

这样做的效果是:低亮度区间变化更细腻,高亮度区间变化更平缓,人眼感知就更均匀。类似的做法在手机屏幕的亮度调节中也广泛使用。

第三种映射是加入死区。当电位器旋转到接近两端极限时,ADC 值可能会有微小波动(比如 65535 会跳到 65400),虽然肉眼难察,但在某些精确控制场景下这个抖动会造成输出不稳定。可以加一个边界裁剪:

if filtered_u16 < 500: filtered_u16 = 0 elif filtered_u16 > 65000: filtered_u16 = 65535

这三种映射策略各有适用场景,你甚至可以做成按键切换模式,这样同一个项目就能演示多种思路,在写博客或者做分享时内容也会丰富很多。

3.3 PWM 频率选择的实际意义

代码里我用了 1000Hz 作为 PWM 频率,但这个选择并不随意。PWM 频率如果太低(比如 50Hz),LED 会明显闪烁,因为人类能感知到约 60Hz 以下的光闪烁;如果太高(比如 1MHz),虽然灯不闪了,但对于 MCU 来说意味着更高的中断负载,且 LED 驱动电路(如果有三极管/MOSFET)的开关损耗也会增加。1000Hz 是 LED 控制常见的安全区间,既不闪烁,也没必要往高了调。

如果你用的不是 LED 而是直流电机,PWM 频率可能需要提升到 10kHz 以上,因为电机线圈的感抗会平滑电流,低频率会造成明显的转速脉动和噪声。不同负载对 PWM 频率的要求差别很大,这一点是实际项目中设计者必须考虑的。

4. SerialPlot 串口波形采集实战

4.1 为什么串口数据要用上位机可视化

有时候你觉得代码逻辑明明是对的,但看 Shell 里那一串数字也看不出所以然。频率、范围、趋势、异常抖动,这些特征在波形图上一眼就能看出来,在纯数字列表里却要盯着看好久。对于传感器数据观测、控制参数整定、信号质量评估这类任务,串口波形工具几乎是刚需。SerialPlot 就是一款免费开源的串口数据可视化工具,支持多通道实时曲线、数据导出、实时缩放,完全满足嵌入式开发中的日常调试需求。

类似的工具还有 Arduino 自带的 Serial Plotter、Processing、Python Matplotlib 动态绘图等,但 SerialPlot 胜在开箱即用、交互流畅、不需要写任何前端代码。我推荐的组合是:Pico 串口输出数据 + SerialPlot 实时绘制,这套方案在我做传感器调试的时候帮了大忙。

4.2 SerialPlot 安装与连接配置

到 SourceForge 搜索 SerialPlot 即可下载安装包,Windows 版本是免安装的便携版,解压后直接运行 exe。打开之后界面比较简洁,主要分三个区域:连接设置区(端口、波特率)、数据曲线区、命令发送区。

连接配置步骤:

  1. 在 Thonny 中停止当前脚本(或者断开 Thonny 与 Pico 的连接),因为 Thonny 会占用串口,SerialPlot 就抢不到了
  2. 打开 SerialPlot,在端口下拉框里选择 Pico 对应的 COM 口
  3. 波特率选 115200
  4. 点击 Connect 按钮

这里有个操作顺序的坑:如果你在 Thonny 里运行着脚本,串口被 Thonny 占用,SerialPlot 是连不上的。所以要么用 Thonny 运行后立刻断开 Thonny 的串口连接(菜单“运行 -> 停止/重启后端进程”),要么更优雅的方案是用一个独立文件管理器直接把 main.py 烧进 Pico 里的方法运行,这样脚本在 Pico 上独立运行,串口资源就不会被 Thonny 抢占。

接好之后,SerialPlot 会自动识别数据流。默认情况下它会尝试识别一到两个通道,由于我们代码里输出的数据格式是数值,数值,SerialPlot 会自动识别为两个通道。曲线区会出现两条实时变化的曲线,其中一条是原始 ADC 值(0~65535),另一条是电压值(0~3.3)。两条曲线看起来形状完全一样,只是量程不同。你旋转电位器,两条曲线会同步起伏,LED 亮度也同步变化,整套系统就完整跑通了。

SerialPlot 中还可以配置各个通道的颜色、数据点样式、坐标轴范围。默认的自适应坐标轴比较复杂,有时候曲线会和上下边界贴合,可以手动把纵轴范围调到 0~70000,这样曲线就始终在中间位置浮动,视觉上更清晰。

4.3 采样率、串口波特率与数据吞吐量分析

任何串口调试都必须考虑一个底线问题:你的波特率能支撑多高的采样率?115200 波特率,默认 8N1 格式(8 数据位、无校验、1 停止位),每个字节实际传输需要 10 个 bit。所以有效传输速度是 11520 字节/秒。

在 50ms 采样周期下,每秒输出 20 次,每个数据行大约 10 到 12 个字符(数值加逗号加换行),每秒的数据量大约在 240 字节左右,波特率完全够用。但如果你把采样周期降到 1ms(即 1kHz 采样率),每秒 1000 行、每行 12 字节,就是 12KB/s,已经接近 115200 波特率的传输极限。这时候必须提高波特率到 921600,或者减少输出通道数量。

这里再说一个容易被忽略的问题:Pico 的 MicroPython 通过 USB CDC 虚拟串口通信时,底层枚举的串口速率设置看起来是 115200,但实际传输速度上限由 USB 协议决定,通常可以达到 1Mbps 以上。这意味着你可以用更高的波特率(比如 921600)而不必担心 USB 串口芯片的瓶颈。但如果你用的是外部 USB 转 TTL 模块连接 UART 引脚,那么必须严格按照芯片的波特率能力来。

4.4 数据可视化进阶:多通道对比与动态交互

SerialPlot 最有用的功能之一是它能同时绘制多个通道。这意味着你不只可以观察电位器原始数据,还可以同时观察滤波前和滤波后的数据,对比噪声抑制效果;或者同时观察 ADC 数据和 PWM 占空比输出,验证整个链路的一致性。

把滤波前后的数据一起发出来很简单,代码里多加一个变量:

print(f"{raw_u16},{filtered_u16},{voltage:.3f}")

波形图上就会出现三个通道,你能清晰地看到原始数据的毛刺被滤波后抹平的效果。数据可视化不仅能让你“看到”数据,更能帮你快速验证算法是否正确。给不懂代码的人展示成果时,波形图也远比数字列表更有说服力。

再进阶一步,SerialPlot 支持把数据保存为 CSV 文件,在菜单的 Logging 选项里可以设置保存路径。这样你在调试中采集到的数据可以离线导入 Python 或者 MATLAB 进一步分析。比如你正在采集一个传感器的响应曲线,先采集几百个点,再离线画出曲线、分析线性度,整个过程非常顺手。

5. 常见问题、坑点排查与扩展方向

5.1 实践中最容易踩的 5 个坑

第一,串口端口被占用。程序在 Thonny 里运行后,SerialPlot 连不上端口,或者反过来 Thonny 连不上。这是新手遇到最多的问题。解决思路其实很简单:串口同一时刻只能被一个程序占用。调试完代码以后,如果想要长期运行并配合 SerialPlot 使用,就把代码保存为main.py,然后完全断开 Thonny 的连接(甚至关掉 Thonny),再打开 SerialPlot 连接。

第二,ADC 数值跳变剧烈。这个问题常见于使用了较长的杜邦线连接电位器,或者电位器本身质量一般。解决方法是软件滤波(代码里已经实现),或者在硬件上并联一个 0.1uF 电容在 GPIO26 与 GND 之间,形成一阶 RC 低通滤波。

第三,LED 不亮或亮度不变。先用万用表测量 GPIO16 引脚在程序运行时的电压,旋动电位器看电压是否在 0~3.3V 之间变化。如果电压不变,说明代码里 PWM 赋值没有生效,多半是引脚号填错。

第四,串口乱码或数据显示不完整。检查 Thonny 的串口设置和 SerialPlot 的波特率是否一致。理论上来讲 MicroPython 的 print 输出默认走 USB CDC,波特率设置对 USB 虚拟串口几乎没有影响,但如果诡异问题不断,统一设置成 115200 通常能解决。

第五,电位器旋钮转到底时读数到不了 65535。这是正常现象,因为电位器自身的引脚电阻和接触电阻导致电压无法完全达到 3.3V。读数可能在 65000 左右,不影响功能。

5.2 参数调优经验与“手感”调整

这个看似简单的项目,其实有很多可以琢磨的调节空间。采样周期、滑动滤波窗口大小、PWM 频率这三个参数的组合直接影响系统表现。如果你希望系统响应更迅速,将time.sleep_ms(50)调小到 10ms,同时把滤波窗口减到 3;如果你希望显示更平滑,把采样周期保持 50ms、滤波窗口加到 30,这时曲线会非常顺滑,几乎没有毛刺。

我实际调过几组组合,这里给一个参考经验表:

需求场景采样周期滤波窗口PWM 频率体验效果
快速响应试验10ms3100HzLED 跟随旋钮几乎无延迟,波形毛刺较多
演示效果50ms101kHzLED 顺滑适中,波形干净
极致平滑100ms505kHz旋钮转动时 LED 有明显阻尼感,波形非常圆润

这三组方案我都实跑过,没有哪组是绝对正确的,关键是你想让这个系统呈现出什么样的“手感”。

5.3 这个方案还能往哪些方向扩展

这套 ADC 采集 + 串口可视化的基础框架,可以横向迁移到非常多的实际场景中。简单列几个我想到的扩展方向。

方向一:换成其他模拟传感器。比如光敏电阻(接在分压电路里)、NTC 热敏电阻、麦克风模块输出等,只要输出的是 0~3.3V 的模拟电压,就能直接接到 GPIO26~28 上,复用这套采集代码。

方向二:加入多通道采集。Pico 有 3 路 ADC,插上两个电位器和一路光敏电阻,代码里声明三个 ADC 对象,在循环里依次读取并打印,SerialPlot 上就会显示三条曲线。这可以用于对比不同传感器对同一物理量的响应差异。

方向三:结合 PID 控制。如果你把电位器当作目标值输入、把某个执行器的当前状态当作反馈值,ADC 采集到的数据就是 PID 控制器的输入信号。配合 SerialPlot 观察调节曲线,这是很多做平衡车、无人机、温控项目的玩家都在用的调试方式。

方向四:数据记录与离线分析。SerialPlot 可以保存 CSV 文件,拿到数据后可以用 Python 的 matplotlib 画出更专业的图表,也可以计算均值、方差、线性度等指标,用数据来验证你的硬件表现。

方向五:扩展到其他 MCU 平台。这套逻辑不仅适用于 Pico,STM32 的 HAL 库 ADC 采集、ESP32 的 analogRead、Arduino 的 analogRead,都遵循相同的原理:读取原始值 -> 换算实际电压 -> 滤波 -> 串口输出。换平台时只需要替换 API 调用,整体架构完全一致。

5.4 一点额外的经验心得

最后分享一个我在实际调试中的小体会:把 ADC 项目的成败标准定义为“能不能看到波形”其实是个很好的心态。如果 SerialPlot 上曲线不平滑,你就去调滤波参数;如果 LED 亮度变化不自然,你就去改 PWM 映射曲线;如果数据有周期性干扰,你就要找干扰源是不是来自电源纹波。这种“问题驱动”的调试方式,能把很多教科书上抽象的概念,比如采样率、量化误差、滤波、占空比,变成你亲手解决过的实际问题。很多工程上的直觉,都是在这样的循环里练出来的。这个项目虽然小,但它几乎包含了一个完整的“信号采集-处理-输出-反馈”链路的所有环节,值得耐心地做一遍,再按自己的需求改一遍,你会收获很多程序之外的东西。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 10:34:54

OpenHarmony跨端开发实测:RNOH TodoList渐变背景踩坑全记录

很多人一开始接触 OpenHarmony 应用开发时&#xff0c;第一个纠结的问题不是用什么架构&#xff0c;而是“我到底该用 ArkTS 写原生&#xff0c;还是用跨端框架”。我的看法很简单&#xff1a;如果你的团队已经有 React 技术栈沉淀&#xff0c;或者你后续要在多个系统上一套代码…

作者头像 李华
网站建设 2026/9/9 10:33:52

会议录音转文字工具怎么选?四款AI纪要工具实测对比

开选会议录音转文字工具那阵子&#xff0c;我差点被参数表逼疯。各家都说自己识别准、功能全、有AI&#xff0c;但真拿一段40分钟的周会录音扔进去&#xff0c;出来的东西差距能大到让你怀疑人生。用了大半个月&#xff0c;把飞书妙记、讯飞听见、通义听悟、腾讯会议AI小助手这…

作者头像 李华
网站建设 2026/9/9 10:33:43

UKF无迹卡尔曼滤波在线参数辨识实战:锂电池一阶RC模型

做电池管理系统、电机控制或者任何“模型里带未知参数”的工程&#xff0c;大概率都经历过一个尴尬阶段&#xff1a;模型方程写得明明白白&#xff0c;但参数要么拿不准&#xff0c;要么跑着跑着就漂了。电池内阻随温度、SOC、循环次数变化&#xff0c;电机电感电阻随工况漂移&…

作者头像 李华
网站建设 2026/9/9 10:32:27

多功能ALU部件设计实战:从Verilog仿真到FPGA上板验证的完整复盘

数字逻辑与部件设计这门课的第十二个任务&#xff0c;现在初赛阶段终于告一段落。说实话&#xff0c;交板子那一刻心态很复杂&#xff0c;既有“总算把功能跑通”的松快&#xff0c;也清楚后面还有一堆优化和扩展等着做。这轮做的是一位多功能算术逻辑运算部件&#xff0c;简称…

作者头像 李华
网站建设 2026/9/9 10:31:19

国产FPGA管脚兼容替代Xilinx Artix-7实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 10:30:25

宽度对比自动化实战:基于Playwright的视觉回归测试方案

这两年做自动化测试&#xff0c;越来越觉得行业里有个挺有意思的现象&#xff1a;大家张口闭口都在谈自动化&#xff0c;但真正把"自动化"当成一个系统性工程来对待的人&#xff0c;其实并不多。就拿我最近在搞的这个"宽度对比&#xff08;自动化&#xff09;&q…

作者头像 李华