有许多电机可供选择,但选择适合工作的合适电机非常重要。如果您的项目需要精确定位,伺服电机通常是最佳选择。指示他们指向哪里,他们就会为您做。就这么简单!
它们可用于各种机器人项目,例如控制遥控的前轮或旋转机器人车辆上的传感器。
什么是伺服系统?是什么让它变得精确?
伺服电机是一种允许您精确控制物理运动的电机,因为它们通常会移动到某个位置而不是连续旋转。它们易于连接和控制,因为电机驱动器内置于其中。
伺服系统包含一个小型直流电机,通过齿轮连接到输出轴。输出轴驱动伺服齿轮,还连接到电位器(pot)。
电位计向控制单元中的误差放大器提供位置反馈,该放大器将电机的当前位置与目标位置进行比较。
为了响应错误,控制单元调整电机的当前位置,使其与所需位置匹配。
在控制工程中,这种机制被称为伺服机构,简称伺服。它是一个闭环控制系统,利用负反馈来调节电机的速度和方向以达到期望的结果。
伺服电机如何工作?
您可以通过向伺服电机发送一系列脉冲来控制它。典型的伺服电机预计每 20 毫秒产生一个脉冲(即信号应为 50Hz)1秒/20毫秒=50次。
脉冲的长度决定了伺服电机的位置。
- 1 毫秒或更短的短脉冲会将伺服电机旋转至 0 度(一个极端)。
- 1.5 ms 的脉冲持续时间将使舵机旋转 90 度(中间位置)。
- 2 ms 左右的脉冲持续时间将使舵机旋转 180 度(另一个极端)。
1ms 到 2ms 范围内的脉冲将使舵机旋转到与脉冲宽度成比例的位置。下面的动画将帮助您了解脉冲和位置之间的关系。
值得注意的是,脉冲和位置之间的确切关系没有标准,因此您可能需要调整草图以调整伺服范围。
此外,不同品牌的脉冲持续时间可能有所不同;例如,180 度可能为 2.5 毫秒,0 度可能为 0.5 毫秒。
伺服电机引脚分配
伺服电机通常具有三个连接,如下所述。
GND作为电机和逻辑的共同点。
5V是为伺服系统供电的正电压。
Control是控制系统的输入。必须是具有PWM的引脚,如果是uno则只能使用3,5,6,9,10,11这几个引脚,所以只能驱动6个伺服马达,如果是使用esp32开发板可以选择的余地就大一些,有21个引脚可以使用。
伺服电机之间的电线颜色有所不同,但红线始终为 5V,GND 为黑色或棕色。控制线通常是橙色或黄色。
将伺服电机连接到 Arduino UNO
让我们将伺服电机连接到 Arduino。
我们将在实验中使用 SG90 微型伺服电机。它的工作电压为 4.8-6VDC(典型值为 5V),可以旋转 180 度(每个方向 90 度)。
它在闲置时消耗约 10mA 的电流,在移动时消耗约 100mA 至 250mA 的电流,因此我们可以使用 Arduino 的 5 伏输出为其供电。
如果您的伺服器消耗超过 250mA,请考虑为其使用单独的电源。如果使用的是SG90微型伺服电机,可以直接使用开发板供电驱动,否则可能需要提供独立的电源,使用独立电源时要主要电源和主板共同接地。
将红线连接到 Arduino 的 5V 电源,将黑/棕线接地。最后,将橙/黄线连接至 PWM 启用引脚 #9。
下表列出了引脚连接:
伺服电机 | Arduino | |
5V | 5V | |
gnd | 接地 | |
control | 9 |
下图显示了如何将SG90伺服电机连接到Arduino。
Arduino 示例 1 – 扫描
首先,我们将使用 Arduino IDE 的内置示例之一。导航至示例子菜单。选择伺服并加载扫描草图。
继续上传草图。伺服电机的轴将开始来回扫过 180 度。
#include <Servo.h>
int servoPin = 9;
Servo servo;
int angle = 0; // servo position in degrees
void setup() {
servo.attach(servoPin);
}
void loop() {
// scan from 0 to 180 degrees
for(angle = 0; angle < 180; angle++) {
servo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for(angle = 180; angle > 0; angle--) {
servo.write(angle);
delay(15);
}
}
代码说明:
控制舵机并不是一项简单的任务,但幸运的是,Arduino IDE 已经包含了一个名为 Servo 的库。它包含简单的命令,可用于快速指示舵机旋转到特定角度。
因此,在草图的开头,我们包含了这个库。
#include <Servo.h>
然后我们声明连接伺服电机控制引脚的 Arduino 引脚。
int servoPin = 9;
下一行创建一个伺服对象。
Servo servo;
实际上,您可以通过这种方式定义最多八个舵机;例如,如果您有两个伺服系统,您可以编写:
Servo servo1;
Servo servo2;
该变量angle
用于存储舵机的当前角度(以度为单位)。
int angle = 0;
在设置函数中,我们使用以下命令将对象链接servo
到伺服系统的控制引脚:
servo.attach(servoPin);
循环函数有两个for
循环。第一个循环将使电机沿一个方向旋转,而第二个循环将使电机沿相反方向旋转。
该servo.write(angle)
函数指示舵机将其位置更新为指定角度。
servo.write(angle);
故障排除
有时,您的伺服系统可能会出现故障,尤其是当您决定直接从 Arduino 操作它时。原因是伺服器消耗大量电量,特别是在启动期间,这可能会导致 Arduino 板重置。
为了解决这个问题,在输入电源上放置一个相对较大的电解去耦电容器(470μF – 1000μF)。确保电容器的较长引线连接到 5V,负极引线连接到 GND。
电容器存储电荷,因此当电机启动时,它会从 Arduino 电源和电容器汲取电力,确保电流平稳流动。
Arduino 示例 2 – 使用电位计控制伺服
我们的下一个示例涉及包括一个电位计,以便我们可以手动调整伺服器的位置。当控制连接到伺服系统的传感器的平移和倾斜时,该项目非常有用。如果希望更精确的调整伺服电机的位置,可以使用旋转编码器代替这里的电位器。
接线
我们将重复使用上一个示例中的接线,但这次我们将添加一个 10KΩ 电位计。将电位器的一端接地,另一端连接 5V,将抽头连接到模拟输入 A0。
Arduino代码
使舵机跟随旋钮位置的代码比使其扫描的代码更简单。
#include <Servo.h>
int potPin = 0;
int servoPin = 9;
Servo servo;
void setup() {
servo.attach(servoPin);
}
void loop() {
int reading = analogRead(potPin);
int angle = map(reading, 0, 1023, 0, 180);
servo.write(angle);
}
代码说明
potPin
请注意,引入了一个名为的新变量。
int potPin = 0;
我们通过读取模拟引脚 A0 的值来启动循环功能。
int reading = analogRead(potPin);
该analogRead()
函数返回一个介于 0 到 1023 之间的值。但是,我们必须按比例缩小它,因为舵机只能旋转 180 度。
一种方法是使用 Arduino map()函数,该函数将数字从一个范围重新映射到另一个范围。下面的行将读数转换为 0 到 180 之间的度数。
int angle = map(reading, 0, 1023, 0, 180);
最后,我们使用write()
命令将舵机的位置更新为电位器选择的角度。
servo.write(angle);