本教程是的一部分: 使用 PCA9685 控制 16 或 32 伺服电机
这套包含视频教程的合集将帮助您使用 Arduino UNO、Nano、Mini 或 ESP32 控制 32 个或更多伺服电机。所有代码均已提供。
使用PCA9685模块和Arduino V2草图逐个控制16个伺服电机
在本教程中,我们将学习如何使用 PCA9685 模块和 Arduino 控制多达 16 个伺服电机。PCA9685 是一个 16 通道、12 位 PWM 控制器,可以精确控制伺服电机。通过遵循本指南,您将能够单独控制每个伺服电机并将其设置为特定角度,从而实现多种机器人动作。
我们将首先讨论您在此项目中需要的硬件组件,然后提供详细的接线说明。之后,我们将逐步讲解代码,突出关键标识符及其在控制伺服电机中的作用。为了更清楚的理解,您可以参考附带的视频(视频在:00)。
硬件解析
该项目的主要组件是PCA9685模块,负责生成PWM信号以控制伺服电机。每个伺服电机连接到PCA9685的16个通道之一,允许独立控制。该模块使用I2C协议与Arduino通信,仅需要两根线:SDA和SCL。
除了PCA9685,你还需要一个Arduino开发板、16个伺服电机和一个外部电源。外部电源至关重要,因为单靠Arduino可能无法提供足够的电流同时驱动所有伺服电机。每个伺服电机通常在5V下工作,因此请确保你的电源满足这一要求。
数据表详细信息
| 制造商 | 恩智浦半导体 |
|---|---|
| 零件编号 | PCA9685 |
| 逻辑/IO电压 | 2.3 - 5.5 V |
| 供电电压 | 5 V |
| 输出电流(每通道) | 25 毫安 |
| PWM频率指导 | 60赫兹 |
| 输入逻辑阈值 | 0.3VCC(低)/ 0.7VCC(高) |
| 电压降 / RDS(开)/ 饱和度 | - |
| 热限制 | - |
| 包裹 | TSSOP-28 / VQFN-28 |
| 备注 / 变体 | - |
- 为伺服电机连接一个外部5V电源。
- 使用I2C进行通信,将SDA连接到Arduino上的A4,将SCL连接到A5。
- 确保Arduino和PCA9685之间的所有接地都是共用的。
- 根据使用的特定伺服电机调整脉冲宽度。
- 如果同时为多个伺服电机供电,请保持 PCA9685 的适当冷却。
接线说明
要将PCA9685模块连接到Arduino和伺服电机,首先将外部5V电源连接到PCA9685的V+端子。将电源的地线连接到PCA9685的地线端子以及Arduino的地线。
接下来,将PCA9685上的SDA和SCL引脚连接到Arduino上的相应引脚(SDA连接到A4,SCL连接到A5)。每个伺服电机都有三根线:接地线(通常是黑色或棕色)、VCC线(通常是红色)和信号线(通常是黄色或白色)。将每个伺服电机的接地线连接到PCA9685的接地端子,VCC线连接到V+端子,信号线连接到PCA9685上的各自通道(0-15)。确保每个伺服电机的信号线按正确的顺序连接。
代码示例与演练
我们现在将逐一查看控制伺服电机的代码。代码首先导入用于I2C通信和PCA9685模块的必要库。以下摘录初始化了PCA9685对象:
#include
#include
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); // Initialize PCA9685 在设置函数中,我们初始化串口监视器并设置伺服电机的PWM频率:
void setup() {
Serial.begin(9600); // Start serial communication
pwm.begin(); // Initialize PCA9685
pwm.setPWMFreq(60); // Set frequency to 60 Hz for servos
}主循环包含两个嵌套循环:外部循环遍历16个伺服电机,而内部循环逐渐将角度从0变化到180度:
void loop() {
for(int i=0; i<16; i++) {
for(int angle = 0; angle<181; angle += 10) {
delay(50); // Wait for servo to move
pwm.setPWM(i, 0, angleToPulse(angle)); // Set servo position
}
}
delay(1000); // Wait before repeating
}这种结构允许每个伺服以10度的增量移动到其指定角度,从而实现平滑过渡。该功能angleToPulse(int ang)将角度值转换为适合伺服电机的脉冲宽度:
int angleToPulse(int ang) {
int pulse = map(ang, 0, 180, SERVOMIN, SERVOMAX); // Map angle to pulse width
return pulse; // Return pulse width
}此功能对于将所需角度转换为PCA9685可以理解并传输到伺服电机的PWM信号至关重要。有关更多详细信息,请记得在文章下方加载完整代码。
演示 / 预期内容
一旦一切连接正确并且代码上传完毕,你应该会看到每个舵机依次移动到其各自的角度。如果遇到任何问题,请仔细检查连接,确保为舵机提供稳定的电源。如果舵机的响应不如预期,请确认通过PCA9685发送的PWM信号。
视频时间戳
- 00:00 带有芯片PCA9685的模块详情
- 06:14 添加PCA9685所需的库
- 07:14 正在加载示例代码
- 07:35 代码讲解
- 11:31 简化的 Arduino PCA9685 代码
- 12:00 为你的伺服电机找到最小值和最大值
- 18:27 映射脉冲角度到脉冲宽度
- 20:05 创建用于映射的单独方法
- 20:55 使用 for 循环测试所有角度以进行映射
本教程是……的一部分: 使用 PCA9685 控制 16 或 32 伺服电机
/*
* Original source: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
* PCA9685 Video V2, Arduino Code-1
* This is the Arduino code PAC6985 16 channel servo controller
* watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
* This code is #1 for V2 Video Watch the video :https://youtu.be/bal2STaoQ1M
get this code and wiring from https://robojax.com/RTJ243
* I have got 3 codes as follow:
#1-Arduino Code to run one by one all servos from 0 to 180°
#2-Arduino Code to control specific servos with specific angle
#3-Arduino Code to run 2 or all servos at together
* Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
* Date: Dec 16, 2017, in Ajax, Ontario, Canada
* Watch video for this code:
*
* Related Videos
V5 video of PCA9685 32 Servo with ESP32 with WiFi https://youtu.be/bvqfv-FrrLM
V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
V3 video of PCA9685 how to control 32 Servo motors https://youtu.be/6P21wG7N6t4
V2 Video of PCA9685 3 different ways to control Servo motors: https://youtu.be/bal2STaoQ1M
V1 Video introduction to PCA9685 to control 16 Servo https://youtu.be/y8X9X10Tn1k
* Disclaimer: this code is "AS IS" and for educational purpose only.
* this code has been downloaded from https://robojax.com
or make donation using PayPal http://robojax.com/L/?id=64
* * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been download from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/***************************************************
This is an example for our Adafruit 16-channel PWM & Servo driver
Servo test - this will drive 16 servos, one after the other
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/815
These displays use I2C to communicate, 2 pins are required to
interface. For Arduino UNOs, thats SCL -> Analog 5, SDA -> Analog 4
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
// Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN 125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 575 // this is the 'maximum' pulse length count (out of 4096)
// our servo # counter
uint8_t servonum = 0;
void setup() {
Serial.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
//yield();
}
// the code inside loop() has been updated by Robojax
void loop() {
//watch video for details: https://youtu.be/bal2STaoQ1M
for(int i=0; i<16; i++)
{
for( int angle =0; angle<181; angle +=10){
delay(50);
pwm.setPWM(i, 0, angleToPulse(angle) );
// see YouTube video for details (robojax)
}
}
// robojax PCA9865 16 channel Servo control
delay(1000);// wait for 1 second
}
/*
/* angleToPulse(int ang)
* @brief gets angle in degree and returns the pulse width
* @param "ang" is integer representing angle from 0 to 180
* @return returns integer pulse width
* Usage to use 65 degree: angleToPulse(65);
* Written by Ahmad Shamshiri on Sep 17, 2019.
* in Ajax, Ontario, Canada
* www.Robojax.com
*/
int angleToPulse(int ang){
int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
Serial.print("Angle: ");Serial.print(ang);
Serial.print(" pulse: ");Serial.println(pulse);
return pulse;
}
/*
* Original sourse: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
* PCA9685 Video V2, Arduino Code-2
* This is the Arduino code PAC6985 16 channel servo controller
* watch the video for details (V1) and demo http://youtu.be/y8X9X10Tn1k
* This code is #2 for V2 Video Watch the video :https://youtu.be/bal2STaoQ1M
get codes and wring from https://robojax.com/RTJ243
* I have got 3 codes as follow:
#1-Arduino Code to run one by one all servos from 0 to 180°
#2-Arduino Code to control specific servos with specific angle
#3-Arduino Code to run 2 or all servos at together
*
* Written/updated by Ahmad Shamshiri for Robojax Video channel www.Robojax.com
* Date: Dec 16, 2017, in Ajax, Ontario, Canada
* Permission granted to share this code given that this
* note is kept with the code.
* Disclaimer: this code is "AS IS" and for educational purpose only.
* this code has been downloaded from https://robojax.com
* Watch video for this code:
*
* Related Videos
V5 video of PCA9685 32 Servo with ESP32 with WiFi https://youtu.be/bvqfv-FrrLM
V4 video of PCA9685 32 Servo with ESP32 (no WiFi): https://youtu.be/JFdXB8Za5Os
V3 video of PCA9685 how to control 32 Servo motors https://youtu.be/6P21wG7N6t4
V2 Video of PCA9685 3 different ways to control Servo motors: https://youtu.be/bal2STaoQ1M
V1 Video introduction to PCA9685 to control 16 Servo https://youtu.be/y8X9X10Tn1k
* Get this code and other Arduino codes from Robojax.com
Learn Arduino step by step in structured course with all material, wiring diagram and library
all in once place. Purchase My course on Udemy.com http://robojax.com/L/?id=62
****************************
Get early access to my videos via Patreon and have your name mentioned at end of very
videos I publish on YouTube here: http://robojax.com/L/?id=63 (watch until end of this video to list of my Patrons)
****************************
or make donation using PayPal http://robojax.com/L/?id=64
* * This code is "AS IS" without warranty or liability. Free to be used as long as you keep this note intact.*
* This code has been download from Robojax.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// you can also call it with a different address you want
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
// Depending on your servo make, the pulse width min and max may vary, you
// want these to be as small/large as possible without hitting the hard stop
// for max range. You'll have to tweak them as necessary to match the servos you
// have!
// Watch video V1 to understand the two lines below: http://youtu.be/y8X9X10Tn1k
#define SERVOMIN 125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 575 // this is the 'maximum' pulse length count (out of 4096)
// our servo # counter
uint8_t servonum = 0;
void setup() {
Serial.begin(9600);
Serial.println("16 channel Servo test!");
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
//yield();
}
// the code inside loop() has been updated by Robojax
void loop() {
//watch video for details: https://youtu.be/bal2STaoQ1M
for(int i=0; i<16; i++)
{
for( int angle =0; angle<181; angle +=10){
delay(50);
pwm.setPWM(5, 0, angleToPulse(angle) );
pwm.setPWM(8, 0, angleToPulse(angle) );
pwm.setPWM(15, 0, angleToPulse(angle) );
}
}
// robojax PCA9865 16 channel Servo control
delay(1000);
}
/*
* angleToPulse(int ang)
* gets angle in degree and returns the pulse width
* also prints the value on seial monitor
* written by Ahmad Shamshiri for Robojax, Robojax.com
*/
int angleToPulse(int ang){
int pulse = map(ang,0, 180, SERVOMIN,SERVOMAX);// map angle of 0 to 180 to Servo min and Servo max
Serial.print("Angle: ");Serial.print(ang);
Serial.print(" pulse: ");Serial.println(pulse);
return pulse;
}
资源与参考
尚无可用资源。
文件📁
没有可用的文件。