舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。其工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为20ms,宽度为1.5ms 的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
在这里插入图片描述

Arduino Uno驱动舵机的方法主要有以下两种:

一、使用Arduino IDE自带Servo库

Arduino IDE自带的Servo库可以简化舵机的控制,只需几行代码即可实现舵机的基本控制。

#include <Servo.h>

Servo myServo;  // 创建Servo对象来控制舵机
int servoPin = 9;  // 舵机信号引脚连接到Arduino的9号引脚
int angle = 0;     // 舵机初始角度

void setup() {
  myServo.attach(servoPin);  // 将舵机连接到指定引脚
}

void loop() {
  // 从0度到180度转动舵机
  for (angle = 0; angle <= 180; angle += 1) {
    myServo.write(angle);  // 告诉舵机转到指定角度
    delay(15);             // 等待舵机转动到指定位置
  }
  
  // 从180度回到0度
  for (angle = 180; angle >= 0; angle -= 1) {
    myServo.write(angle);  // 告诉舵机转到指定角度
    delay(15);             // 等待舵机转动到指定位置
  }
}    

二、使用PWM信号直接控制舵机

除了使用Servo库,也可以通过Arduino的PWM功能直接控制舵机。这种方法更加灵活,可以精确控制PWM信号的宽度。

int servoPin = 9;  // 舵机信号引脚连接到Arduino的9号引脚

void setup() {
  pinMode(servoPin, OUTPUT);  // 将舵机控制引脚设置为输出模式
  TCCR1A = 0;                 // 重置TCCR1A寄存器
  TCCR1B = 0;                 // 重置TCCR1B寄存器
  TCNT1 = 0;                  // 重置计数器值
  
  // 设置PWM频率为50Hz (20ms周期)
  ICR1 = 39999;               // 设置TOP值,确定PWM周期
  TCCR1B |= (1 << WGM13);     // 设置为模式14:PWM, Phase and Frequency Correct, ICR1作为TOP
  TCCR1B |= (1 << CS11) | (1 << CS10);  // 设置预分频为64
  TCCR1A |= (1 << COM1A1);    // 设置为非反转PWM模式
}

void loop() {
  // 从0度到180度转动舵机
  for (int pulseWidth = 544; pulseWidth <= 2400; pulseWidth += 5) {
    OCR1A = pulseWidth;       // 设置PWM脉冲宽度
    delay(15);                // 等待舵机转动到指定位置
  }
  
  // 从180度回到0度
  for (int pulseWidth = 2400; pulseWidth >= 544; pulseWidth -= 5) {
    OCR1A = pulseWidth;       // 设置PWM脉冲宽度
    delay(15);                // 等待舵机转动到指定位置
  }
}    

舵机控制原理

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,对应的控制关系是这样的:

  • 0.5ms--------------0度;
  • 1.0ms------------45度;
  • 1.5ms------------90度;
  • 2.0ms-----------135度;
  • 2.5ms-----------180度;

使用Servo库时,write()函数接受0-180的角度值,库会自动将其转换为对应的脉冲宽度。而使用PWM直接控制时,需要手动计算并设置脉冲宽度值。

#include <Servo.h>

Servo myServo;
int servoPin = 14;  // 使用D5引脚(GPIO14),避免使用TX/RX等特殊引脚

void setup() {
  myServo.attach(servoPin);
  Serial.begin(115200);
  Serial.println("Servo Control Ready!");
}

void loop() {
  // 角度控制示例
  for (int angle = 0; angle <= 180; angle += 10) {
    myServo.write(angle);
    Serial.print("Angle: ");
    Serial.println(angle);
    delay(500);
  }
  
  delay(1000);
}   
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐