16浏览
查看: 16|回复: 3

[项目] 【Arduino 动手做】使用PCA9685模块控制16台伺服电机

[复制链接]
本帖最后由 驴友花雕 于 2025-6-30 18:13 编辑

使用PCA9685模块与Arduino Uno R4(V2)控制16台伺服电机的简明方案

1. 核心硬件配置
PCA9685模块:
16通道PWM输出,支持I²C通信(地址可配置,默认0x40)。
每通道输出频率20Hz-1.5kHz可调,分辨率12位(4096级),适合伺服电机控制。
Arduino Uno R4(V2):
主控板,通过I²C接口与PCA9685通信,释放主控PWM资源。
伺服电机:
16台标准舵机(如SG90、MG996R),需5V电源供电,信号线接PCA9685通道。

2. 硬件连接
PCA9685与Arduino:
SDA → Arduino A4(或板载SDA引脚)
SCL → Arduino A5(或板载SCL引脚)
VCC → 5V(若电机功率低)或外部电源(推荐)
GND → 共地
伺服电机连接:
每台伺服电机的信号线接PCA9685的PWM0-PWM15通道。
电机电源线(红/棕)接独立5V电源(避免Arduino供电不足)。

3. 软件实现
库依赖:
安装Adafruit_PWMServoDriver库(支持PCA9685高级控制)。

关键代码逻辑:

  1. #include <Wire.h>
  2. #include <Adafruit_PWMServoDriver.h>
  3. Adafruit_PWMServoDriver pca = Adafruit_PWMServoDriver(); // 默认I²C地址0x40
  4. void setup() {
  5.   pca.begin();  // 初始化PCA9685
  6.   pca.setPWMFreq(50); // 设置PWM频率为50Hz(标准舵机频率)
  7. }
  8. void loop() {
  9.   // 控制第0通道伺服电机转至90度(脉冲宽度1500μs)
  10.   pca.setPWM(0, 0, angleToPulse(90));
  11.   // 类似控制其他通道(1-15)
  12.   delay(1000);
  13. }
  14. // 将角度转换为PCA9685的脉冲值(0-4095对应0.5ms-2.5ms)
  15. int angleToPulse(int angle) {
  16.   int pulse = map(angle, 0, 180, 150, 600); // 150=0.5ms, 600=2.5ms(50Hz下)
  17.   return pulse * (4096 / 20000); // 转换为12位分辨率值
  18. }
复制代码


4. 关键注意事项
电源管理:
伺服电机总电流可能超过Arduino的5V输出能力,必须使用独立电源(如4节AA电池或开关电源)。
电源负极需与Arduino共地。
I²C地址冲突:
若需连接多个PCA9685,通过A0-A5引脚配置不同地址(如0x40-0x4F)。
频率匹配:
伺服电机通常需要50Hz PWM信号,PCA9685需通过setPWMFreq(50)设置。
实时性优化:
避免在loop()中执行耗时操作,建议使用非阻塞控制(如定时器中断)。

5. 扩展功能
多板级联:
通过I²C扩展多个PCA9685,最多可控制16×N台伺服电机(N为模块数量)。
动态控制:
结合传感器输入(如电位器、蓝牙模块)实现交互式控制。

6. 典型应用场景
六足机器人关节控制
机械臂多自由度运动
动态灯光秀(需兼容LED控制)
此方案通过PCA9685的I²C扩展能力,高效解放了Arduino的PWM资源,适合需要同时控制多台伺服电机的低成本项目。

【Arduino 动手做】使用PCA9685模块控制16台伺服电机图3

【Arduino 动手做】使用PCA9685模块控制16台伺服电机图1

【Arduino 动手做】使用PCA9685模块控制16台伺服电机图4

【Arduino 动手做】使用PCA9685模块控制16台伺服电机图5

【Arduino 动手做】使用PCA9685模块控制16台伺服电机图2


驴友花雕  中级技神
 楼主|

发表于 5 小时前

【Arduino 动手做】使用 PCA9685 模块控制 16 台伺服电机

项目代码

  1. /*
  2. * Original sourse: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
  3. *
  4. * This is the Arduino code PAC6985 16 channel servo controller
  5. * watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
  6. *  This code is #1 for V2 Video Watch the video :https://youtu.be/bal2STaoQ1M
  7. *  I have got 3 codes as follow:
  8.    #1-Arduino Code to run one by one all servos from 0 to 180�   
  9.    #2-Arduino Code to control specific servos with specific angle
  10.    #3-Arduino Code to run 2 or all servos at together
  11.    
  12. * Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
  13. * Date: Dec 16, 2017, in Ajax, Ontario, Canada
  14. * Watch video for this code:
  15. *
  16. * Related Videos
  17. V5 video of PCA9685 32 Servo with ESP32 with WiFi https://youtu.be/bvqfv-FrrLM
  18. V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
  19. V3 video of PCA9685 how to control 32 Servo motors https://youtu.be/6P21wG7N6t4
  20. V2 Video of PCA9685 3 different ways to control Servo motors: https://youtu.be/bal2STaoQ1M
  21. V1 Video introduction to PCA9685 to control 16 Servo  https://youtu.be/y8X9X10Tn1k
  22. * Disclaimer: this code is "AS IS" and for educational purpose only.
  23. * this code has been downloaded from http://robojax.com/learn/arduino/
  24. * Get this code and other Arduino codes from Robojax.com
  25. Learn Arduino step by step in structured course with all material, wiring diagram and library
  26. all in once place. Purchase My course on Udemy.com http://robojax.com/L/?id=62
  27. ****************************
  28. Get early access to my videos via Patreon and have  your name mentioned at end of very
  29. videos I publish on YouTube here: http://robojax.com/L/?id=63 (watch until end of this video to list of my Patrons)
  30. ****************************
  31. or make donation using PayPal http://robojax.com/L/?id=64
  32. *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
  33. * This code has been download from Robojax.com
  34.     This program is free software: you can redistribute it and/or modify
  35.     it under the terms of the GNU General Public License as published by
  36.     the Free Software Foundation, either version 3 of the License, or
  37.     (at your option) any later version.
  38.     This program is distributed in the hope that it will be useful,
  39.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  40.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  41.     GNU General Public License for more details.
  42.     You should have received a copy of the GNU General Public License
  43.     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  44. */
  45. /***************************************************
  46.   This is an example for our Adafruit 16-channel PWM & Servo driver
  47.   Servo test - this will drive 16 servos, one after the other
  48.   Pick one up today in the adafruit shop!
  49.   ------> http://www.adafruit.com/products/815
  50.   These displays use I2C to communicate, 2 pins are required to  
  51.   interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4
  52.   Adafruit invests time and resources providing this open source code,
  53.   please support Adafruit and open-source hardware by purchasing
  54.   products from Adafruit!
  55.   Written by Limor Fried/Ladyada for Adafruit Industries.  
  56.   BSD license, all text above must be included in any redistribution
  57. ****************************************************/
  58. #include <Wire.h>
  59. #include <Adafruit_PWMServoDriver.h>
  60. // called this way, it uses the default address 0x40
  61. Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
  62. // you can also call it with a different address you want
  63. //Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
  64. // Depending on your servo make, the pulse width min and max may vary, you
  65. // want these to be as small/large as possible without hitting the hard stop
  66. // for max range. You'll have to tweak them as necessary to match the servos you
  67. // have!
  68. // Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
  69. #define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
  70. #define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)
  71. // our servo # counter
  72. uint8_t servonum = 0;
  73. void setup() {
  74.   Serial.begin(9600);
  75.   Serial.println("16 channel Servo test!");
  76.   pwm.begin();
  77.   
  78.   pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  79.   //yield();
  80. }
  81. // the code inside loop() has been updated by Robojax
  82. void loop() {
  83. //watch video for details: https://youtu.be/bal2STaoQ1M
  84. for(int i=0; i<16; i++)
  85.   {
  86.     for( int angle =0; angle<181; angle +=10){
  87.       delay(50);
  88.         pwm.setPWM(i, 0, angleToPulse(angle) );
  89.         // see YouTube video for details (robojax)
  90.       
  91.     }
  92.   }
  93.   // robojax PCA9865 16 channel Servo control
  94.   delay(1000);// wait for 1 second
  95. }
  96. /*
  97. /* angleToPulse(int ang)
  98. * @brief gets angle in degree and returns the pulse width
  99. * @param "ang" is integer represending angle from 0 to 180
  100. * @return returns integer pulse width
  101. * Usage to use 65 degree: angleToPulse(65);
  102. * Written by Ahmad Shamshiri on Sep 17, 2019.
  103. * in Ajax, Ontario, Canada
  104. * www.Robojax.com
  105. */
  106. int angleToPulse(int ang){
  107.    int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
  108.    Serial.print("Angle: ");Serial.print(ang);
  109.    Serial.print(" pulse: ");Serial.println(pulse);
  110.    return pulse;
  111. }
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 5 小时前

【Arduino 动手做】使用 PCA9685 模块控制 16 台伺服电机

项目代码之二
  1. ++
  2. /*
  3. * Original library source: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
  4. *
  5. * This is the Arduino code for the PCA6985 16-channel servo controller
  6. * to control 32 servo motors with an ESP32 board
  7. *
  8. * This is V3 Video on PCA9685: https://youtu.be/JFdXB8Za5Os
  9. *
  10. * Watch video for this code:
  11. *
  12. * Related Videos:
  13. V5 video of PCA9685 32 Servo with ESP32 with WiFi: https://youtu.be/bvqfv-FrrLM
  14. V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
  15. V3 video of PCA9685 how to control 32 servo motors: https://youtu.be/6P21wG7N6t4
  16. V2 Video of PCA9685 3 different ways to control servo motors: https://youtu.be/bal2STaoQ1M
  17. V1 Video introduction to PCA9685 to control 16 servos: https://youtu.be/y8X9X10Tn1k
  18. *  
  19.    
  20. * Written/updated by Ahmad Shamshiri for Robojax Video channel, www.Robojax.com
  21. * Date: Dec 15, 2019, in Ajax, Ontario, Canada
  22. * Disclaimer: this code is "AS IS" and for educational purposes only.
  23. * this code has been downloaded from http://robojax.com/learn/arduino/
  24. * Get this code and other Arduino codes from Robojax.com.
  25. Learn Arduino step by step in a structured course with all material, wiring diagrams, and libraries
  26. all in one place. Purchase my course on Udemy.com: http://robojax.com/L/?id=62
  27. ****************************
  28. Get early access to my videos via Patreon and have your name mentioned at the end of every
  29. video I publish on YouTube here: http://robojax.com/L/?id=63 (watch until the end of this video for a list of my Patrons)
  30. ****************************
  31. or make a donation using PayPal: http://robojax.com/L/?id=64
  32. *  * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
  33. * This code has been downloaded from Robojax.com
  34.     This program is free software: you can redistribute it and/or modify
  35.     it under the terms of the GNU General Public License as published by
  36.     the Free Software Foundation, either version 3 of the License, or
  37.     (at your option) any later version.
  38.     This program is distributed in the hope that it will be useful,
  39.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  40.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  41.     GNU General Public License for more details.
  42.     You should have received a copy of the GNU General Public License
  43.     along with this program.  If not, see <https://www.gnu.org/licenses/>.
  44. */
  45. #include <Wire.h>
  46. #include <Adafruit_PWMServoDriver.h>
  47. // called this way, it uses the default address 0x40
  48. Adafruit_PWMServoDriver board1 = Adafruit_PWMServoDriver(0x40);
  49. Adafruit_PWMServoDriver board2 = Adafruit_PWMServoDriver(0x41);
  50. // Depending on your servo make, the pulse width min and max may vary, you
  51. // want these to be as small/large as possible without hitting the hard stop
  52. // for max range. You'll have to tweak them as necessary to match the servos you
  53. // have!
  54. // Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
  55. #define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
  56. #define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)
  57. int servoNumber = 0;
  58. void setup() {
  59.   Serial.begin(9600);
  60.   Serial.println("32 channel Servo test!");
  61.   board1.begin();
  62.   board2.begin();  
  63.   board1.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  64.   board2.setPWMFreq(60);
  65.   //yield();
  66. }
  67. // the code inside loop() has been updated by Robojax
  68. void loop() {
  69.     for( int angle =0; angle<181; angle +=10){
  70.       for(int i=0; i<16; i++)
  71.         {      
  72.             board2.setPWM(i, 0, angleToPulse(angle) );
  73.             board1.setPWM(i, 0, angleToPulse(angle) );
  74.         }
  75.     }
  76.   
  77. // robojax PCA9865 16 channel Servo control
  78.   delay(100);
  79. }
  80. /*
  81. * angleToPulse(int ang)
  82. * gets angle in degree and returns the pulse width
  83. * also prints the value on serial monitor
  84. * written by Ahmad Nejrabi for Robojax, Robojax.com
  85. */
  86. int angleToPulse(int ang){
  87.    int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
  88.    Serial.print("Angle: ");Serial.print(ang);
  89.    Serial.print(" pulse: ");Serial.println(pulse);
  90.    return pulse;
  91. }
复制代码




回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 5 小时前

【Arduino 动手做】使用 PCA9685 模块控制 16 台伺服电机

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail