如果將測(cè)得的速度值用VOFA+上位機(jī)畫出來,我們可能會(huì)看到這樣的曲線
從圖中我們可以看到,速度值在目標(biāo)速度附近來回小幅度震蕩,始終不穩(wěn)定。這是因?yàn)?a href="http://m.xsypw.cn/tags/編碼器/" target="_blank">編碼器測(cè)速得到的速度值是離散的,如果電機(jī)的速度值剛好卡在兩個(gè)離散值中間,我們測(cè)得的速度值就會(huì)在這兩個(gè)離散值中間來回震蕩。如果我們想要解決這個(gè)問題,最好先對(duì)測(cè)速的精度進(jìn)行分析。
對(duì)于M法測(cè)速來說,測(cè)速的公式如下,其中,k是將速度換算成rpm的比例系數(shù)
由于除號(hào)后面的都是定值,所以我們只要分析每次采樣的脈沖數(shù)對(duì)速度的影響即可。
我們假設(shè)現(xiàn)在測(cè)速頻率是50Hz,減速比為30,編碼器線數(shù)為13,那么脈沖數(shù)每變化1,速度的變化為
所以我們測(cè)得的速度只能是1.923rpm的整數(shù)倍。如果想要提高精度,在電機(jī)不變的情況下,我們可以使用500線的GMR編碼器或者降低測(cè)速頻率。
在VOFA+中,我們可以測(cè)得震蕩時(shí)波峰和波谷的差值為1.92左右,和我們的計(jì)算相符。
為了改善這一現(xiàn)象,我們可以對(duì)速度采樣值使用平均濾波,即將最近幾次的速度采樣值存放到數(shù)組中,每測(cè)得一個(gè)新的速度,就將新速度存入數(shù)組,將最早測(cè)得的速度值從數(shù)組中刪除,我們使用的速度值是數(shù)組中所有速度的平均值。實(shí)現(xiàn)代碼如下
#define SPEED_RECORD_NUM 20 // 經(jīng)測(cè)試,50Hz個(gè)采樣值進(jìn)行濾波的效果比較好
float speed_Record[SPEED_RECORD_NUM]={0};
/*
* 進(jìn)行速度的平均濾波
* 輸入新采樣到的速度,存放速度的數(shù)組,
* 返回濾波后的速度
*/
float Speed_Low_Filter(float new_Spe,float *speed_Record)
{
float sum = 0.0f;
test_Speed = new_Spe;
for(uint8_t i=SPEED_RECORD_NUM-1;i >0;i--)//將現(xiàn)有數(shù)據(jù)后移一位
{
speed_Record[i] = speed_Record[i-1];
sum += speed_Record[i-1];
}
speed_Record[0] = new_Spe;//第一位是新的數(shù)據(jù)
sum += new_Spe;
test_Speed = sum/SPEED_RECORD_NUM;
return sum/SPEED_RECORD_NUM;//返回均值
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//定時(shí)器回調(diào)函數(shù),用于計(jì)算速度
{
if(htim- >Instance==GAP_TIM.Instance)//間隔定時(shí)器中斷,是時(shí)候計(jì)算速度了
{
motor1.direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&ENCODER_TIM);//如果向上計(jì)數(shù)(正轉(zhuǎn)),返回值為0,否則返回值為1
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
if(motor1.lastCount - motor1.totalCount > 19000) // 在計(jì)數(shù)值溢出時(shí)進(jìn)行防溢出處理
{
motor1.overflowNum++;
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
}
else if(motor1.totalCount - motor1.lastCount > 19000) // 在計(jì)數(shù)值溢出時(shí)進(jìn)行防溢出處理
{
motor1.overflowNum--;
motor1.totalCount = COUNTERNUM_1 + motor1.overflowNum * RELOADVALUE_1;//一個(gè)周期內(nèi)的總計(jì)數(shù)值等于目前計(jì)數(shù)值加上溢出的計(jì)數(shù)值
}
motor1.speed = (float)(motor1.totalCount - motor1.lastCount) / (4 * MOTOR_SPEED_RERATIO * PULSE_PRE_ROUND) * 3000;//算得每秒多少轉(zhuǎn),除以4是因?yàn)?倍頻
/*******************在這里添加濾波函數(shù)************************/
motor1.speed = Speed_Low_Filter(motor1.speed,speed_Record);
/**********************************************************/
motor1.lastCount = motor1.totalCount; //記錄這一次的計(jì)數(shù)值
}
經(jīng)過濾波后的速度曲線如下。
綠線是原始速度,紅線是目標(biāo)速度,粉線是濾波后的速度。可以看到,濾波后的速度值明顯要平滑很多,這對(duì)我們后期的PID調(diào)試是很有利的。
-
編碼器
+關(guān)注
關(guān)注
45文章
3673瀏覽量
135280 -
濾波
+關(guān)注
關(guān)注
10文章
669瀏覽量
56780 -
測(cè)速
+關(guān)注
關(guān)注
0文章
39瀏覽量
14235
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
使用STM32 HAL庫(kù)進(jìn)行GPIO控制的實(shí)例
【HAL庫(kù)每天一例】第113例:?jiǎn)屋S25GA370直流電機(jī)編碼測(cè)速(L298N驅(qū)動(dòng))
STM32標(biāo)準(zhǔn)庫(kù)改為HAL庫(kù)的程序?qū)崿F(xiàn)
測(cè)速發(fā)電機(jī)的使用范圍 測(cè)速電機(jī)的特點(diǎn)
仿標(biāo)準(zhǔn)庫(kù),對(duì)HAL庫(kù)的補(bǔ)充代碼
![仿標(biāo)準(zhǔn)<b class='flag-5'>庫(kù)</b>,對(duì)<b class='flag-5'>HAL</b><b class='flag-5'>庫(kù)</b>的補(bǔ)充代碼](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
stm32F103 基于HAL庫(kù)的直流電機(jī)驅(qū)動(dòng)(一)
![stm32F103 基于<b class='flag-5'>HAL</b><b class='flag-5'>庫(kù)</b>的直流<b class='flag-5'>電機(jī)</b>驅(qū)動(dòng)(一)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
【STM32】HAL庫(kù) PWM控制電機(jī)轉(zhuǎn)速與編碼器讀取(超詳解)
![【STM32】<b class='flag-5'>HAL</b><b class='flag-5'>庫(kù)</b> PWM控制<b class='flag-5'>電機(jī)</b>轉(zhuǎn)速與編碼器讀取(超詳解)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
測(cè)速電機(jī)是什么?
![<b class='flag-5'>測(cè)速</b><b class='flag-5'>電機(jī)</b>是什么?](https://file1.elecfans.com/web2/M00/89/94/wKgaomSIHMOAWxOcAABia8VgfG0041.png)
評(píng)論