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没有完整的标准库,比如
numpy、pandas这些就别想了 - 硬件控制是MicroPython的强项,
machine.Pin、machine.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 本章知识体系
为了让你更直观地理解本章的知识结构,我画了一张图:
这张图把本章的三个核心模块串起来了。从左到右,从理论到实践,一步步带你入门嵌入式Python开发。
我的建议:
学完本章后,别急着往下走。花点时间把GPIO和PWM的例程跑通,然后自己改改参数试试。比如把呼吸灯的频率改成500Hz看看效果,或者用两个LED做一个交通灯。动手实践是最好的学习方式。
好了,这一章的内容就到这儿。记住,嵌入式开发没有捷径,多动手、多踩坑,经验就是这么积累起来的。
公众号:蓝海资料掘金营,微信deep3321