问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

舵机原理介绍:从基础到实战的Arduino驱动代码详解

创作时间:
作者:
@小白创作中心

舵机原理介绍:从基础到实战的Arduino驱动代码详解

引用
CSDN
1.
https://blog.csdn.net/qq_66771136/article/details/144723644

舵机是伺服电机的一种特殊版本,常用于航模和小型机器人等领域。本文将详细介绍舵机的工作原理,并提供具体的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);                       // 等待转动到指定角度
  }
}  
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号