树莓派+Jupyter+PCA9685舵机机械臂控制实战
2026/9/12 4:35:36 网站建设 项目流程

这次我们来看一套非常典型的树莓派机械臂控制链路:树莓派 4B + Jupyter Notebook + PCA9685 16 路 PWM 驱动板 + 舵机机械臂。很多做 3D 打印机械臂毕业设计或者机器人入门实验的同学,最后都会走到这套组合上。它的价值在于,你不需要反复修改脚本、重复烧录,而是直接在浏览器里用 Jupyter 实时控制每一路舵机,调角度、看反馈、跑动作序列,调试效率比纯命令行高很多。

整套系统里,树莓派负责运行 Jupyter 服务和 Python 控制程序;PCA9685 负责接收树莓派通过 I2C 发送的 PWM 指令,并且独立为舵机提供足够电流的驱动通道;Jupyter 则负责提供一个交互式开发界面。你可以在一个单元格里写“让 0 号舵机转到 90 度”,立刻执行,马上看到机械臂动作,然后根据实际效果继续调参数。这种“改一行代码,马上验证”的交互方式,比每次写完整脚本再跑要直观得多。

本文会完整演示:硬件接线、树莓派系统配置、启用 I2C、安装 Jupyter、安装 PCA9685 控制库、验证 I2C 通信、基础 PWM 输出、舵机角度映射、多舵机联动动作序列,以及常见坑的排查方法。还会顺带讲清楚 Jupyter Notebook 和 Jupyter Lab 怎么选、如何从局域网访问树莓派上的 Notebook。

适合的人群很明确:正在做机械臂抓取课程设计的学生,想快速验证舵机动作逻辑的机器人爱好者,准备把树莓派摄像头视觉识别和机械臂抓取结合起来的开发者,以及想用 Python 交互式控制 PCA9685 但又不想写命令行程序的人。如果你只是想用 Arduino 控制几个舵机,那可以直接用 Arduino 库,本文这套树莓派方案更适合需要跑视觉、跑 Python 逻辑、做动作规划的场景。

1. 核心能力速览

能力项说明
项目类型树莓派 + I2C + PWM 舵机控制实验平台
核心硬件树莓派 4B(5 代同样适用)、PCA9685 16 路 12 位 PWM 驱动板、普通模拟/数字舵机、机械臂结构件
通信方式树莓派 I2C 总线,默认设备地址 0x40
控制方式Jupyter Notebook / Jupyter Lab 内运行 Python 代码,实时控制
舵机控制原理PWM 脉宽控制,常见频率 50Hz,脉宽范围约 0.5ms 到 2.5ms
库依赖adafruit-circuitpython-servokit、adafruit-circuitpython-pca9685、board、busio
是否支持批量任务支持,可以把多舵机动作序列写成循环或队列依次执行
是否支持接口 API本身不提供 REST API,但可以在 Jupyter 中把控制逻辑封装为函数,后续可进一步扩展 Flask/ROS 服务
适合场景机械臂动作调试、毕业设计、视觉抓取实验、ROS 前置学习、教学演示
需要注意的边界舵机必须外接电源,不能直接从树莓派 3.3V 引脚取电;操作前先单独调试每路舵机

这套方案最核心的卖点不是“能转舵机”,而是把调试过程变成了“写一行、跑一行、看结果”的交互流程。你不需要每次运行一整份脚本,出现问题后逐行打印排查,而是可以用 Jupyter 单元格逐步验证每个部件。

2. 适用场景与使用边界

2.1 适合什么场景

最典型的场景是机械臂动作调试。普通的 3D 打印机械臂通常有 4 到 6 个舵机,分别对应底座旋转、肩部抬升、肘部弯曲、手腕旋转和夹爪开合。直接写一个完整脚本去让所有舵机联动,一旦某个角度不对,很难判断是机械限位问题、舵机脉宽标定问题,还是动作顺序问题。放到 Jupyter 里调试就清楚很多:先单独控制 0 号舵机,确认它在 0 度、90 度、180 度分别对应什么机械位置,再做多舵机联动。

这也是视觉机械臂抓取的前置步骤。树莓派搭配 ov5647 摄像头模块做目标识别,识别结果最后总会输出到舵机角度上。如果舵机控制链路没有先调通,视觉识别再准也没法驱动机械臂完成抓取。先通过 Jupyter 把 PCA9685 和舵机这一层完全掌握,后面接视觉、接 ROS、接轨迹规划都会顺畅很多。

2.2 不适合什么场景

如果你只是想做简单的几个舵机来回摆动,而且不需要 Python 逻辑,直接用 Arduino 控制舵机是更轻量的选择。Arduino 的舵机库写起来更简单,也不需要配置系统、安装 Jupyter、管理 I2C 地址。另外,如果你要做的是工业级机械臂控制,追求高精度轨迹规划和高响应频率,那 PCA9685 并不合适。它更适合教学、原型验证、小型机械臂实验,而不是承载高精度工业控制任务。

还有一点需要注意:Jupyter 是交互式调试工具,不是实时控制系统。Jupyter 执行单元格时会有进程开销,如果用来跑非常高频的舵机 PID 闭环控制,实时性不足。更稳妥的方案是:在 Jupyter 里完成参数调试和动作序列设计,真正需要稳定运行时,把逻辑导出为 Python 脚本,用 systemd 或 Docker 去托管。

2.3 安全边界与合规提醒

舵机控制涉及机械运动,操作前一定要做好物理安全防护。机械臂的夹爪位置不要对着人,调试时先移除夹爪或者用小扭矩舵机测试。舵机堵转时电流会明显上升,长期堵转会发热,可能导致舵机损坏甚至烧毁驱动板。电源部分必须外接独立电源,不能依赖树莓派的 GPIO 供电。树莓派的 3.3V 引脚电流输出能力非常有限,带不动多路舵机同时工作。

如果后续接入摄像头做视觉抓取,注意不要对未经授权的人脸或隐私区域做识别采集。如果使用网上下载的 3D 打印机械臂模型,先确认模型的许可证是否允许改装和商用。机械臂动作设计要避免危险动作,不要设计武器化改造,不要攻击人或动物。

3. 硬件准备与接线说明

3.1 硬件清单

硬件数量说明
树莓派 4B1建议 4GB 内存版本以上;树莓派 5 同样兼容
microSD 卡116GB 以上,安装 Raspberry Pi OS
PCA9685 模块116 通道、12 位分辨率 PWM 驱动板
舵机4-6根据机械臂结构确定,常见 SG90 / MG996R
舵机机械臂结构件1套3D 打印或成品机械臂
5V 外接电源1电流需匹配舵机数量,多舵机建议 5V 5A 以上
杜邦线若干母对母为主,I2C 信号线和舵机信号线
摄像头(可选)1树莓派 ov5647 摄像头模块,用于视觉抓取扩展

3.2 PCA9685 与树莓派接线

PCA9685 的接线方式非常固定。树莓派的 GPIO 引脚编号使用的是 BCM 编号,I2C 接口默认在 GPIO2(SDA)和 GPIO3(SCL)上。PCA9685 模块上的 VCC 接树莓派 3.3V,GND 接 GND,SDA 接 SDA,SCL 接 SCL。

PCA9685 引脚树莓派 GPIO备注
VCC3.3V(物理引脚 1)给 PCA9685 板载逻辑供电
GNDGND(物理引脚 6)与树莓派共地
SDAGPIO2(物理引脚 3)I2C 数据线
SCLGPIO3(物理引脚 5)I2C 时钟线
V+外接 5V 电源正极给舵机供电,不接树莓派
GND(电源侧)外接电源负极必须与树莓派 GND 共地

舵机连接到 PCA9685 的通道输出口上。PCA9685 的每一路输出是 3 针接口,通常对应黄色/橙色信号线、红色电源线、棕色/黑色地线。舵机的信号线接 PCA9685 对应通道的 PWM 引脚,红色接 V+,棕色/黑色接 GND。注意 PCA9685 板上的 V+ 和 GND 是给舵机供电的通道,板载逻辑的 VCC 和舵机电源的 V+ 是分开的。一定要让舵机电源的 GND 和树莓派的 GND 连在一起,否则 I2C 信号没有共同参考地,控制会出现随机抖动。

3.3 电源选择建议

这是最容易踩坑的部分。单个 SG90 舵机在空载时电流只有几十毫安,但启动瞬间和堵转时电流会达到几百毫安甚至更大。MG996R 这类大扭矩舵机要求的电流更大。如果 4 个舵机同时动作,峰值电流可能轻松超过 2A,USB 口的 5V 供电根本不够。

更稳妥的选择是:单独准备一个 5V 5A 以上的开关电源,或者使用带 BEC 的航模电池供电方案。供电之后,先用万用表确认电压在舵机规格范围内,再接通 PCA9685 的 V+。接线顺序也有讲究:先接信号线和共地线,再接通外部电源。不要在舵机运行时带电插拔杜邦线,很容易烧坏驱动板上的电路。

4. 树莓派系统配置与 Jupyter 环境搭建

4.1 系统基础检查

先确保树莓派已经刷好 Raspberry Pi OS,并且能通过 SSH 或者桌面终端登录。登录后先执行系统更新,顺便检查当前 I2C 是否已经启用。

# 更新系统软件源和已安装软件 sudo apt update sudo apt full-upgrade -y

这里有个小细节:国内网络环境下,树莓派默认软件源速度可能很慢。如果遇到 apt 更新卡住,可以先把树莓派软件源换成国内镜像源,再执行更新。换源之后,很多依赖安装问题会明显缓解。

系统更新完成后,检查内核是否加载了 I2C 驱动:

ls /dev/i2c*

如果能看到/dev/i2c-1,说明 I2C 设备节点已经存在。如果没有,就需要在 raspi-config 里手动启用。

4.2 启用 I2C 接口

树莓派官方系统默认不启用 I2C,需要手动打开。最标准的方式是使用 raspi-config:

sudo raspi-config

在菜单中找到Interface Options,依次进入I3 I2C,选择开启。退出后重启树莓派:

sudo reboot

重启完成后,再用ls /dev/i2c*确认 I2C 设备节点已经出现。这一步非常关键,后续 PCA9685 的所有控制都基于 I2C 通信,如果 I2C 没启用,Python 代码会直接报错找不到总线。

另外可以顺手确认一下python3版本和pip3是否可用:

python3 --version pip3 --version

树莓派官方系统自带 Python 3,一般不需要额外编译。如果pip3不存在,可以先安装:

sudo apt install -y python3-pip

4.3 安装 Jupyter Notebook 和 Jupyter Lab

Jupyter 是一个浏览器端交互式开发环境,支持把代码、输出、说明文字混合在一个文档里。对树莓派控制实验来说,它最大的好处是可以用单元格逐步调试。

安装方式有两种。第一种是使用系统包管理器,这种方式简单,但版本可能偏旧:

sudo apt install -y jupyter-notebook

第二种是使用 pip 安装,版本更新,更容易管理依赖:

pip3 install --user jupyter pip3 install --user jupyterlab

这里要解释一下 Jupyter Notebook 和 Jupyter Lab 的区别。Notebook 是经典的单文档界面,适合打开一个.ipynb文件逐步运行;Lab 是 Jupyter 新一代工作台,左侧有文件树,可以同时打开多个 Notebook、终端、文本编辑器,更像一个轻量级 IDE。如果你只是做树莓派舵机控制,两者都能满足需求;如果你需要同时编辑多个文件、查看图像输出、管理目录,选 Jupyter Lab 更顺手。

安装完成后,可以查看当前安装的 Jupyter 版本:

jupyter --version

4.4 启动 Jupyter 并配置远程访问

在树莓派桌面环境中,直接执行jupyter notebook就会自动打开浏览器。但很多用户是远程连接树莓派,没有桌面环境,这时需要设置为“无浏览器启动”模式:

jupyter notebook --ip=0.0.0.0 --port=8888 --no-browser

参数含义:

参数作用
--ip=0.0.0.0允许局域网其他设备访问
--port=8888指定端口,默认 8888
--no-browser不在树莓派本地打开浏览器

服务启动后,终端会输出一个带 token 的访问地址,例如http://127.0.0.1:8888/?token=xxx。在你自己电脑的浏览器里访问http://树莓派IP:8888,输入 token 即可登录。

如果希望把 token 固定下来,避免每次启动都变化,可以先执行jupyter notebook password设置登录密码。之后在局域网内访问时,只需要输入 IP 地址和端口,再填写密码即可。这里要注意:如果端口 8888 已经被占用,Jupyter 会自动切换到 8889 并输出提示,看到日志里出现新的端口就不是出错,不用紧张。

5. 安装 PCA9685 控制库并检测 I2C 设备

5.1 安装 Adafruit PCA9685 库

PCA9685 的控制库有两种主流选择:旧版 Adafruit PCA9685 库和新的 CircuitPython 库。新库 API 更清晰,对舵机控制提供了更底层的封装,推荐优先使用 CircuitPython 库。在 Jupyter 的终端或者树莓派命令行中执行:

pip3 install --user adafruit-circuitpython-pca9685 pip3 install --user adafruit-circuitpython-servokit

adafruit-circuitpython-servokit依赖adafruit-circuitpython-pca9685,安装 servokit 时通常会自动带上 PCA9685 的驱动库。这个库会自动扫描 I2C 总线上的 PCA9685 设备,并把它初始化为 16 通道的 PWM 输出模块。

5.2 I2C 设备检测与地址检查

在写 Python 代码之前,先做一次硬件层面的 I2C 扫描,确认树莓派真的能识别到 PCA9685。在 Jupyter 里新建一个 Notebook,或者在终端输入:

sudo apt install -y i2c-tools i2cdetect -y 1

这里的1表示使用 I2C 总线 1,这是树莓派默认的 I2C 总线编号。执行后,输出表格中应该有一个位置显示0x40,这个地址就是 PCA9685 的默认 I2C 地址。

如果扫描不到0x40,优先检查接线:SDA 和 SCL 是否接反、VCC 是否接了树莓派 3.3V、GND 是否共地。很多情况下,PCA9685 模块上的逻辑供电来自 VCC 引脚,VCC 没接对,I2C 芯片不会工作,自然扫描不到设备。

如果多个 PCA9685 模块级联,可以通过模块上的 A0-A5 跳线修改地址。默认全不焊时地址是 0x40。扫描结果里出现多个设备时,确保代码里使用正确的地址。

# 在 Jupyter 中查看 PCA9685 默认地址的示例 import busio from board import SCL, SDA i2c = busio.I2C(SCL, SDA) # 扫描 I2C 总线上所有设备地址 while not i2c.try_lock(): pass print([hex(device_address) for device_address in i2c.scan()]) i2c.unlock()

如果这一行代码能输出['0x40'],说明硬件链路已经完全打通,可以进入下一步的 PWM 控制验证了。

6. 在 Jupyter 中控制 PCA9685 与舵机

6.1 基础 PWM 输出验证

完整控制的第一步是验证 PCA9685 能不能正常输出 PWM 信号。PCA9685 内部有一个频率寄存器,默认频率通常是 1kHz 左右,但舵机需要的是 50Hz 左右的 PWM 信号,也就是周期为 20ms。先把频率设置成 50Hz。

import board import busio from adafruit_pca9685 import PCA9685 # 初始化 I2C 总线和 PCA9685 i2c = busio.I2C(board.SCL, board.SDA) pca = PCA9685(i2c) # 设置 PWM 频率为 50Hz,适配舵机控制 pca.frequency = 50 # 设置第 0 通道输出一个中间占空比 pca.channels[0].duty_cycle = 0x7FFF # 约 50% 占空比

执行这个单元格后,用示波器或者直接接一个舵机,可以看到第 0 通道有 PWM 信号输出。如果接的是舵机,舵机会转到中间位置附近。把 duty_cycle 改成0x2E660x4CCC,舵机会偏转不同角度。

注意,这里直接操作 duty_cycle 需要自己算脉宽对应的占空比值,不直观。实际控制舵机时,更常用的是后续的 ServoKit 库。

6.2 舵机脉宽与角度关系

普通舵机的控制原理是:PWM 频率固定为 50Hz,通过改变高电平脉宽来控制舵机角度。常见舵机的映射关系是 0.5ms 对应 0 度,1.5ms 对应 90 度,2.5ms 对应 180 度。也有部分舵机是 1ms 到 2ms 对应 0 到 180 度。

50Hz 对应的周期是 20ms,PCA9685 的 duty_cycle 是 16 位值,范围 0 到 65535。所以脉宽为 T 毫秒时,对应的 duty_cycle 可以通过公式计算:

duty_cycle = int((pulse_ms / 20.0) * 65535)

例如 1.5ms 对应:

pulse_ms = 1.5 duty_cycle = int((pulse_ms / 20.0) * 65535) print(duty_cycle)

这个计算值可以直接赋给pca.channels[0].duty_cycle。但不同舵机会有差异,实际项目里一定要用 Jupyter 逐步测试每一路舵机的脉宽上下限,记录到自己的校准表里,而不是直接信任理论值。

6.3 用 ServoKit 直接设置角度

如果你不想手动计算占空比,可以用 ServoKit 库,它提供了更直观的角度控制接口:

from adafruit_servokit import ServoKit # 初始化 16 通道 ServoKit,默认频率 50Hz kit = ServoKit(channels=16) # 控制第 0 通道舵机转到 90 度 kit.servo[0].angle = 90

执行这一行代码,第 0 通道的舵机就会转到 90 度位置。与直接操作 duty_cycle 相比,ServoKit 把角度映射和脉宽变化都封装好了,代码可读性明显更高。

可以继续测试多个角度:

import time # 依次转到不同角度,观察舵机是否平滑移动 for angle in [0, 45, 90, 135, 180]: kit.servo[0].angle = angle time.sleep(1)

如果某路舵机在极端角度出现抖动或者异响,说明角度超出了该舵机的实际机械范围,需要减小上限。

ServoKit 还支持设置脉宽范围。部分舵机的 0 度并不等于 0.5ms,可以按实际舵机型号调整:

# 设置第 0 通道舵机的最小和最大脉宽 kit.servo[0].set_pulse_width_range(500, 2500)

这里的单位是微秒,500 对应 0.5ms,2500 对应 2.5ms。如果你的舵机在 0 度和 180 度位置有偏差,改变这个范围通常能解决问题。

6.4 多舵机联动与动作序列

机械臂控制的核心是多舵机联动。每个舵机负责一个关节,要完成一次抓取动作,需要让多个舵机按顺序运动到指定角度。

首先,把所有舵机都接入 PCA9685 的通道中。假设机械臂有 4 个舵机:0 号是底座旋转,1 号是肩部,2 号是肘部,3 号是夹爪。一个简单的“下降-抓取-抬起”动作序列可以这样写:

import time from adafruit_servokit import ServoKit kit = ServoKit(channels=16) # 初始姿态:各个关节归位 kit.servo[0].angle = 90 # 底座居中 kit.servo[1].angle = 60 # 肩部适当抬起 kit.servo[2].angle = 30 # 肘部展开 kit.servo[3].angle = 0 # 夹爪完全张开 time.sleep(1) # 向下移动到抓取位置附近 kit.servo[1].angle = 80 kit.servo[2].angle = 60 time.sleep(1) # 闭合夹爪 kit.servo[3].angle = 90 time.sleep(1) # 抬起机械臂 kit.servo[1].angle = 60 kit.servo[2].angle = 30 time.sleep(1)

这段代码在 Jupyter 中运行时,每个步骤之间都有time.sleep延时。这样做的目的是让舵机有足够时间完成机械运动,避免多舵机同时大范围动作导致电源瞬间过载。

6.5 把控制逻辑封装成可复用函数

当动作序列越来越复杂时,直接在单元格里写几行kit.servo[x].angle = y会很难维护。更工程化的做法是把动作封装成函数。这样后续可以做批量任务、接口扩展,甚至可以读取 JSON 配置文件来实现动作编排。

import json import time from adafruit_servokit import ServoKit kit = ServoKit(channels=16) # 定义一个动作执行函数 def run_action(action_list): """ action_list 格式: [ {"servo": 0, "angle": 90, "delay": 1}, {"servo": 1, "angle": 60, "delay": 1} ] """ for action in action_list: kit.servo[action["servo"]].angle = action["angle"] time.sleep(action.get("delay", 0.5))

调用方式:

actions = [ {"servo": 0, "angle": 90, "delay": 1}, {"servo": 1, "angle": 80, "delay": 1}, {"servo": 3, "angle": 90, "delay": 1}, ] run_action(actions)

如果需要批量测试多组动作,可以准备一组动作列表,循环执行:

# 批量执行多组动作 for i in range(3): run_action(actions) time.sleep(2)

这种思路也叫“动作序列批量任务”。后续如果接入摄像头视觉识别的结果,只需要让视觉程序输出一个动作列表,再调用run_action执行,就能实现简单的视觉抓取逻辑。

7. 机械臂动作调试与效果验证

7.1 舵机角度标定

拿到一套新机械臂时,不要直接写复杂的动作序列。第一次上电时,应该先让所有舵机回到一个已知的中间角度,再逐个检查机械限位。

建议步骤:

  1. 断开机械臂的舵机输出连接,只接 PCA9685 控制板。
  2. 在 Jupyter 中逐一执行kit.servo[i].angle = 90,让每路舵机转到中间位置。
  3. 观察每个关节的机械结构,确认 90 度位置是否是安全的中间位。
  4. 再测试每个关节的 0 度和 180 度,记录机械结构是否会出现干涉。
  5. 把每个舵机的安全角度上下限记到配置里。

如果某个舵机在 Jupyter 里设定为angle = 180,但机械结构最先到达限位位置,说明该关节的安全上限不是 180。你需要在后续所有动作序列中避免超出这个范围。

7.2 动作验证流程

动作序列写好后,先用小范围、慢速度验证。把每步延时调大,比如delay=2,让动作速度变慢,观察机械臂在每个阶段的姿态。如果出现明显抖动、卡顿或者异响,先判断是机械结构问题还是舵机脉宽上下限设置问题。

验证通过后,再逐步减小延时,调整到合适的动作速度。要注意:机械臂转动速度越快,对电源峰值电流的要求越高。多舵机同时快速动作时,电源电压跌落可能导致舵机失控,出现随机抖动或者复位现象。

7.3 树莓派资源占用观察

PCA9685 本身只承担 PWM 信号生成,树莓派这边的工作量很低。真正占资源的是 Jupyter 服务、摄像头图像处理、以及可能的视觉模型推理。可以在树莓派上开一个终端,用htop观察进程状态:

sudo apt install -y htop htop

如果只是控制舵机,python3进程的 CPU 占用通常很低。如果发现 Jupyter 服务响应变慢,优先检查内存是否不足,可以查看free -h的输出。树莓派 4B 4GB 版本跑 Jupyter 加摄像头识别通常够用;如果跑大型视觉模型,建议升级到 8GB 版本,或者在树莓派上只做舵机控制,把视觉推理放到其他设备上。

8. 常见问题与排查方法

问题现象可能原因排查方式解决方案
i2cdetect -y 1扫描不到 0x40PCA9685 未通电、VCC 未接、SDA/SCL 接反、共地缺失检查接线和电源指示灯重新插拔杜邦线,确认共地,确认 VCC 接 3.3V
Jupyter 启动后浏览器打不开端口被占用、IP 输入错误、防火墙拦截查看启动日志中的 IP 和端口,尝试更换端口使用--port=8889重新启动,或在同一局域网访问
执行 ServoKit 代码时报 I2C 地址错误库默认地址与硬件地址不一致i2cdetect扫描实际地址初始化时传入address=0x40参数,或者调整硬件跳线
舵机在 0 度或 180 度位置抖动脉宽上下限设置不合理set_pulse_width_range逐个测试调整最小和最大脉宽值,缩小到舵机实际支持范围
多个舵机同时动作时异常抖动电源电流不足、电压跌落用万用表测量舵机供电电压换成 5V 5A 以上电源,或者减少同时动作的舵机数量
舵机完全没有反应通道接错、信号线没接触好、库初始化失败确认舵机信号线接入的 PCA9685 通道号用同一个通道接已知正常的舵机测试
Jupyter 执行代码后按钮一直无响应单元格内部陷入死循环、进程卡死点击内核重启(Kernel -> Restart)重启内核后重新执行,避免过长的while True循环
换源后 apt 安装失败软件源配置有误检查/etc/apt/sources.list确认源地址可用,执行sudo apt update

这些排查思路覆盖了最常见的硬件和软件问题。其中比较高频的是接线和电源问题,尤其是“共地”这个概念,第一次做的人很容易忽略。

9. 最佳实践与扩展方向

9.1 工程化建议

在 Jupyter 里调试好动作逻辑之后,建议把校准参数和动作序列单独整理成配置文件,不要硬编码在代码里。例如用 JSON 保存每个舵机的角度上下限和默认初始角度:

{ "servo_config": { "0": {"min_angle": 0, "max_angle": 180, "init_angle": 90}, "1": {"min_angle": 20, "max_angle": 160, "init_angle": 60}, "2": {"min_angle": 30, "max_angle": 150, "init_angle": 30}, "3": {"min_angle": 0, "max_angle": 90, "init_angle": 0} } }

这样在调整机械结构或者更换舵机后,只需要修改配置文件,不用翻代码找角度数字。动作序列也可以放到独立的 JSON 文件里,配合前面的run_action函数读取执行。

批量任务运行时,建议在每个动作序列执行前记录日志,包括当前时间戳、每个舵机的目标角度和实际执行状态。后续排查问题时会非常方便。如果计划长期运行,可以把 Jupyter 里的逻辑导出为.py文件,再用systemd做成开机自启服务,让树莓派在断电重启后自动恢复机械臂控制能力。

9.2 扩展方向:摄像头视觉抓取

这套系统最常见的扩展方向是摄像头视觉抓取。树莓派接上 ov5647 摄像头模块后,可以在同一套 Jupyter 环境里跑 OpenCV 完成颜色识别或者简单目标检测,识别到目标后输出目标在画面中的位置,再根据位置换算成机械臂各关节的目标角度,最后调用舵机控制函数完成抓取。

基本的扩展流程是:摄像头获取图像 -> 图像处理识别目标中心坐标 -> 坐标映射到机械臂底座旋转角度和肩部角度 -> 调用 ServoKit 执行动作。整个过程可以继续在 Jupyter 里逐步调试。如果识别准确率不够,先打印中间图像结果,确认图像处理的每个环节都正常,再和舵机控制对接。

另外,如果你在做的是 ROS 机械臂开发,PCA9685 更多是作为底层执行器。可以先在 Jupyter 里把舵机控制校准完成,再通过 ROS 的话题和服务方式,把角度指令转发给舵机控制程序。这样可以避免直接在 ROS 节点里调硬件时出现大量标定问题。

最后说一个实际经验

做树莓派机械臂最容易忽略的事情不是代码,而是“先让小范围动作跑通,再做大范围联动”。第一次上电时,先用 Jupyter 给每个舵机设定 90 度或者 0 度,确认机械结构不会卡死,再逐步扩大动作范围。同时,一定要把舵机供电和树莓派供电分开,用独立电源解决电流问题。前面 80% 的异常抖动和随机复位,基本都是电源和接线导致的,真正需要在 Python 代码里排查的问题反而不多。

这套环境搭好之后,后续做视觉抓取、动作轨迹规划、ROS 集成都能复用同一套校准数据。建议收藏备用,下次遇到 PCA9685 或者树莓派机械臂项目时,可以直接照着这篇文章把链路跑通。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询