舵机原理介绍:从基础到实战的Arduino驱动代码详解
舵机原理介绍:从基础到实战的Arduino驱动代码详解
舵机是伺服电机的一种特殊版本,常用于航模和小型机器人等领域。本文将详细介绍舵机的工作原理,并提供具体的Arduino驱动代码示例,帮助读者快速掌握舵机控制技术。
1. 舵机简介
舵机是伺服电机的一种特殊版本,常用于航模和小型机器人等领域。它是通过控制输入PWM信号来精确控制转动角度的。因此,想要驱动舵机就是让Arduino输出PWM信号即可。
2. 舵机转动角度的PWM条件(以180度的SG90舵机为例)
2.1 控制关系
翻译成人话就是说 ,我们要想驱动它, PWM的周期T需要时20ms 修改它的占空比 对应角度
对于PWM的占空比和周期不熟悉的请看我之前的文章:(这个是必须要会的)
Arduino 占空比 脉冲 PWM-CSDN博客
占空比(周期是20ms) 角度 Timer1.pwm(pin,num)占空比配置函数 num的值
0.5/20*100%=2.5% 0度 26
5% 45度 51.2 ≈51
7.5% 90度 76.8≈76
10% 135度 102.4≈102
12.5% 180度 128
2.2 arduino产生PWM
我使用的是定时器1的相关库TimerOne.h来配置PWM的,简单易操作,且上限高.
arduino定时器1 TimerOne 一篇搞懂_#include <timerone.h>-CSDN博客
它的PWM的分辨率是10位的也就是1024
定时器1的两个PWM引脚是9和10 这里我们用9引脚. 第二个是变量除以1024 就是高电平的占比 也就是占空比.
占空比函数 Timer1.pwm(pin,num);
Timer1.pwm(9,26);//26/1024≈2.5%
定时器初始化和设置周期函数 Timer1.initialize();
Timer1.initialize(20000);//周期20ms 变量是微秒级别的,20000就是20毫秒
#include <TimerOne.h>
volatile long ms_tick=0,ms_tick_flag=0;
void setup(void)
{
Timer1.initialize(20000);//周期20ms
Timer1.pwm(9,26);//26/1024≈5%
Serial.begin(115200);
}
void loop(void)
{
}
3.0 附代码 循环0度到180度开关舵机(非阻塞版本)
这个代码是循环的0-180度,我中间加了延时,只是为了让舵机运行的慢一点而已,其实是并没有阻塞程序.这里面的delay 完全可以用其他延时来替代
这里推荐看一看我写的延时大全:arduino延时最全解析。(完结)_arduino 延时微秒函数-CSDN博客
使用非阻塞的延时代码.
#include <TimerOne.h>
volatile long ms_tick=0,ms_tick_flag=0;
void setup(void)
{
Timer1.initialize(20000);//精确度20ms
Timer1.pwm(9,26);
Serial.begin(115200);
}
void loop(void)
{
static int i=26,flag=0;
//这两个if语句主要是为了实现亮灭亮交替
if(i<=26)
flag=0;
if(i>=130)
flag=1;
if(flag==0)
i+=1;
else
i-=1;
Timer1.pwm(9,i);
delay(10);
}
4.0 Servo.h 舵机代码
使用Serivo.h的库文件理论上可以达到控制舵机的效果,但是本人是不推荐的,我们使用arduino大多是为了学习单片机思维,我使用TimerOne.h来驱动舵机,即使我们换了一款单片机也同样能做到.这就代表着我们学会了这个模块,彻底的吃透了它.
#include <Servo.h>
#include<Arduino.h>
Servo myservo; // 定义Servo对象来控制
int pos = 0; // 角度存储变量
void setup() {
// put your setup code here, to run once:
myservo.attach(9); // 控制线连接数字6
myservo.write(0);
}
void loop() {
// put your main code here, to run repeatedly:
shun_180(myservo);
delay(1000);
ni_180(myservo);
delay(1000);
}
void shun_180(Servo name)
{
for (pos = 0; pos <= 180; pos ++) { // 0°到180°
name.write(pos); // 舵机角度写入
delay(5); // 等待转动到指定角度
}
}
void ni_180(Servo name)
{
for (pos = 180; pos >= 0; pos --) { // 从180°到0°
name.write(pos); // 舵机角度写入
delay(5); // 等待转动到指定角度
}
}