在本教程中,我们将学习伺服电机的工作原理以及如何使用 Arduino 和 PCA9685 PWM 驱动器控制多个伺服电机。
概述
伺服电机的种类很多,其主要特点是能够精确控制轴的位置。伺服电机是一个闭环系统,它使用位置反馈来控制其运动和最终位置。
图2
在本教程中,我们将详细介绍业余伺服电机。我们将解释这些伺服系统的工作原理以及如何使用 Arduino 控制它们。
图8
我们只需要将舵机的控制引脚连接到 Arduino 板的任何数字引脚,将地线和正极线连接到外部 5V 电源,并将 Arduino 地线连接到舵机地。
Arduino伺服电机控制代码
现在让我们来看看控制伺服电机的 Arduino 代码。代码非常简单。我们只需要定义伺服所连接的引脚,将该引脚定义为输出,然后在循环部分生成具有特定持续时间和频率的脉冲,如前所述。
/*伺服电机控制 – 50Hz 脉冲串发生器作者:Dejan,https://howtomechatronics.com*/#define servoPin 9void setup() {pinMode(servoPin, OUTPUT);}void loop() {// A pulse each 20msdigitalWrite(servoPin, HIGH);delayMicroseconds(1450); // Duration of the pusle in microsecondsdigitalWrite(servoPin, LOW);delayMicroseconds(18550); // 20ms – duration of the pusle// Pulses duration: 600 – 0deg; 1450 – 90deg; 2300 – 180deg}
经过一些测试后,总结出这个伺服系统的脉冲持续时间与角度有以下关系:持续时间为 0.6ms 的脉冲对应于 0 度位置,1.45ms 对应于 90 度,2.3ms 对应于 180 度。
我将万用表与伺服串联连接以检查电流消耗。我注意到的最大电流消耗在堵转时高达 0.63A。那是因为这不是原来的 TowerPro MG996R 舵机,而是更便宜的复制品,显然性能更差。
图9
尽管如此,让我们来看看使用 Arduino 控制伺服系统的更方便的方法。那是使用 Arduino 伺服库。
/*使用 Arduino 伺服库控制伺服电机作者:Dejan,https://howtomechatronics.com*/#include Servo myservo; // 创建伺服对象来控制伺服void setup() {myservo.attach(9,600,2300); // (pin, min, max)}void loop() {myservo.write(0); // 告诉伺服器转到特定角度delay(1000);myservo.write(90);delay(500);myservo.write(135);delay(500);myservo.write(180);delay(1500);}
在这里,我们只需要包含库,定义伺服对象,并使用 attach() 函数定义伺服连接到的引脚以及定义脉冲持续时间的最小值和最大值。然后使用 write() 函数,我们只需将伺服的位置设置为 0 到 180 度。使用这个库,我们可以同时驱动多达 12 个舵机或使用 Arduino Mega 板驱动 48 个舵机。
Arduino 和 PCA9685 PWM/伺服驱动器
还有另一种使用 Arduino 控制伺服系统的方法,那就是使用 PCA9685 伺服驱动器。这是一个 16 通道 12 位 PWM 伺服驱动器,它使用 I2C 总线与 Arduino 通信。它有一个内置时钟,因此它可以驱动 16 个自由运行的伺服系统,独立于 Arduino。
图10
更酷的是,我们可以在单个 I2C 总线上以链式连接多达 62 个这些驱动器。因此理论上我们可以仅使用 Arduino 板上的两个 I2C 引脚来控制多达 992 个伺服系统。6 个地址选择引脚用于为每个附加驱动器设置不同的 I2C 地址。我们只需要根据这张表连接焊盘。
图11
这是电路原理图,我们可以再次注意到,我们需要为伺服系统单独供电。
图12
现在让我们来看看 Arduino 代码。为了控制这个伺服驱动器,我们将使用可以从GitHub下载的 PCA9685 库。
PCA9685 Arduino 代码
/*使用 Arduino 和 PCA9685 驱动程序控制伺服电机作者:Dejan,https://howtomechatronics.com库:https://github.com/NachtRaveVL/PCA9685-Arduino*/#include #include “PCA9685.h”PCA9685 driver;// PCA9685 输出 = 12 位 = 4096 步// 20ms 的 2.5% = 0.5ms ; 20ms 的 12.5% = 2.5ms// 4096 的 2.5% = 102 步;4096 的 12.5% = 512 步PCA9685_ServoEvaluator pwmServo ( 102, 470 ) ; // (-90deg, 90deg)// 第二个伺服// PCA9685_ServoEvaluator pwmServo2(102, 310, 505); // (0deg, 90deg, 180deg)void setup() {Wire.begin(); // Wire must be started firstWire.setClock(400000); // Supported baud rates are 100kHz, 400kHz, and 1000kHzdriver.resetDevices(); // Software resets all PCA9685 devices on Wire linedriver.init(B000000); // Address pins A5-A0 set to B000000driver.setPWMFrequency(50); // Set frequency to 50Hz}void loop() {driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));delay(1000);driver.setChannelPWM(0, pwmServo.pwmForAngle(0));delay(1000);driver.setChannelPWM(0, pwmServo.pwmForAngle(90));delay(1000);}
首先我们需要包含库并定义 PCA9685 对象。然后使用 Servo_Evaluator 实例定义驱动器的脉冲持续时间或 PWM 输出。请注意,输出为 12 位,或者分辨率为 4096 步。因此,0.5ms 或 0 度位置的最小脉冲持续时间将对应 102 步,而 2.5ms 或 180 度位置的最大脉冲持续时间将对应 512 步。但如前所述,这些值应根据您的伺服电机进行调整。在我的例子中,从 102 到 470 的值对应于 0 到 180 度的位置。
在setup部分,我们需要定义 I2C 时钟速率,设置驱动程序地址并将频率设置为 50Hz。
在loop循环部分,使用 setChannelPWM() 和 pwmForAngle() 函数,我们只需将伺服设置为所需的角度。
我将第二个伺服器连接到驱动器,正如我预期的那样,它的定位与第一个不同,这是因为我使用的伺服器是廉价的版本,它们不太可靠。然而,这不是一个大问题,因为使用 Servo_Evaluator 实例我们可以为每个伺服设置不同的输出设置。我们还可以调整 90 度位置,以防它不是正好在中间。这样所有的舵机都将工作相同并以准确的角度定位。
使用 Arduino 和 PCA9685 驱动程序控制许多伺服系统
我们将再看一个示例,该示例使用多个链接的 PCA9685 驱动器控制许多伺服系统。
图13
为此,我们需要将驱动器相互连接并连接适当的地址选择焊盘。下面是电路原理图:
图14
现在让我们来看看 Arduino 代码。
/*使用 Arduino 和 PCA9685 驱动程序控制伺服电机作者:Dejan,https://howtomechatronics.com库:https://github.com/NachtRaveVL/PCA9685-Arduino*/#include #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 stepsPCA9685_ServoEvaluator pwmServo(102, 470); // (-90deg, 90deg)// Second ServoPCA9685_ServoEvaluator pwmServo2(102, 310, 505); // (0deg, 90deg, 180deg)void setup() {Wire.begin(); // Wire must be started firstWire.setClock(400000); // Supported baud rates are 100kHz, 400kHz, and 1000kHzdriver.resetDevices(); // Software resets all PCA9685 devices on Wire linedriver.init(B000000); // Address pins A5-A0 set to B000000driver.setPWMFrequency(50); // Set frequency to 50Hz}void loop() {driver.setChannelPWM(0, pwmServo.pwmForAngle(-90));delay(1000);driver.setChannelPWM(0, pwmServo.pwmForAngle(0));delay(1000);driver.setChannelPWM(0, pwmServo.pwmForAngle(90));delay(1000);}
所以我们应该为每个驱动程序创建单独的 PCA9685 对象,为每个驱动程序定义地址并将频率设置为 50Hz。现在只需使用 setChannelPWM() 和 pwmForAngle() 函数,我们就可以在任何驱动器上设置任何伺服以定位我们想要的任何角度。
如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。