🍓 第九章 Raspberry Pi Pico 开发板与 MicroPython 语言
📄 一句话概括

machine 三件兵器(Pin/PWM/ADC)实战:数字输出、按键输入、调光、读模拟量——第七章在树莓派上干过的事,这里用另一套更贴近硬件的 API 再干一遍,最后合成【电位器控灯】闭环。

📝 本节和前面几节的关系

7-3(数字输入输出)、7-4(PWM 调光)、7-5(模拟输入)在树莓派上用 gpiozero 做过——gpiozero 的思路是【LED、Button 这些高级对象替你包好】;本节的 machine 是反面:只有 Pin、PWM、ADC 这类裸对象,逻辑全要自己写。对比完你会发现【抽象层高=好写、贴近硬件=好懂】。8-5 的串口知识在 MicroPython 里对应 machine.UART(本节点到为止)。9-3 已把 Thonny 链路打通,本节全部实验都能落地。

一、数字输出:machine.Pin 三行起步

from machine import Pin
import time

led = Pin(15, Pin.OUT)      # GP15 做输出(接一颗 LED + 220Ω 电阻,接法同 7-3)
led.on()                    # 拉高 3.3V
led.off()                   # 拉低
led.value(1)                # on/off 的通用写法,1=高 0=低

和 gpiozero 对照(7-3 的知识搬过来):gpiozero 是 led = LED(17) 然后 led.on()——连输出方向都不用声明;machine.Pin 必须显式写 Pin.OUT 或 Pin.IN。少一层抽象,多一分明白:方向、电平,原来都是自己一句话一句话定的。

二、数字输入:上拉电阻要自己开口要

button = Pin(14, Pin.IN, Pin.PULL_UP)   # GP14 做输入,启用内部上拉

while True:
    if button.value() == 0:    # 按下=接通 GND=读到 0
        led.on()
    else:
        led.off()

三件事和 7-3 完全同理,但都要自己写:

三、PWM:duty_u16 的十六位世界

from machine import Pin, PWM

pwm = PWM(Pin(15))
pwm.freq(1000)              # 1kHz —— 人眼看着不闪的最低舒适频率(7-4 的知识)

pwm.duty_u16(32768)         # 半亮度:占空比 32768/65536 ≈ 50%
pwm.duty_u16(0)             # 全灭
pwm.duty_u16(65535)         # 最亮

duty_u16 是 16 位占空比:0 ~ 65535(u16 = unsigned 16-bit)。换算口诀:

平均电压 = 3.3V × duty_u16 ÷ 65535 —— 7-4 的公式原样成立,只是刻度从 gpiozero 的 0~1 换成了 0~65535。 想沿用 0~1 的手感:pwm.duty_u16(int(value * 65535))。

用完记得释放(单片机内存金贵,9-2 说过):pwm.deinit()。

四、ADC:Pico 自带,这次不用买芯片

7-5 的最大痛点在这里消失——树莓派读模拟量要外接 MCP3008,Pico 芯片里就有 3 路 12 位 ADC(GP26/GP27/GP28):

from machine import Pin, ADC

pot = ADC(Pin(26))          # 电位器中间脚接 GP26,两端接 3V3 和 GND

raw = pot.read_u16()        # 返回 16 位数 0~65535(内部 12 位折算上来)
voltage = raw / 65535 * 3.3 # 换算成电压
print(raw, round(voltage, 2))

两个刻度要分清:内部 ADC 是 12 位(0~4095),但 read_u16() 把它折算到 16 位刻度(0~65535)返回——统一刻度方便和 PWM 对接。换算电压时用 65535 做分母(对着返回值算),别用 4095。

闭环就用一行(电位器控灯亮度,7-5 末尾那个项目的 MicroPython 版):

pwm.duty_u16(pot.read_u16())   # ADC 和 PWM 刻度天然相同,直接对接!

五、定时与串口:认识两个名字

六、老教程里已失效的写法(这一节防坑值最高)

MicroPython 和 Pico 硬件这几年换代,老书老博客里这几处照抄必挂:

  1. ⚠️W 型号上 Pin(25) 控制不了板载 LED——Pico W/Pico 2 W 的 GP25 接的是无线芯片,不是灯!正确写法: python led = Pin("WL_GPIO0", Pin.OUT) # W 型号的板载灯 # 或新版固件:from machine import LED; led = LED("WLED") 老教程的 Blink 十有八九栽在这里——代码能跑、灯不亮,还不报错。
  2. adc.read() 已废弃——老代码的 read()(返回 12 位)被 read_u16() 取代;对照读两份资料时数字差 16 倍就是栽在这。
  3. duty() 与 duty_u16() 是两套刻度——duty() 是 0~1023(10 位),duty_u16() 是 0~65535。老教程写 duty(512)【半亮】,直接搬进新代码要写 duty_u16(32768)。
  4. 固件版本看官方页——老书印的版本号一律以 micropython.org/download 当前稳定版为准(当前 v1.28)。

七、动手 Demo:电位器调灯——三个兵器连成一条闭环

接线三根(对照 7-5 的接法,但这次不用买任何芯片):

电位器脚 接到
两端的两个脚 3V3 / GND
中间脚 GP26
LED 阳极(长脚) GP15(串 220Ω 电阻到 GND)

程序:

from machine import Pin, PWM, ADC

pot = ADC(Pin(26))
pwm = PWM(Pin(15))
pwm.freq(1000)

while True:
    duty = pot.read_u16()          # 读模拟量(ADC 兵器)
    pwm.duty_u16(duty)             # 输出亮度(PWM 兵器)
    print("duty =", duty)          # Thonny Shell 里看数值变化

看到什么算成功:拧电位器,灯从灭到最亮平滑变化,Shell 里 duty 数值跟着从 0 附近爬到 65535 附近。

读结果:

八、30 秒实验:算占空比与电压

拧电位器让 Shell 显示 duty = 20000:

  1. 灯的平均电压是多少?
  2. 这相当于 gpiozero(0~1 刻度)里的 value 多少?

参考答案:1. 3.3 × 20000 ÷ 65535 ≈ 1.01V(按 7-4 的公式代入 16 位刻度)。2. 20000 ÷ 65535 ≈ 0.31——如果你手边有树莓派,把这个 0.31 填进 7-4 的 PWMLED.value,两块板亮度应该几乎一样。

九、常见误区

  1. 【用树莓派的 BCM 号找 Pico 的针】 —— Pico 用 GP 号(9-1 的坑),接线看板子丝印。
  2. 【W 型号上跑 Blink 教程灯不亮,以为板子坏了】 —— W 型的 GP25 接的是无线芯片!用 Pin("WL_GPIO0") 或 LED("WLED")。
  3. 【read_u16() 读到 65535 是坏了】 —— 那是满量程(电位器拧到头、输入 3.3V);读到 0 是另一头。中间乱跳才是真的有问题(检查接线)。
  4. 【duty 与 duty_u16 随便用】 —— 两套刻度差 64 倍(0~1023 vs 0~65535),照抄老代码亮度会全乱。
  5. 【Pico 也要像树莓派那样外接 ADC 芯片】 —— 不用!3 路 12 位内置(GP26~GP28),这是它对比树莓派最直接的优势。
自测三问(点开对答案) 1. `machine.Pin` 的输入模式为什么要写 `Pin.PULL_UP`?gpiozero 里呢? 2. `duty_u16(16384)` 大约是几成亮度? 3. 读模拟量该用哪个针脚、哪个类? **参考答案** 1. 不写上拉,输入脚是**浮空**的、读数乱跳。gpiozero 的 `Button` **默认带内部上拉**,`machine.Pin` 必须**显式写**——抽象层的差异就在这类地方。 2. **16384 ÷ 65535 ≈ 0.25,约四分之一亮度**,平均电压约 0.83V(3.3 × 0.25)。 3. **GP26/GP27/GP28 三选一**,用 `machine.ADC` 类;`read_u16()` 取 16 位值,电压 = 值 ÷ 65535 × 3.3。
📄 第九章读完了,回头看这条线

9-1 认识它(家族里的【另一种东西】)→ 9-2 掌握它的语言(语法不变、环境全新)→ 9-3 打通工具链(Thonny 一个软件管两头)→ 9-4 亲手控制它(三件兵器重建第七章的闭环)。 走完这一章,你手里那套【分工明确的小系统】又多了一个成员:树莓派负责【想】、Arduino 负责【扛造的实时】、Pico 负责【会 Python 的实时+自带 ADC】。 回头看 9-1 埋的那句【别和树莓派混——Pico 自带 ADC】:7-5 要买芯片才能做的事,Pico 出厂就会——这就是【按需选板】最直观的一课。 下一章按教材顺序,等波仔报标题。

相关笔记