最近學習STM32控制SG90舵機
學習過程中發現舵機轉速過快,無法平緩的轉向指定角度
在網上查找資料具體了解到
舵機的轉速與舵機的目標角度和舵機的當前角度的差值呈正相關
下面這張圖舉個例子
假設舵機在當前為90° 我們設置目標角度為180°
舵機的轉速=|(180°-90°)|*k, k為比例系數
也就是舵機距離目標角度越近轉速越慢,距離目標角度越遠轉速越快,所以我們看到舵機的起步一般非常快
現在大概知道了轉速快的原因,我的目標是讓舵機可以平緩的運動最好是勻速運動
思路是將目標角度與當前角度的差值分成若干塊,逐步使舵機轉向目標值,
例如
下載.png (31.44 KB, 下載次數: 65)
下載附件
2021-2-10 14:33 上傳
將90°分成四步,每步轉22.5°,每轉22.5°適當延時,當舵機轉完22.5°后發送下一步信號,再次轉動22.5° 以此類推
舵機的轉速大概趨于平穩
當然每步22.5°肯定是不平滑的,我們可以分更多塊每步1°或者更小
順便寫了一個函數,還有優化的空間
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "timer.h"
#include "key.h"
#include "oled.h"
unsigned int key=0,actual_pwm=100;
u32 part=0,time=0;
/**
*作用:舵機旋轉
*expect_pwm:舵機目標旋轉值
*s:舵機到達指定位置耗時
*最小轉動角度:0.45*5
**/
void SG90(u32 expect_pwm,u32 s)
{
if(expect_pwm>actual_pwm)
time=1000000*s*5/(expect_pwm-actual_pwm);//微秒級拆分
if(expect_pwm<actual_pwm)
time=1000000*s*5/(actual_pwm-expect_pwm);//微秒級拆分
if(expect_pwm!=actual_pwm)
{
if(expect_pwm>actual_pwm)
{
while(1)
{
actual_pwm=actual_pwm+5;//一次
TIM_SetCompare1(TIM14,actual_pwm);
part++;
delay_us(time);
if(expect_pwm==actual_pwm)
{
part=0;
break;
}
}
}
if(expect_pwm<actual_pwm)
{
while(1)
{
actual_pwm=actual_pwm-5;
TIM_SetCompare1(TIM14,actual_pwm);
part++;
delay_us(time);
if(expect_pwm==actual_pwm)
{
part=0;
break;
}
}
}
}
}
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統中斷優先級分組2
delay_init(168); //初始化延時函數
TIM14_PWM_Init(4000-1,420-1); //84M/4200=200khz的計數頻率,重裝載值4000,所以PWM周期為0.02s(20ms)
KEY_Init();
while(1)
{
key=KEY_Scan(0);
if(key==1)
{
SG90(500,1);
}
if(key==2)
{
SG90(100,1);
}
}
}
全部程序51hei下載地址:
舵機控制(控制轉速).7z
(310.21 KB, 下載次數: 92)
2021-2-10 17:03 上傳
點擊文件名下載附件
低轉速 下載積分: 黑幣 -5
|