"硬件控制"系列开篇,我打算用树莓派Pico这块小板子来聊。你可能听过树莓派,但Pico和他们家那台信用卡大小的电脑完全是两码事——Pico是一块微控制器开发板,只有单片机级别的算力,干不了跑系统、看电影这种活,但它能做的是直接和硬件打交道:读传感器、点灯、驱动舵机、控制电机。价格便宜、资料齐全、入门门槛低,是我首选推荐给新手用来做硬件控制的板子。
这篇文章适合零基础刚接触嵌入式的人,也适合玩过Arduino但想换换口味的老手。我会从Pico到底是个什么东西讲起,拆一下它的外设资源,再带着你搭建环境、点亮第一颗LED,最后用舵机控制把PWM和电源这两个硬件控制里最关键的环节讲透。内容不追求高深,但每一步都能落到实际操作上。
1. 为什么硬件控制入门,我首选Pico
1.1 先从“它不是树莓派”讲起
很多人第一次听到Pico,第一反应是“树莓派出了个廉价版?”其实完全不是。树莓派那类单板计算机运行的是完整操作系统,本质上是一台小电脑,适合跑程序、做服务器、搞AI推理;而Pico属于微控制器(MCU),出厂时里面是空白的,你用USB线把固件烧进去,它才按照你写的代码去控制引脚。
这块板子的核心是RP2040芯片,双核Arm Cortex-M0+处理器,主频133MHz,264KB的SRAM,2MB板载Flash。光看参数可能没啥概念,但你要知道,微控制器领域很常见的Arduino Uno用的芯片主频只有16MHz,RAM只有2KB。Pico的定位就是给你一片“比入门级强不少,但依然简单直接”的控制核心。
Pico最有意思的地方还不是性能,而是它底下那两排针脚。26个GPIO(通用输入输出引脚)几乎都支持多种复用功能:数字输入输出、PWM、I2C、SPI、UART,还有3个ADC模拟采样通道。这意味着你手里这一块小板子,传感器、舵机、显示屏、通讯模块基本都能接,硬件控制的几大类应用在这块板子上都能练一遍。
1.2 Pico系列怎么挑:普通版、W版、Pico 2
Pico已经出了好几个型号,新手很容易挑花眼。我直接给你列个对比表,按需求选就行。
| 型号 | 主控芯片 | 主频 | 无线能力 | 适合场景 |
|---|---|---|---|---|
| Pico | RP2040 | 133MHz | 无 | 纯本地硬件控制、低成本教学项目 |
| Pico W | RP2040 | 133MHz | Wi-Fi 4 + 蓝牙5.2 | 需要联网上报数据、手机远程控制 |
| Pico 2 | RP2350 | 150MHz | 无 | 算力更强的本地控制、跑复杂协议 |
| Pico 2 W | RP2350 | 150MHz | Wi-Fi + 蓝牙 | 想兼顾性能和无线功能的项目 |
很多人在普通版和W版之间纠结。我的建议是:如果项目里完全没有联网需求,买普通版就够了,省十几块钱不说,还能少一个无线模块的功耗和配置麻烦。反过来,如果你已经能预见到项目要往物联网方向走,比如温湿度数据要传到手机上看,直接上Pico W,不用后面再换板子。
至于Pico 2,用的是新一代RP2350芯片,主频更高,还做了架构升级(双核Cortex-M33,也可以切换成RISC-V核心)。网上偶尔会有人讨论2026年会不会有新款的Pico,我没有内部消息也不会瞎猜,但从芯片迭代节奏看,现在买Pico 1或者Pico 2都不会亏,这个系列的引脚和编程接口保持了很好的兼容性,中途升级板子基本不用重写代码。
1.3 Pico vs Arduino vs ESP32:三选一怎么决策
硬件控制入门绕不开这三个名字,选错平台会走很多弯路。我三块都用过,说点实际感受。
Arduino最大的优势是生态极度成熟,网上教程多到看不完,很多传感器都有现成库,函数封装得特别简单。但它的短板也很明显:单片机本身资源少,跑复杂程序吃力,还有官方板子的价格不太友好。对于想系统学习硬件原理、而不是只做拼积木式项目的人,Arduino有时候反而太“傻瓜”了,把底层都藏住了。
ESP32性能强,自带Wi-Fi和蓝牙,价格也不贵,看起来是万能选手。但它的坑在于工程环境比较复杂,外设资源虽然多,出问题时不那么好排查,对纯新人不太友好。而且ESP32的很多模块是5V容忍的,跟3.3V传感器配合时需要额外注意电平转换。
Pico正好卡在一个舒服的位置:硬件文档极其透明,数据手册和官方示例质量高,编程可以用MicroPython快速验证想法,也能用C SDK深入底层。我在实际项目中用它做过小型机械臂控制、土壤湿度监测和桌面气象站,都能稳定跑很久。所以我现在带人入门硬件控制,第一块板子都推荐Pico,逻辑清晰、出问题容易定位,等把基础打牢了,再转ESP32做联网项目就是两天的事。
2. Pico的硬件底子:能控哪些东西
2.1 GPIO:数字输出/输入和复用功能
GPIO是硬件控制最基础的动作。Pico的26个GPIO可以配置成输入或者输出:输出模式就是让引脚输出高电平(3.3V)或低电平(0V),可以点亮LED、控制继电器;输入模式就是读取引脚上的电平是高还是低,可以接按键、接传感器数字输出。
但Pico的GPIO不是普通数字口那么单一,它旁边有个“复用”概念。每个引脚除了当作普通IO,还能被切到硬件外设的专用功能上。比如GPIO0不仅能做数字IO,还能切到I2C的SDA、UART的TX、PWM通道A等。这意味着你不用像某些芯片那样为每个功能预留独立引脚,一个引脚可以按需多职兼任。
新手最容易混淆的是引脚编号。Pico板子物理上有40个引脚,两排各20个,但GPIO编号并不是从1到26连续排列,中间夹杂着电源、地和几个特殊引脚。比如物理引脚1对应的是GPIO0,但物理引脚4是3V3电源,物理引脚5对应GPIO2……一旦接错,代码写对了也没反应。我自己的习惯是,每次接线前先看一眼丝印,用万用表测一下确认,再动手。
提示:Pico的引脚是3.3V逻辑电平,绝对不能用5V直接灌到GPIO上。虽然有些引脚标注了“耐5V”或“容忍I2C”,但不是所有引脚都这样,新手最好的做法是默认所有引脚都只能接3.3V信号。
2.2 ADC:把模拟电压变成数字量
数字IO只能分辨0和1,但很多传感器输出的是连续变化的模拟电压,比如电位器、光敏电阻、土壤湿度传感器。这时候就需要ADC(模数转换器)把电压值读进芯片。
Pico上有3个对外可用的ADC通道(ADC0到ADC2),ADC3被板载的温度传感器占用了。ADC的精度是12位,也就是把0到3.3V的电压范围用0到4095的数字来表示,分辨率大约是0.8毫伏。举个例子,如果一个光敏电阻分压后输出1.65V,你读到的ADC值就接近2048。
读取ADC的代码很简单,MicroPython里几行就能跑:
from machine import ADC, Pin light = ADC(Pin(26)) # ADC0 对应 GPIO26 value = light.read_u16() # 返回0~65535之间的数值 print(value)这里有个容易踩的坑:GPIO的编号和ADC通道的编号不一样。ADC0对应GPIO26,ADC1对应GPIO27,ADC2对应GPIO28,很多人按ADC通道号去Pin()里写数字,结果找不到引脚,半天没反应过来。用之前先在本子上记一下对应关系,能省很多时间。
ADC的输入电压范围是0到3.3V,如果要测更高电压或者真实世界里的分压信号,记得先加电阻分压或运放跟随器,直接怼上去大概率会烧引脚。
2.3 PWM:电机、舵机、调光的核心
PWM(脉冲宽度调制)是硬件控制绕不开的关键技能。简单说,它不是让引脚一直输出高或低,而是飞快地在高低电平之间切换,通过调整“高电平占一个周期的时间比例”来控制设备的等效功率。
想象一个开关:如果你以极快的速度开关灯,人眼看到的不是闪烁,而是“变暗了”。PWM就是这个原理,只不过频率通常高到设备都感觉不到断续。Pico的PWM功能很强,最多支持8路PWM通道,而且每一路都可以独立设置频率和占空比,驱动多个电机或者多路LED互不干扰。
MicroPython里配置PWM很直观:
from machine import Pin, PWM led_pwm = PWM(Pin(25)) # 板载LED led_pwm.freq(1000) # 设置频率为1kHz led_pwm.duty_u16(32768) # 占空比设为50%,范围0~65535占空比、频率、分辨率这几个概念刚接触时有点绕,但它们是硬件控制的基本功。占空比决定“够不够劲”,频率决定“切得多快”,分辨率决定“控制得多精细”。后面舵机控制的PWM,就是把这套机理玩到极致的一个经典场景。
2.4 I2C/SPI/UART:和外设模块“对话”的三种语言
硬件控制不只是点灯读传感器,很多功能模块(OLED屏、加速度计、GPS模块、存储器)需要按协议和主控交换数据。Pico把这些接口都开放出来了,最常见的三种分别是I2C、SPI和UART。
I2C只需要两根线(SDA和SCL),可以在一根总线上挂多个设备,每个设备有独立地址,像门牌号一样区分。适合小数据量、多设备的场景,比如OLED屏幕、温湿度传感器、气压计都常用I2C。Pico上I2C用的引脚可以软件配置,通常我会选在GPIO4/GPIO5上。
SPI速度比I2C快,但需要4根线(MOSI、MISO、SCK、CS),适合大数据量的外设,比如SD卡、TFT屏幕、高速ADC。UART则是串口通信,两条线(TX、RX)即可,最常用于调试输出和与GPS、蓝牙模块通信。
选哪种接口不只看速度,还要看外设模块设计时默认支持什么。我接模块前的习惯是,先去查模块的手册,确认它的通信方式,再决定用Pico的哪组引脚。有一个小技巧:Pico的I2C和SPI引脚是可以重映射的,在代码里指定Pin编号就行,不用焊跳线换物理位置,这个灵活性比Arduino舒服很多。
3. 零基础搭建Pico开发环境
3.1 选MicroPython还是C SDK
Pico支持两种主流开发方式:MicroPython和C/C++ SDK。新手入门,我强烈建议先走MicroPython路线。
MicroPython是Python语言在嵌入式平台上的精简实现,语法和PC上的Python几乎一样,最大的好处是写代码即时生效,不需要编译、烧录版本号那些繁琐流程,改一行保存一行就能看到效果。用MicroPython学硬件控制,能把注意力集中在“引脚接对没有、逻辑对不对”上,而不是纠结编译报错。
C SDK的优势是极致性能、底层控制力强,适合做产品级开发或者对时序要求苛刻的项目。但需要搭建编译工具链,调试流程也复杂不少。我的建议是:前三个月老老实实用MicroPython,等把GPIO、PWM、ADC这些都玩明白了,再学C SDK,你会发现自己对底层的理解完全是另一个层次。
3.2 烧录固件的完整步骤(BOOTSEL法)
MicroPython并不是Pico出厂自带的,你需要先通过USB往芯片里烧一段固件。Pico的设计让这个操作非常简单,完全不需要额外的下载器,方法如下:
- 先从树莓派官网下载MicroPython固件(.uf2格式文件),注意区分Pico 1和Pico 2的固件,文件名里都有标明,下错了会烧录失败。
- 按住Pico板子上的BOOTSEL按钮不要松手。
- 用USB线把Pico连接到电脑。
- 松开BOOTSEL按钮,电脑上会出现一个名为“RPI-RP2”的可移动磁盘。
- 把下载好的.uf2文件直接拖进这个磁盘,拖完磁盘自动消失,Pico自动重启,固件烧录完成。
整个过程就是“把文件拖进U盘”这么简单。烧录完成后,Pico再次连接电脑时,会以串口设备的形式出现在系统里,这就是你后续交互的通道了。
一个很容易被忽略的坑:BOOTSEL模式只在按住按钮上电的那一瞬间生效。如果你已经用USB线连着电脑,想重新进BOOTSEL模式,需要先拔线,按住按钮再插线,不能只按按钮就进去。我第一次用的时候傻傻按了好几秒没反应,后来才发现要重新插拔USB线。
3.3 点亮板载LED:第一个能跑的硬件控制程序
环境搭好以后,写一个点灯程序是硬件圈的“Hello World”,虽然简单,但能验证整个链路(固件、编辑环境、串口通信)是否正常。
我习惯用Thonny这款免费IDE来写MicroPython程序,它对Pico的支持很完整,打开就能看到代码编辑区和REPL交互区。连接Pico后,在编辑器里写:
from machine import Pin import time led = Pin(25, Pin.OUT) # 板载LED对应GPIO25 while True: led.toggle() # 翻转电平 time.sleep(0.5) # 延时0.5秒保存为main.py,然后运行,你会看到板载LED以每秒1次的频率闪烁。这里注意,Pico板上那颗绿色LED对应的是GPIO25,不是物理引脚25,也不是GPIO编号25附近的那排针脚——它只在板子内部连到了芯片的GPIO25,物理引脚上你是碰不到的。很多初学者在引脚表里找半天找不到“LED”引脚,因为这个LED本来就没引出来。
一旦LED按预期闪烁,说明你的开发链路已经畅通了。接下来才算真正进入硬件控制的核心玩法。
4. 拿舵机练手:理解PWM和电源这两件大事
4.1 舵机为什么只听50Hz的脉冲
舵机是硬件控制项目里出现频率最高的执行器之一,从机器人关节、摄像头云台到车船模型方向控制,全靠它。绝大多数入门舵机(比如SG90)的控制方式叫“脉冲位置控制”,它的本质是:舵机内部有一个电位器反馈当前角度,控制芯片根据输入脉冲的宽度来判断目标角度,然后驱动电机转到对应位置。
为什么是50Hz?因为标准舵机的控制周期是20毫秒,也就是50Hz。在这个周期内,脉宽(高电平持续的时间)决定了目标角度,典型对应关系是:
| 舵机角度 | 脉宽 |
|---|---|
| 0度 | 0.5毫秒 |
| 90度 | 1.5毫秒 |
| 180度 | 2.5毫秒 |
如果给舵机输入1.5毫秒的脉宽,它就会转到中位90度并保持。舵机的“保持”不是死死锁住,而是不断根据脉宽误差修正位置,所以只要PWM信号不断,舵机就会一直维持角度。
新手一上来容易思考一个问题:既然是20ms周期,能不能用普通GPIO做延时来模拟?理论上可以,但极度不推荐。因为普通延时无法保证精确时序,而且一旦程序被其他任务卡住,脉宽就会漂移,舵机会颤抖甚至误动作。用硬件PWM通道才是正确的做法。
4.2 SG90舵机控制代码:频率、脉宽换算
用Pico控制SG90舵机的接线很简单:舵机有三根线,红色接电源正极,棕色接GND,橙色(或黄色)接Pico的一个GPIO引脚,我这里选GPIO0。
MicroPython的PWM设置中,duty_u16的值和脉宽的换算关系要自己算一下。我说下计算逻辑:duty_u16的范围是0到65535,对应占空比0%到100%。在20ms周期下,2.5ms的高电平占一个周期的比例是2.5/20=12.5%,也就是65535乘以0.125,约等于8192。同理,0.5ms脉宽对应的值是1638。
代码这么写:
from machine import Pin, PWM servo = PWM(Pin(0)) servo.freq(50) # 周期20ms def angle_to_duty(angle): pulse_ms = 0.5 + (angle / 180) * 2.0 # 0.5ms~2.5ms duty = int(pulse_ms / 20 * 65535) return duty servo.duty_u16(angle_to_duty(0)) time.sleep(1) servo.duty_u16(angle_to_duty(90)) time.sleep(1) servo.duty_u16(angle_to_duty(180)) time.sleep(1)跑起来你就能看到舵机依次转到0度、90度、180度。这里的关键思路是:频率决定了周期,脉宽决定了角度,而MicroPython只给了你占空比这个旋钮,所以你先把脉宽换算成占空比,再去设值。把公式记下来,后面做云台、机械臂都是一样的套路。
4.3 千万别忽略的电源问题:Pico到底能不能直接带舵机
这一步是最多人翻车的环节,我必须单独拎出来讲。SG90舵机在正常转动时电流大约在100到200毫安,但堵转(被卡住)瞬间电流可能飙到六七百毫安。Pico板载的3.3V稳压电路一般建议只带300毫安以内的负载,一旦舵机启动或堵转,靠Pico直接供电很容易把板子的电源拉垮,轻则舵机抽搐、Pico重启,重则损坏稳压芯片。
正确的接法是这样的:舵机的电源单独从外部供电取,5V或者4.8V都可以,舵机的地线要和Pico的地线连在一起,信号线接入Pico的GPIO引脚。注意“共地”是必须的——如果Pico和舵机电源各自独立却不连地,信号电平就没有统一的参考点,舵机根本没法稳定工作。
我用过一个比较稳的省心组合:外接一个5V、至少1A的电源适配器或锂电池,舵机电源接外部5V,Pico用USB供电,两个地接一起。这样Pico只管发信号,舵机只管吃外部电源,互不干扰,实测跑一整天也没出问题。
注意:不要试图用Pico的3V3引脚给5V舵机供电。3.3V虽然可能让舵机勉强动一动,但已经是欠压状态,扭矩不足、抖动、发热都是家常便饭。
4.4 实测定标:为什么我的舵机转不到180度
很多人在舵机测试时发现,代码写了180度,实测只能转到160多度,或者反向不太线性。这不是代码错了,而是舵机本身的物理限制和PWM精度问题。
市面上的SG90舵机用的是模拟舵机方案,它的内部电位器标定范围一般在0.5ms到2.4ms左右,超过2.4ms之后的脉宽变化,舵机内部已经饱和,不会再继续转动。而且不同品牌、不同批次的舵机,中位脉宽和满刻度脉宽可能有细微差异。解决方法是给舵机做一次“实测标定”:写一段程序让脉宽从1ms逐步增加到2.5ms,每步停顿一秒,观察舵机实际停在哪里开始打滑、哪里完全不动,记录下极值对应的duty_u16,然后把角度换算公式里的上下限改成你的实测值。
这个习惯非常重要。你在网上抄的舵机代码多半用0.5~2.5ms,但每只舵机都有一点个体差异,不做标定就直接用到项目上,轻则角度不准,重则顶到机械限位烧电机。我会专门写一个标定用的测试程序,每次拿到新舵机先测一轮,时间成本不超过五分钟,换来的却是整个项目稳定性的巨大提升。
5. 坏板子多半不是被烧坏的:常见问题排查
5.1 电脑不识别Pico怎么办
这是新手遇到最多的第一个坎。刚把Pico插到电脑上,系统没反应、设备管理器里也找不到,整个人就慌了。绝大多数情况不是板子坏了,而是下面三个原因:
第一,USB线只能充电不能传数据。现在很多USB线是充电专用线,里面没有数据线芯,接上去Pico会亮灯但电脑认不到。找一根手机数据线,换着试,往往立刻解决。
第二,没有正确进入BOOTSEL模式。再次强调操作顺序:按住BOOTSEL按钮不放,然后插入USB线,等待2秒再松手。如果你先插线再按按钮,是进不去的。
第三,MicroPython固件已经烧录,设备在系统里显示为串口而不是U盘。打开设备管理器,在“端口(COM和LPT)”下面找找,能看到一个带COM编号的设备就是它了。这时候用Thonny连接,选择对应COM口即可。
5.2 舵机抖动、乱转怎么查
舵机抖动或乱转,原因不外乎以下几种:脉宽信号不稳定、电源不足、地线没共地、PWM频率不对。
如果舵机以肉眼可见的频率抖动,先量一下电源电压,看是不是被拉低到4V以下。我见过不少项目,用劣质USB供电带动两三个舵机,一启动电压就跳水,舵机当然抖。把外部电源换成电流余量大的,抖动通常立刻消失。
如果乱转,则要检查信号线是不是接在PWM能力的引脚上。Pico虽然几乎所有GPIO都支持PWM,但MicroPython里创建PWM对象时要确保引脚编号没有写错。还有一个隐蔽问题:舵机的信号线没有插紧,或者用了过长的杜邦线,信号毛刺会导致舵机误判脉宽。
5.3 引脚电压理解错误:3.3V设备的兼容性红线
Pico是3.3V逻辑器件,但很多传感器模块(尤其是老的超声波模块、5V继电器模块)是5V逻辑。直接把5V模块的输出接到Pico的GPIO上,如果该引脚不耐5V,轻则读到的电平永远是高,重则烧毁引脚。
解决思路是电平转换。最简单的办法是选用明确标注“3.3V兼容”的模块;如果必须用5V模块,在信号线上加一个分压电阻(比如1k对2k)把5V降到3.3V左右,或者用专用的电平转换模块。反过来,Pico输出3.3V高电平去驱动5V的TTL设备,很多设备也能识别,但要看具体模块手册的输入高电平阈值,别想当然。
5.4 新手最容易踩的5个坑(速查表)
| 坑点 | 现象 | 处理办法 |
|---|---|---|
| 把Pico当成树莓派电脑板 | 接显示器无画面、以为板子坏了 | 认清它是微控制器,程序通过USB烧录,不做视频输出 |
| 引脚编号搞混 | 代码写对但外设没反应 | 接线前查引脚图,区分物理引脚号和GPIO编号 |
| 5V信号直接接入GPIO | 引脚损坏、模块读取异常 | 默认所有引脚不接5V,必要时做电平转换 |
| 舵机由Pico直接供电 | 板子重启、舵机抖动 | 外部电源单独供电,GND共地 |
| 忘记共地 | 信号不稳定、外设失控 | 所有模块电源地和Pico的地必须汇总到同一点 |
以上这些坑,我基本都亲自踩过一遍。你可能会问,为什么教程总是讲“能怎么做”,但实际项目的失败案例里,“没共地”“供电不足”这些看起来很低级的错误占了大多数。原因其实很简单,硬件控制就是一连串细节的叠加,任何一个环节掉了链子,系统都不会按你预期工作。
最后给个我个人的经验:买Pico时建议一次买三块,一块专门用来试验和写代码,万一接错线烧掉,手边还有备用的。你会在后面的实验里发现,多一块备用板子比任何调试仪器都让人安心。