资讯动态

树莓派Pico控制SG90舵机:MicroPython实现智能自动化入门

发布时间:2026/9/5 17:05:00 来源:尧图企业网站定制
直接说结论想低成本入门“智能自动化”不需要先买一两百块的开发板也不用急着学复杂的嵌入式操作系统。一颗树莓派 Pico加一个几块钱的 SG90 舵机再把 MicroPython 固件烧进去几十行代码就能做出“检测到目标后自动开门”“定时转动投喂”“传感器触发挡板”这类基础自动化装置。最近“树莓派 pico 控制舵机”这个方向之所以热门不是因为舵机本身有多新鲜而是 Pico 把过去门槛偏高的动手门槛打了下来你不需要会画 PCB、不需要懂寄存器细节甚至不需要 Linux 环境一条 USB 线加一个文本编辑器就能跑起来。这篇文章会从“为什么用 Pico 做自动化”讲起再带你完成 MicroPython 环境搭建、舵机 PWM 控制、传感器触发联动最后给出排错思路和工程化建议。读完你应该能完成两件事第一手里有一套能跑的 Pico 控制舵机最小系统第二知道怎么在此基础上扩展成真正有点“智能”的自动化项目而不是只会让舵机空转。1. 二十块钱的 Pico凭什么做智能自动化很多新手第一次接触“智能自动化”第一反应是买个树莓派 4B 或者直接上高性能开发板。但冷静想一下智能自动化的本质是“感知 决策 执行”而大多数机械控制场景对算力的要求并不是 PC 级别而是对引脚电平、脉冲时序、触发响应的确定性要求非常高。树莓派 Pico 在日常开发板里属于另类它没有完整 Linux 系统只是一个单片机开发板核心芯片是 RP2040采用双核 Arm Cortex-M0 架构主频常见配置为 133MHz 左右。在电脑面前这笔配置不起眼但对“读一个传感器、算一个阈值、推一个舵机”这种任务性能绰绰有余而且没有操作系统调度带来的不确定延迟。执行舵机 PWM 信号这类任务靠的是芯片内部硬件定时器而不是靠软件忙等这比在树莓派Linux 板上用 Python 写的软件 PWM 要稳定得多。还有一点容易被忽略成本。标题里说的“20 块”不是说整套系统只要 20 块而是指不带无线模块的 Pico 板子本身价格很亲民通常在二三十元人民币这个量级。舵机 SG90 市场价也在几块到十几块之间整套最小实验系统成本通常能控制在几十元。如果只是想验证自动门、自动遮光帘、遥控小车这类原型这个投入比动辄几百元的 Linux 板子理性很多。在选型上我有几个比较明确的判断方案定位适合场景学习成本树莓派 Pico单片机微控制器实时控制、GPIO 驱动、传感器联动低MicroPython 即可树莓派 4B/5Linux 单板计算机图像识别、Web 服务、跑算法高需要系统与网络基础Arduino单片机微控制器偏硬件底层控制、外设库丰富中C 语法ESP32单片机微控制器需要 WiFi/蓝牙的联网控制中需要处理电源和射频干扰从这个表能看出Pico 并不是“性能最强”的选择而是“离自动化的本质最近”的选择。自动化项目真正依赖的是事件触发、动作执行、状态保持这些逻辑用单片机和传感器解决比跑一个操作系统更直接。2. 控制舵机前必须理解的几个基础概念很多人看到“树莓派 Pico 控制舵机”的第一反应是是不是像控制 LED 一样给个高低电平它就转了并不是。2.1 PWM 不是单纯的高低电平舵机采用的是一种叫 PWM 的脉冲宽度调制信号。通俗地说控制端每隔固定周期给舵机发一个脉冲脉冲持续的时间高电平宽度决定了舵机转到的角度。典型航模舵机使用 50Hz 左右的 PWM 信号也就是周期大约 20 毫秒。在一个周期内高电平持续的时间从 0.5 毫秒到 2.5 毫秒不等对应舵机从 0 度到 180 度的大致范围。不同舵机对这个范围的标定不完全一致但调试思路是通用的先找到能让舵机平滑转动的脉冲范围再把角度映射成脉冲时间。2.2 Pico 的 PWM 和 GPIO 的关系树莓派 Pico 的 26 个 GPIO 引脚中很多引脚都能复用为 PWM 输出。这意味着你不用自己写代码“模拟”脉冲宽度只需要把某个 GPIO 配置成 PWM 模式然后设置频率和占空比芯片硬件会自动产生连续的脉冲信号。这里有个容易误解的点GPIO 是“引脚”PWM 是“引脚的一种工作模式”。同一个物理引脚既可以做普通数字输入输出也可以被配置成 PWM 通道具体要看固件和代码配置。2.3 MicroPython 还是 C/C SDK开发 Pico 主要有两条路线MicroPythonPython 语法开发效率高适合原型验证、个人项目、教学演示。舵机控制、传感器读取都有简洁的 API。C/C SDK官方推荐的高性能方案适合量产、复杂时序、PIO 等高级功能但需要编译器环境和更多底层知识。如果你是第一次做智能自动化对“跑通一个系统”有强烈需求我建议从 MicroPython 开始。因为你不需要频繁编译、烧录把脚本保存到板子里就能执行改逻辑非常快。等真正遇到性能瓶颈或者要做产品化了再切到 C SDK 也来得及硬件的接线和引脚思想是通用的。3. 环境准备给 Pico 烧录 MicroPython开始接线之前先把开发环境弄好。这里的顺序很重要先确认板子能运行 Python再去做硬件连接能规避一半的玄学问题。3.1 准备硬件你最少需要这些材料树莓派 Pico 或 Pico 兼容板。SG90 舵机一个或者其他型号舵机注意接口和供电。面包板、公对母杜邦线若干。一个能给板子供电的 USB 数据线。可选5V/2A 独立电源、电池盒、万用表。在继续之前请确认你的 USB 线是数据线而不是单纯的充电线否则电脑无法识别板子。3.2 烧写 MicroPython 固件Pico 出厂时默认不带 MicroPython需要手动烧录一次。步骤并不复杂访问 MicroPython 官方下载页面在 Raspberry Pi Pico 目录下下载 .uf2 格式固件。先按住 Pico 板子上的 BOOTSEL 按键不放。用 USB 线连接 Pico 和电脑。电脑会识别出一个名为 RPI-RP2 的可移动磁盘。把下载好的 .uf2 文件拖入该磁盘。文件复制完成后Pico 会自动重启BOOTSEL 模式退出。接下来电脑上就看不到这个磁盘了因为板子已经进入 MicroPython 运行状态。这一步如果没成功常见原因是 USB 线只支持充电或 BOOTSEL 按键没有按住再插线。3.3 使用 Thonny 连接 Pico推荐使用 Thonny IDE 做 MicroPython 开发它对新手很友好能直接显示文件结构、运行脚本和读取串口输出。打开 Thonny先点击右下角的解释器配置选择 MicroPythonRaspberry Pi Pico对应的解释器。然后点击运行按钮底部 Shell 会出现提示符说明板子和电脑已经建立串口通信。3.4 第一个测试点亮板载 LED在微控制器开发中先测试最小输出是很好的习惯。Pico 板载 LED 通常连接在 GP25 引脚上。# 文件led_test.py from machine import Pin import time led Pin(25, Pin.OUT) for _ in range(5): led.value(1) time.sleep_ms(200) led.value(0) time.sleep_ms(200) print(LED test finished.)运行后如果板载 LED 闪烁 5 次并且 Shell 打印 finished说明 MicroPython 环境正常。如果步失败优先检查 Thonny 解释器是否选对、USB 线是否连接正常。4. 树莓派 Pico 与舵机的硬件接线这里以最常见的 SG90 舵机为例。SG90 通常引出三根线颜色有约定舵机线颜色作用接法棕色GND接 Pico 的 GND红色VCC接舵机供电正极橙色/黄色信号接 Pico 的 GPIO 引脚信号线的位置建议不要选在容易被误插的电源引脚附近。为了清晰本文使用 GPIO0 作为信号输出口。接线步骤如下PWM 信号线接 Pico 的 GPIO0。舵机地线接 Pico 的 GND。舵机电源线接 5V 电源。这里要特别注意Pico 的逻辑电压是 3.3V而很多舵机推荐工作在 4.8V 到 6V 左右。这在电路设计上是很常见的搭配MCU 用逻辑信号控制舵机的信号输入端舵机的功率从独立电源获取两边共地即可。如果只是在面包板上做初次测试临时把舵机电源接到 Pico 的 VBUS5V 电源脚也能演示但千万不要长时间让舵机堵转或者同时带动多个舵机。更稳的做法是准备一个独立 5V 电源或者 4 节 5 号电池盒让 Pico 和舵机共地但不共电源。这种“信号共地、功率分离”的画法是后面一切自动化设备接线的基础。继电器、电磁锁、直流电机驱动模块的接线逻辑也基本如此。5. 最小示例让 Pico 驱动舵机来回扫描环境没问题后下面写一个能直接运行的程序。它的功能是让舵机在 0 到 180 度之间来回扫描用来验证舵机、PWM 和电源是否正常。# 文件servo_sweep.py from machine import Pin, PWM import time SERVO_PIN 0 PWM_FREQ 50 # 50Hz即 20ms 一个周期 PWM_PERIOD_US 20000 # 20000us 20ms MIN_PULSE_US 500 MAX_PULSE_US 2500 servo PWM(Pin(SERVO_PIN)) servo.freq(PWM_FREQ) def clamp(value, low, high): return max(low, min(value, high)) def set_servo_pulse(pulse_us): pulse_us clamp(int(pulse_us), MIN_PULSE_US, MAX_PULSE_US) duty int(pulse_us * 65535 / PWM_PERIOD_US) servo.duty_u16(duty) def set_servo_angle(angle): angle clamp(angle, 0, 180) pulse_us MIN_PULSE_US (angle / 180.0) * (MAX_PULSE_US - MIN_PULSE_US) set_servo_pulse(pulse_us) try: while True: for angle in range(0, 181, 10): set_servo_angle(angle) time.sleep_ms(200) for angle in range(180, -1, -10): set_servo_angle(angle) time.sleep_ms(200) finally: servo.deinit()这段代码核心逻辑分三层PWM_FREQ控制 PWM 频率设置成 50Hz 对应舵机常用的 20ms 周期。set_servo_pulse把脉冲宽度换算成duty_u16需要的数值。MicroPython 的duty_u16用 0 到 65535 表示 0% 到 100% 的占空比换算公式是“脉冲宽度除以周期再乘以 65535”。set_servo_angle先把角度限制在 0 到 180 度再做线性映射得到对应的脉冲时间。运行后预期现象是舵机从接近 0 度的位置开始每 0.2 秒转动一次逐步转到 180 度附近再反向转回来。如果舵机没有任何反应先检查舵机电源是否正常、信号线是否插到 GPIO0、以及电源地线和 Pico 地线是否共地。这里的 500us 到 2500us 只是一个通用参考范围不代表所有舵机都能无碰撞地走完整个跨度。真机调试时建议从 700us 到 2300us 这种更保守的范围开始确认转动方向正确后再扩大范围防止舵机憋住。6. 加入传感器做一个“自动触发”的自动化装置舵机只会来回扫描还谈不上“自动”。智能自动化的关键转折点在于系统能够根据外部事件做出不同动作。这一节用一个超声波测距模块作为“眼睛”让系统在检测到 20cm 内有物体时把舵机转到 120 度位置保持 2 秒然后回到 30 度位置。这个场景可以类比为自动感应开盖装置。如果你没有超声波模块也可以用按键顶替“传感器”思路完全一样。6.1 HC-SR04 超声波模块接线HC-SR04 模块有四根引脚VCC、Trig、Echo、GND。VCC 接 5V 电源GND 和 Pico 共地。Trig 是触发信号Pico 发一个短脉冲后模块通过 Echo 引脚返回一个高电平脉冲高电平持续时间对应声波往返时间。安全提醒HC-SR04 常见版本是 5V 逻辑而 Pico 的 GPIO 工作在 3.3V。 Echo 引脚返回的高电平理论上接近 5V如果直接接到 Pico 引脚长期使用有损坏风险。正规做法是先把 Echo 信号经过电阻分压再进 Pico例如使用 1kΩ 和 2kΩ 分压把 5V 降到 3.3V 左右。接线参考如下HC-SR04 引脚接法VCC5VGNDPico GNDTrigPico GP2Echo经过电阻分压后接 Pico GP3舵机仍然使用 GP0 作为信号脚电源由独立 5V 供给。6.2 超声波触发舵机示例代码# 文件auto_trigger.py from machine import Pin, PWM, time_pulse_us import time SERVO_PIN 0 TRIG_PIN 2 ECHO_PIN 3 PWM_FREQ 50 PWM_PERIOD_US 20000 MIN_PULSE_US 700 MAX_PULSE_US 2300 OPEN_ANGLE 120 CLOSE_ANGLE 30 DISTANCE_THRESHOLD_CM 20 HOLD_MS 2000 servo PWM(Pin(SERVO_PIN)) servo.freq(PWM_FREQ) trig Pin(TRIG_PIN, Pin.OUT) echo Pin(ECHO_PIN, Pin.IN) servo_opened False servo_opened_time 0 def clamp(value, low, high): return max(low, min(value, high)) def set_servo_angle(angle): angle clamp(angle, 0, 180) pulse_us MIN_PULSE_US (angle / 180.0) * (MAX_PULSE_US - MIN_PULSE_US) pulse_us clamp(int(pulse_us), MIN_PULSE_US, MAX_PULSE_US) duty int(pulse_us * 65535 / PWM_PERIOD_US) servo.duty_u16(duty) def measure_distance_cm(): trig.value(0) time.sleep_us(5) trig.value(1) time.sleep_us(10) trig.value(0) duration_us time_pulse_us(echo, 1, 30000) if duration_us 0: return -1 return duration_us / 58.0 set_servo_angle(CLOSE_ANGLE) while True: distance measure_distance_cm() print(distance%.1f cm % distance) if 0 distance DISTANCE_THRESHOLD_CM and not servo_opened: servo_opened True servo_opened_time time.ticks_ms() set_servo_angle(OPEN_ANGLE) if servo_opened: if time.ticks_diff(time.ticks_ms(), servo_opened_time) HOLD_MS: servo_opened False set_servo_angle(CLOSE_ANGLE) time.sleep_ms(100)这个示例比前面多出的关键设计是状态变量servo_opened。很多新手在写传感器触发逻辑时会在循环里写“只要距离小于阈值就一直转到开盖角度”。结果就是物体一直停在传感器前时舵机一直被重复驱动甚至可能抖动、发热。这里用状态变量保证“检测到物体时只执行一次开盖动作”等保持时间结束后再关闭。这就是自动化程序中很常见的“边沿触发”思想上升沿有效而不是电平持续有效。time_pulse_us是 MicroPython 的机器级函数用来测量引脚上电平持续的时间单位是微秒。测量得到的时间除以 58可以粗略换算成厘米因为声波在空气中往返 1 厘米大约需要 58 微秒。如果测量超时函数会返回负数此时不能参与距离判断。运行后你可以把手或者书本移动到传感器前方 20cm 内预期舵机会转动到 120 度方向停留约 2 秒后转回 30 度位置。整个过程 Shell 里会持续打印距离值方便观察。7. 树莓派 Pico 控制舵机常见问题排查我把实际做项目时最常踩的坑整理成了一张表。如果遇到舵机不动、抖动、程序下载失败等问题从这里开始排查通常是最快的。问题现象可能原因排查方式解决方案舵机完全不动舵机电源没接好先用万用表测舵机电源引脚电压给舵机提供独立 5V 电源并与 Pico 共地舵机不动但有嗡嗡声信号线接触不良或脉冲范围过大舵机憋住检查杜邦线连接看信号引脚是否输出 PWM缩小程序脉冲范围重新插拔信号线舵机剧烈抖动电源输出电流不足观察电源指示灯或给舵机单独供电换 5V/2A 左右独立电源或在电机供电端并联电容角度范围不对不同舵机对脉宽标定不同打印当前 pulse 值逐步增减范围调整 MIN_PULSE_US 和 MAX_PULSE_US程序能运行但舵机反应慢循环里用了较长的 sleep 阻塞测距分析主循环耗时把测距和舵机刷新拆成两个函数或使用异步定时器USB 无法识别 Pico数据线问题或未进入烧录模式换线重新按住 BOOTSEL 插入确保 USB 线支持数据传输duty_u16相关报错MicroPython 版本的 API 差异查看固件日期和版本优先使用官方最新固件统一 APIEcho 引脚导致程序卡住超声波没有返回信号或电平不匹配Shell 打印 duration 是否为 -1检查 trig/echo 接线和电阻分压其中最容易误导新手的是“舵机不动但有嗡嗡声”的情况。舵机内部有一个电机和一个电位器反馈电路如果给它一个超出可转动范围的脉宽它会一直往某个方向顶却又因为机械结构卡住而无法到位电机持续堵转听起来就是高频的嗡嗡声。长时间堵转会让舵机发热甚至损坏电机齿轮。遇到这种问题先把脉宽范围调得更保守再手动掰舵机摇臂确认确实能自由转动。8. 从原型到实际项目工程化建议原型跑通之后距离一个真正能在桌面上长期运行的自动化项目还有几步。下边这些建议不是“锦上添花”而是实际项目里很关键的工程细节。8.1 电源系统是自动化的第一优先级舵机瞬时启动电流会比额定电流大很多尤其是从静止突然转到目标角度时。如果 Pico 和舵机共用一个不稳定的电源会出现舵机一动Pico 就重启的经典故障。建议把控制部分和功率部分分开供电Pico 通过 USB 或者 3.3V 稳压电路供电。舵机、电机、电磁锁等功率器件使用独立电源。两组电源的 GND 必须连在一起否则控制信号没有参考地无法正确传回。如果你的项目将来要驱动多个舵机建议不要直接从 Pico 的 5V 引脚取电。舵机电流较大时在供电端并联一个几百微法的电解电容会改善电压跌落但根本解法还是提供足够余量的独立电源。8.2 让程序开机自动运行Thonny 里按“运行”执行的脚本在板子断电后就没了。如果希望 Pico 上电后自动执行程序需要把脚本保存到文件系统的根目录并命名为main.py。具体操作是在 Thonny 菜单里选择“文件 - 另存为”然后选择保存到 MicroPython 设备。保存成功后重新插拔 USB 或者按复位键板子会自动运行main.py。调试时要注意开机自动运行的程序如果存在死循环会把串口 REPL 占用导致再次打开 Thonny 时无法操作。此时可以在按住 BOOTSEL 的情况下重新连接或者先尝试中断程序。更稳妥的开发方式是先不把测试脚本命名为main.py等逻辑稳定后再做最后部署。8.3 把传感器读取和动作执行分开写自动化程序会随着功能增加而变复杂。一开始可能是“超声波测距开盖”后来可能要加按键手动控制、BLE 远程控制、状态灯指示。如果把所有功能堆在一个 while 循环里代码很快就不可维护了。比较务实的做法是每个传感器封装成一个函数只负责返回数据。舵机控制封装成一个函数只负责接收角度并执行。主循环只做数据采集、状态判断和执行调用。通过打印或日志观察每个环节的输入输出。当系统出问题时你能很快判断是传感器数值异常、执行机构异常还是状态逻辑异常。8.4 增加“状态机”而不是盲目地一直执行前面示例中的servo_opened是最简单的状态变量。真实项目里状态可能更多例如关门中、暂停、手动模式、故障模式。状态机不一定要用复杂框架。对单片机项目来说用几个变量表示当前状态在 while 循环中做状态转移已经足够清晰。关键原则是任何状态转换都要有明确条件任何状态都不能因为一条错误数据就立刻跳变。比如测距偶尔返回 -1不应该让舵机误触发动。8.5 电气安全和边界控制如果你把自动化从舵机扩展到继电器、加热棒、220V 设备请务必记住一点微控制器本身是低压弱电设备绝不能直接处理高压电。驱动交流设备时需要用继电器模块、固态继电器等隔离方案控制端只负责给继电器一个低电压信号功率端接负载。接线前断开电源功率线和信号线分开走继电器输出端做好绝缘。涉及强电的项目建议在有一定电气安全经验的人指导下进行。9. 掉坑之后的感悟与下一步方向树莓派 Pico 控制舵机这个方向看起来入门很简单实际上拉开差距的往往是细节脉宽范围有没有做限幅、电源供电够不够稳、传感器触发有没有做状态判断、程序能不能开机自启、串口打不开时知不知道如何重新进入烧录模式。如果你现在能跟着文章把一个舵机扫描跑通再用超声波触发舵机做一次动作说明你的“智能自动化最小闭环”已经成立了。接下来可以沿着几个方向继续深入学习按钮外部中断和定时器让系统能同时响应手动操作和自动触发。研究 I2C 协议给 Pico 接 OLED 屏幕或温湿度传感器把自动化系统变成“有显示、有状态”的完整设备。将系统接上继电器控制吸顶灯、风扇等低压直流负载完成一次带功率设备的自动化改造。如果你需要网络化控制关注带 WiFi 的 Pico 或者通过 ESP 系列的联网方案实现局域网内控制。最后提醒一句做任何带动作的自动化原型都不要在没加限位和人工急停的情况下长时间无人运行。先确保程序在异常情况下能安全回到初始状态再加传感器、加联动。把最小系统跑稳比追求功能数量更重要。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价