什么是脉冲
脉冲我理解呢就是拉闸放水的这么一个过程:比如说一个水龙头,我们打开开关,水龙头出水,关上开关,水龙头不出水。如果我们在
一个固定的时间内将水龙头开关上拉0-t,那么水龙头出水,然后在
另一个固定时间内将水龙头开关下拉t-T,那么水龙头不出水,
如果我们描述出水是1,不出水是0的话,如此循环,那么就可以生成如下的图形。
以上从0-T的这个时间里就形成了一个脉冲,学术定义:在短持续时间内突变,随后又迅速返回其初始值的物理量变化过程称之为脉冲。
如果把水龙头换成电路,接通电路为1,断开电路为0,这样就形成了一个电脉冲。
这中间就有一个变量,那就是时间,根据时间的不同可以改变脉冲的波形。
接线
nano MG995
5V----红线
GND----黑线
Pin9----黄线
由于MG995是母头,nano也是母头,所以两个设备之间要用两头都是公头的杜邦线连接。
让舵机改变角度
那么舵机是如何能够自动转向到某一个角度的呢?
你买舵机的时候,某宝,拼某某老板都会告诉你(每个舵机可能都不太一样)。如下图
我买的这个是MG995,当然还有996
并且我还发现了一句话工作死区:4微秒
,为什么会有死区呢,我也不懂,估计是到达一定角度就动不了了吧。
之前从网上下载了好多实例,但是有一个servo.h库文件我是看不懂,后来人家说最好不要用头文件,有bug你也不知道怎样调,后来我就打算不用头文件,自己写,当理解了什么是脉冲,我就知道怎么写了。测试一下成功了。
int servopin=9;//定义数字接口4 连接伺服舵机信号线
void setup() {
pinMode(servopin,OUTPUT);//设定舵机接口为输出接口
}
void loop() {
digitalWrite(servopin,HIGH); //将舵机接口电平至高
delayMicroseconds(1500); //能控制这里面的数字就能控制舵机的角度
digitalWrite(servopin,LOW); //将舵机接口电平至低
delay(20);
}
就这么简单几句就够了,接好线后,上传代码舵机停在了90°的位置(可能会有所偏差,可以自己摸索)
首先,20ms时基脉冲的意思就是上面提到的,返回其初始值的物理量,也就是下拉电平(关上开关or断开电路)的意思,总间隔2ms的意思是0.5ms至2.5ms这些上拉电平区段,都可以进行设置。当设置上拉电平的时候设置0.5ms,舵机角度就停止在0°,如果是设置2.5ms,舵机角度就停止在180°,同理可证设置1.5ms舵机就转向90°。
那么每增加1°要增加多少ms呢?
(2.5-0.5)/180=0.0111111111111111无限循环小数,换算成微秒约等于11微秒
那么现在控制delayMicroseconds(500);
里面的数字就可以控制角度了,500微秒是初始值,那么0°就等于 0(角度)×11+500=500,45°就等于 45×11+500=995,将角度设置成为变量,改变这个变量,我们就可以控制舵机转向。
定义一个脉冲函数,以上内容可以改写为
int servopin=9; //定义数字接口9 连接伺服舵机信号线
int pulsewidth; //定义脉宽变量
int myangle; //定义角度变量
void setup() {
pinMode(servopin,OUTPUT); //设定舵机接口为输出接口
}
void loop() {
pulse(45);
}
//定义一个脉冲函数
void pulse(int myangle){
pulsewidth=(myangle*11)+550; //(实际测量角度偏差50微秒)将角度转化为550-2530的脉宽值
digitalWrite(servopin,HIGH); //将舵机接口电平至高
delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
digitalWrite(servopin,LOW); //将舵机接口电平至低
delay(20);
}
让舵机0°-180°,180°-0°来回动就可以这样写
int servopin=9; //定义数字接口9 连接伺服舵机信号线
int pulsewidth; //定义脉宽变量
int myangle; //定义角度变量
int i=0;
void setup() {
pinMode(servopin,OUTPUT); //设定舵机接口为输出接口
}
void loop() {
for (i=0;i<=180;i++){
pulse(i);
}
for (i=180;i>=0;i--){
pulse(i);
}
}
//定义一个脉冲函数
void pulse(int myangle){
pulsewidth=(myangle*11)+550; //(实际测量角度偏差50微秒)将角度转化为550-2530的脉宽值
digitalWrite(servopin,HIGH); //将舵机接口电平至高
delayMicroseconds(pulsewidth); //延时脉宽值的微秒数
digitalWrite(servopin,LOW); //将舵机接口电平至低
delay(20);
}
从以上实例可以看出,我们控制了myangle
变量就等于控制了舵机
串口控制舵机旋转角度
int servopin=9; //定义舵机接口数字接口9
int pulsewidth; //定义脉宽变量
int val; //串口缓存
int val1;
int myangle;
void setup(){
pinMode(servopin,OUTPUT); //设定舵机接口为输出接口
Serial.begin(9600);
delay(500);
}
void loop(){
val = Serial.read(); //读取串行端口的值
if(val>'0'&&val<='9'){
val1 = val-'0'; //将特征量转化为数值变量
val1 = map(val1,0,9,0,180); //将角度转化为500-2480的脉宽值
Serial.print("moving servo to ");
Serial.print(val1,DEC);
Serial.println();
for(int i=0; i<=50; i++) //给予舵机足够的时间让它转到指定角度
{
pulse(servopin,val1); //引用脉冲函数
}
}
}
//定义一个脉冲函数
void pulse(int sp,int val1){
myangle=map(val1,0,180,550,2480);
digitalWrite(sp,HIGH); //将舵机接口电平至高
delayMicroseconds(myangle); //延时脉宽值的微秒数
digitalWrite(sp,LOW); //将舵机接口电平至低
delay(20-val1/1000);
}
未完待续