Arduino从零开始:探索控制舵机与步进电机的奥秘
0.前言
本文主要介绍通过Arduino控制舵机,步进电机以及循环的使用
目录
1.介绍
对于Arduino控制舵机的方法是通过其输出PWM信号来实现控制的。这里所谓的PWM信号其本质上就是脉冲信号。而对于步进电机的控制,则是通过输出脉冲信号来实现控制的。这两者有怎样的区别,首先要理解什么是PWM信号——是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形。也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比。简而言之,对于角度的控制,舵机的核心是在脉冲的频率上,而步进电机则是在脉冲个数上。
2.Arduino控制舵机:
这里总共会介绍两种方法来控制舵机,方法一是简单的使用其自带的库来实现控制。方法二是我们以原理出发,直接通过脉冲来控制舵机。舵机的话就是普通实验用的。
2.1方法一
接线图:
代码 :
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(2);//定义PWM输出的引脚
}
void loop()
{
myservo.write(90); //写出输出角度
delay(1000);
myservo.write(0);
delay(1000);
}
效果如下:
说明:
1.以上代码是最简形式,通过使用Arduino所自带的Servo.h库来实现,效果为转90°延迟1s转回0°。唯一要注意的就是myservo.write中的值直接是角度值,一般的范围就是0~180°,也有360°的舵机可以使用。
2.对于舵机的控制我们发现该库并没有对速度的控制。就步进电机而言是通过频率来控制速度,而舵机是拿频率来控制角度。故对于速度的控制可以采用微分化来实现,简而言之就是把目标角度分成多段行走,并控制每段的时间来实现。这里分段最小单位可以采取1°,代码如下:
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(2);
}
void loop()
{
for(int i=0;i<90;i++){
myservo.write(i);
delay(1);
}
delay(2000);
for(int i=90;i>0;i--){
myservo.write(i);
delay(50);
}
delay(2000);
}
效果如下:
对比之前,我们就能发现,由0到90°是快速,在由90到0°就变成慢速了。
3.说明2中出现了for循环,for语句用于重复执行被花括号包围的语句块。一个增量计数器通常被用来递增和终止循环。for语句对于任何需要重复的操作是非常有用的。常常用于与数组联合使用以收集数据/引脚。for循环的头部有三个部分:
for (初始化部分; 条件判断部分; 数据递增部分) {
//语句块
。。。
}
初始化部分被第一个执行,且只执行一次。每次通过这个循环,条件判断部分将被测试;如果为真,语句块和数据递增部分就会被执行,然后条件判断部分就会被再次测试,当条件测试为假时,结束循环。
2.2方法二
回归到PWM的定义上,是通过调节占空比的变化来调节角度。也就是其控制需要Arduino产生一定量的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机的角度。对于180°的舵机而言,其对应关系如下:
0.5ms=500us————-0度
1.0ms=1000us————45度
1.5ms=1500us————90度
2.0ms=2000us———–135度
2.5ms=2500us———–180度
因此我们可以通过for循环函数,控制普通数字引脚端口高低电平的变化,直接实现控制舵机。
接线图与方法1一样,代码如下:
void setup()
{
pinMode(2,OUTPUT);
for(int i=0;i<=80;i++){
digitalWrite(2,HIGH);
delayMicroseconds(2500);//旋转180度
digitalWrite(2,LOW);
delay(100);
}
}
void loop()
{
}
效果如下:
说明:
1.这里for循环次数(脉冲输出的个数)也会直接影响舵机的旋转的角度。当循环次数不够时,角度也会走不到需要的位置,但次数过多到不会影响其最后的角度,次数合适即可。
2.for循环中的第二个延时dely(100);这里可以直接完成对速度的控制。
3.Arduino控制步进电机
以带驱动器的57型步进电机为例:
驱动器端接线如下:
备注:这里Arduino采用的是nano,如果是uno也可一样的接。引脚上数字引脚与模拟引脚都无所谓,模拟引脚也能当数字引脚用。
代码如下:
void setup()
{
pinMode(A1,OUTPUT);
pinMode(A2,OUTPUT);
digitalWrite(A2,HIGH);//设定电机旋转方向
for(int i=0;i<=80;i++){//走80个脉冲
digitalWrite(A1,HIGH);
delayMicroseconds(500);
digitalWrite(A1,LOW);
delayMicroseconds(500);
}
}
void loop()
{
}
另外关于步进电机的进阶使用,可以参考我另外的文章: