前言:
最近在做一个小车,其中舵机在运行的时候速度较快,影响了整个系统的稳定性,想着如何才能控制舵机的运动速度,于是写出这篇文章,向大家分享我的做法,本文仅限于新手小白,佬勿喷(玻璃心),那么废话不多,直接上干货!!!
一、如何控制舵机
1.1什么是舵机
舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的闭环控制执行模块,通常采用5V供电并使用PWM信号进行控制。
1.2舵机控制原理
与舵机相连的有三根线,中间的红色线为电源正极,咖啡色线的为电源负极,黄色色线为控制信号线, 如下图所示。舵机的控制采用PWM信号,通常情况下,我们使用一个频率为50HZ的PWM信号,其中高电平宽度一般为0.5ms-2.5ms。 以180°的舵机为例,若我们规定当脉冲宽度为0.5ms时,舵机的角度为0°,大于0.5ms时 舵机旋转角度增大,2.5ms时舵机旋转角度达到最大值180°,则脉冲宽度与角度的关系,如下图所示
也就是说,如果我想让舵机归零度,我就只需要提供频率为50HZ,高电平宽度为0.5ms的PWM信号就行,如果我想要舵机转动到90°的位置,我就只需要提供频率为50HZ,高电平宽度为1.5ms的PWM信号给舵机就可以。
1.3控制舵机转动其他角度
既然舵机可以转动45,90,135,180度,那可不可以控制其转动30度,120度,166度等其他角度呢,答案是可以的。
通过上文,我们知道不同占空比的pwm信号可以控制舵机转动不同的角度,并且根据高电平宽度每增加0.5ms,舵机转动45度的特性来推断高电平宽度的增加应该是与舵机转动角度存在一定的关系,而对于单片机,以RT1064为例,它最大duty值为10000,我们需要写入不同的duty值来设置不同的pwm占空比
这个式子可以实现控制舵机的转动角度,X的取值在0到180度之间,下来是一段控制舵机转动100度角的部分代码示例
int duty;
float angle;
angle = 100/ 90;
duty = (int)(( angle + 0.5 )*500);
pwm_set_duty(channel_list, duty);
二、控制舵机平稳转动
在我实际运行代码的时候,舵机运动过快,导致整个小车不稳定,达到的效果不理想,于是我就在想,能否使用循环,在一段时间内,让他的占空比“缓慢上升”或者“缓慢下降”,以达到舵机平稳运行的目的
2.1思路
函数中设置两个角度值,一个是现在的角度,一个是要转动到的目的角度,在角度变化的过程中添加延时
2.2代码示例
以下是函数代码示例
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 设置舵机的pwm信号
// 参数说明 i 舵机PWM输出通道
// 参数说明 Angle_now 当前舵机的角度
// 参数说明 Angle_next 转动到的目的角度
// 使用示例 duoji_pwm(0,0,90);
//-------------------------------------------------------------------------------------------------------------------
// i为舵机通道 Angle_now是现在的角度 转动到的目的角度
void duoji_pwm(uint8 i , float Angle_now, float Angle_next)
{
// 现在的占空比 接下来的占空比
int duty_now, duty_next, duty_set;
float p_now,p_next;
p_now = Angle_now/ 90;
p_next = Angle_next / 90;
duty_now = (int)(( p_now + 0.5 )*500);
duty_next = (int)(( p_next + 0.5 )*500);
if(duty_next > duty_now)//判断两个占空比的大小
for (duty_set = duty_now; duty_set <= duty_next ; duty_set++)
{
pwm_set_duty(channel_list[i], duty_set);
system_delay_us(1000);//延时1ms
}
else
if(duty_next < duty_now)
{
for (duty_set = duty_now; duty_set >= duty_next ; duty_set--)
{
pwm_set_duty(channel_list[i], duty_set);
system_delay_us(1000);
}
}
}
最后的最后,限于本人的水平以及初次写文章,如有错误和高见请大佬们不吝赐教,最后要是本文对你有用的话,还请点个小赞赞,这是对我最大的认可啦,下期再见!