4、Python在嵌入式中的基础:MicroPython与标准Python的区别、嵌入式Python环境搭建、GPIO与PWM控制实战

各位同学好,我是老张。今天咱们聊聊嵌入式AI里最基础也最绕不开的话题——Python在嵌入式环境下的那些事儿。

说实话,我刚开始做嵌入式开发时,用的还是C语言。后来MicroPython冒出来,我第一反应是:这玩意儿能跑在单片机上?别开玩笑了。直到有一次项目工期紧,客户非要一周出原型,我硬着头皮上了MicroPython……嗯,真香。

4.1 MicroPython与标准Python的区别

先说说最核心的问题:MicroPython和咱们平时用的Python到底差在哪?

说白了,MicroPython就是Python的一个精简版。它专门为资源受限的嵌入式设备设计的。你想想看,一个标准的Python解释器动辄几十MB,而MicroPython压缩后只有几百KB。这中间的取舍,你懂的。

对比项 标准Python (CPython) MicroPython
内存占用 通常 > 50MB 约 256KB - 1MB
标准库支持 完整(os, sys, json等) 精简版(部分库需自行移植)
硬件控制 需通过第三方库(如RPi.GPIO) 内置 machine 模块,直接操作寄存器
浮点运算 软件浮点,精度高 可选硬件浮点,速度更快但精度略低
多线程 支持 threading 模块 仅支持 _thread 模块(有限制)
文件系统 完整文件系统 FAT12/16,空间有限

我在项目中遇到过最典型的坑就是:把标准Python的代码直接复制到MicroPython里跑,结果报错说模块找不到。后来学乖了,写代码前先查一下MicroPython的兼容性列表。

核心差异总结:

  • MicroPython没有完整的标准库,比如 numpypandas 这些就别想了
  • 硬件控制是MicroPython的强项,machine.Pinmachine.PWM 直接操作寄存器
  • 内存管理要更小心,我见过有人用列表推导式一次性生成10000个元素,直接把ESP32搞崩了

4.2 嵌入式Python环境搭建

环境搭建这事儿,说简单也简单,说复杂也复杂。我建议你按这个流程来,能少走不少弯路。

4.2.1 硬件准备

我个人习惯用ESP32作为入门板子。为什么?便宜、性能够用、社区活跃。你买个NodeMCU-32S,也就二三十块钱。

4.2.2 固件烧录

第一步,下载MicroPython固件。去MicroPython官网,找到ESP32对应的.bin文件。

第二步,用esptool.py烧录。命令如下:

# 安装esptool
pip install esptool

# 擦除原有固件
esptool.py --port COM3 erase_flash

# 烧录MicroPython固件
esptool.py --chip esp32 --port COM3 write_flash -z 0x1000 esp32-20220618-v1.19.1.bin

注意:端口号要根据你的实际情况改。Windows上是COM口,Linux/macOS上是/dev/ttyUSB0之类的。

我曾经踩过的坑:

烧录时忘记按住ESP32的BOOT键,结果一直连不上。后来才发现,有些开发板需要手动进入下载模式。具体操作:按住BOOT键,按一下EN键,松开BOOT键。嗯,这个动作我练了十几次才记住。

4.2.3 连接与测试

烧录完成后,用串口工具连接。我推荐用PuTTY或者Thonny IDE。Thonny自带MicroPython支持,用起来很方便。

# 连接成功后,在REPL里输入
import machine
print("Hello from MicroPython!")
# 如果看到输出,说明环境搭建成功

4.3 GPIO与PWM控制实战

好了,环境搭好了,咱们来点实际的。GPIO控制是嵌入式开发的基本功,PWM则是控制电机、LED亮度的利器。

4.3.1 GPIO控制——点亮LED

先来个最简单的:点亮一个LED。电路连接:LED正极接GPIO2,负极接GND(记得串一个220Ω电阻)。

from machine import Pin
import time

# 初始化GPIO2为输出模式
led = Pin(2, Pin.OUT)

# 循环闪烁
while True:
    led.value(1)  # 点亮
    time.sleep(0.5)
    led.value(0)  # 熄灭
    time.sleep(0.5)

这段代码很简单,但有个细节要注意:Pin.OUT 是输出模式,如果你要读取按键状态,要用 Pin.IN 并加上拉电阻。

小技巧:

我习惯用 led.on()led.off() 代替 led.value(1)led.value(0),代码可读性更好。另外,time.sleep() 是阻塞的,如果你需要同时做其他事,可以考虑用定时器。

4.3.2 PWM控制——呼吸灯效果

PWM说白了就是快速开关信号,通过调节占空比来控制平均电压。LED的亮度、电机的转速,都是这么调的。

from machine import Pin, PWM
import time

# 初始化PWM,频率1000Hz
pwm = PWM(Pin(2), freq=1000)

# 呼吸灯效果
while True:
    # 渐亮
    for duty in range(0, 1024, 10):
        pwm.duty(duty)
        time.sleep_ms(10)
    # 渐暗
    for duty in range(1023, -1, -10):
        pwm.duty(duty)
        time.sleep_ms(10)

这里 duty() 的取值范围是0-1023,对应0%到100%的占空比。为什么是1023?因为ESP32的PWM是10位分辨率,2^10=1024。

PWM参数速查表:

参数 说明 ESP32典型值
频率 (freq) PWM信号的频率,单位Hz 1000Hz(LED),50Hz(舵机)
占空比 (duty) 高电平时间占整个周期的比例 0-1023(10位分辨率)
分辨率 占空比的精度位数 10位(0-1023)

我在项目中遇到过一个问题:用PWM控制舵机时,频率设成了1000Hz,结果舵机嗡嗡响就是不转。后来查资料才知道,舵机需要50Hz的PWM信号,占空比在2.5%-12.5%之间对应0°-180°。你看,细节决定成败。

4.4 本章知识体系

为了让你更直观地理解本章的知识结构,我画了一张图:

第4章:Python在嵌入式中的基础 MicroPython vs 标准Python 嵌入式Python环境搭建 GPIO与PWM控制实战 内存占用差异 标准库精简 硬件控制能力 浮点运算差异 硬件准备(ESP32) 固件烧录(esptool) 串口连接测试 REPL交互验证 GPIO输出控制 PWM呼吸灯 频率与占空比 舵机控制应用 核心目标:掌握嵌入式Python开发基础 从环境搭建到GPIO/PWM控制,一步到位 图4-1 第4章知识体系结构图

这张图把本章的三个核心模块串起来了。从左到右,从理论到实践,一步步带你入门嵌入式Python开发。

我的建议:

学完本章后,别急着往下走。花点时间把GPIO和PWM的例程跑通,然后自己改改参数试试。比如把呼吸灯的频率改成500Hz看看效果,或者用两个LED做一个交通灯。动手实践是最好的学习方式。

好了,这一章的内容就到这儿。记住,嵌入式开发没有捷径,多动手、多踩坑,经验就是这么积累起来的。


公众号:蓝海资料掘金营,微信deep3321