PCA9685舵机驱动板:接线、I2C地址、驱动代码全流程

2026-11-06 07:14:11 30阅读

想给桌面机械臂或者六足平台装一把以上的舵机,很快就会撞上同一个问题:Arduino 的 PWM 引脚根本不够分,而且软件生成多路 PWM 还要吃掉主控的运算余量。这一篇把 PCA9685 这块 16 路舵机驱动板的用法一次理顺:怎么接主控、I2C 地址怎么配、代码怎么写,参数全部对照 NXP 芯片资料和原厂教程页核对过。

PCA9685与Arduino及舵机接线图

一块板解决PWM引脚不够用

PCA9685 是 NXP Semiconductors 出的 16 通道、12 位分辨率、I2C 总线控制的 PWM 驱动芯片,常见的蓝色扩展板就是围绕它做的。它只占主控两个引脚(SDA 和 SCL),就能同时驱动 16 路舵机;更狠的是最多可以级联 62 块板,一路 I2C 总线控制到 992 路舵机。

关键在于 PWM 信号由 PCA9685 芯片自己生成,主控只发一条 I2C 命令设定角度,之后维持位置所需的全部刷新都由它完成。芯片内置振荡器,不需要外接时钟。对舵机玩家来说,这意味着 Arduino 把算力省下来做运动学或者传感器融合, PWM 这种苦力活外包出去了。

板子上都有什么

先看板面布局。左侧 1x6 排针是逻辑接口,右侧 16 组三排彩色排座是舵机输出口,编号 0 到 15,颜色和舵机线序一一对应:PWM、V+、GND。还有电源指示 LED、一颗大容量电解电容和两脚电源接线端子。

PCA9685模块引脚图

几个核心参数记一下:12 位分辨率对应 4096 级占空比,PWM 频率范围约 24Hz 到 1526Hz,驱动舵机常用 50Hz。16 个通道各自独立,但同一块板上所有通道必须用同一个 PWM 频率。逻辑电平 3.3V 和 5V 都兼容,接 ESP32 这类 3.3V 主控也不用担心。

那颗电解电容不是摆设。舵机启动和堵转时电流波动很大,它负责稳住供电电压,减少尖峰。两脚端子 V+ 建议给 5 到 6V 直流,专门给舵机供电用。

I2C地址怎么配

一块板不用管,默认地址 0x40。要挂多块板时,就得靠板子右上角的地址选择跳线(A0 到 A5 焊盘)来区分:桥接 A0 变成 0x41,桥接 A1 变成 0x42,A0 和 A1 都桥接就是 0x43。跳线设定的二进制值直接叠加在 0x40 基址上,照这个规则给每块板分配互不冲突的地址即可。

PCA9685 I2C地址选择跳线对照表

级联也不复杂:模块两端各有一组 1x6 排针,定义完全相同,用六芯并行排线把一块板连到下一块就行,背面的空排针也可以补焊后当输入用。唯一要记牢的是每块板的地址跳线必须设成不同值,否则 I2C 总线上会撞车。

多块PCA9685模块级联接线

接线:两根信号线加一路独立电源

逻辑侧四根线:GND 接 Arduino 的 GND,SDA 接 A4,SCL 接 A5,VCC 接 5V。这是 Uno 的标准 I2C 位置,其他板子按各自的 SDA/SCL 引脚来。

舵机侧的线序是棕色或黑色线(GND)靠下、信号线(橙、黄或白)朝上,对准排座插进去就行。

重点说一下供电,这是最容易翻车的地方。小型舵机运转时也要几百毫安,大扭矩舵机堵转能到 1A 以上,六路同时动,电流轻松破几安。用 Arduino 的 5V 引脚直接带舵机,噪声和电压跌落会让主控莫名其妙重启甚至过热。正确做法是给两脚接线端子接一路独立的 5 到 6V 电源,专供舵机,和主控各走各的。

另外 1x6 排针上的 OE 引脚是输出使能,拉高关闭全部输出、拉低使能,板载下拉电阻让它默认就是使能状态,一般悬空不用管。

装库写代码,50Hz扫摆跑起来

库用 NachtRaveVL 的 PCA9685 16-channel PWM Driver Module Library。在 Arduino IDE 左侧点 Library Manager 图标,搜 PCA9685,认准作者 NachtRaveVL,点 Install 就行。

官方示例是让接在通道 0 和 1 的两个舵机在 180 度范围内来回扫摆。代码机械照搬如下,唯一改动是把尖括号头文件写成了引号形式,因为站点编辑器会剥掉尖括号,两种写法在 Arduino 工具链下对库搜索路径是等价的:

#include "Wire.h"
#include "PCA9685.h"

PCA9685 driver;
// PCA9685 outputs = 12-bit = 4096 steps
// 2.5% of 20ms = 0.5ms ; 12.5% of 20ms = 2.5ms
// 2.5% of 4096 = 102 steps; 12.5% of 4096 = 512 steps
// we will use 112 and 500 to avoid pushing the servo to its physical limits
PCA9685_ServoEval pwmServo(112, 500); // (-90deg, +90deg)

void setup() {
  Wire.begin();                 // Wire must be started first
  driver.resetDevices();        // Software resets all PCA9685 devices on Wire line
  driver.init();
  driver.setPWMFrequency(50);   // Set frequency to 50Hz
}

void loop() {
  driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));
  driver.setChannelPWM(1, pwmServo.pwmForAngle(-90));
  delay(1000);
  driver.setChannelPWM(0, pwmServo.pwmForAngle(0));
  driver.setChannelPWM(1, pwmServo.pwmForAngle(0));
  delay(1000);
  driver.setChannelPWM(0, pwmServo.pwmForAngle(90));
  driver.setChannelPWM(1, pwmServo.pwmForAngle(90));
  delay(1000);
}

讲一下这段代码的逻辑。PCA9685_ServoEval 这个类的两个参数 112 和 500,定义的是 -90 度和 +90 度对应的 PWM 步进边界:舵机信号周期 20ms(也就是 50Hz),0.5ms 脉宽约占空比 2.5%,对应 4096 级里的约 102 步;2.5ms 脉宽占 12.5%,对应约 512 步。示例取 112 和 500,稍微收一点边,避免把舵机顶到机械极限。

setup() 里顺序有讲究:Wire.begin() 必须最先,然后 resetDevices() 软复位总线上所有 PCA9685,再 init() 初始化驱动对象,最后 setPWMFrequency(50) 把全部通道定到舵机标准的 50Hz。

loop() 里就是 setChannelPWM 加 pwmForAngle 的组合:通道 0 和 1 先转到 -90 度停一秒,回 0 度停一秒,再到 +90 度停一秒,无限循环。要控制其他通道,把第一个参数换成对应编号即可。

写在最后

PCA9685 的价值就一句话:两根线换十六路舵机,算力还给主控。对六足、机械臂、多自由度云台这类舵机大户,它几乎是绕不开的扩展件。上手成本也低,一下午能跑通。真正要多花心思的只有两件事:供电别偷懒用主控 5V,多板级联时地址跳线别重复。把这两点守住,剩下的就是往代码里填你自己的动作序列了。


作者:舵机老炮
链接:https://www.aiddithome.com/p/df88d0e14477.html
本作版权归作者所有,未经允许请勿转载。若存在违规行为,您可以点击 “举报”。


登录 后发表评论
4条评论
阿伟不emo
1楼 · 1天前

这篇把我之前一直没搞明白的地址跳线讲清楚了,原来A0到A5是在0x40基础上往上加的,之前盲猜地址踩过坑,白折腾一下午。

拆机党
2楼 · 1天前

供电那段说到点子上了,当年用Arduino 5V带四个SG90,舵机一动板子就重启,换独立电源立马好。新手务必记住这条。

探头看一眼
3楼 · 1天前

收藏了,正准备给我的六足换PCA9685方案

线比代码多
4楼 · 1天前

112和500那两个数算的是4096级里的步进,注释里写得很清楚,比很多教程直接甩个魔数不给解释强多了。50Hz对应20ms周期,0.5ms和2.5ms脉宽换算下来就是这个区间,例子还留了点余量不顶机械极限,细节到位。