前言:由於寫部落格過程中出了點小插曲,再加上第二次積分賽的到來,導致第一次積分賽的總結一直鴿到現在。。。現在先水一篇。:-)
我們的有刷電機帶有一個霍爾編碼器,用於獲取速度、角度等資訊,以完成雲臺要求的轉速與角度控制。
以下是該電機編碼器的引數:
一、編碼器原理
我們這裡使用的是增量式編碼器。
增量式編碼器是將裝置運動時的位移資訊變成連續的脈衝訊號,脈衝個數表示位移量的大小。其特點如下:
-
只有當裝置運動時才會輸出訊號。
-
一般會輸出通道A和通道B 兩組訊號,並且有90° 的相位差(1/4個週期),同時採集這兩組訊號就可以計算裝置的運動速度和方向。
如下圖,通道A和通道B的訊號的週期相同,且相位相差1/4個週期,結合兩相的訊號值:
-
- 當B相和A相先是都讀到高電平(1 1),再B讀到高電平,A讀到低電平(1 0),則為順時針轉
- 當B相和A相先是都讀到低電平(0 0),再B讀到高電平,A讀到低電平(1 0),則為逆時針轉
-
除通道A、通道B 以外,還會設定一個額外的通道Z 訊號,表示編碼器特定的參考位置
如下圖,感測器轉一圈後Z 軸訊號才會輸出一個脈衝,在Z軸輸出時,可以通過將AB通道的計數清零,實現對碼盤絕對位置的計算。
-
增量式編碼器只輸出裝置的位置變化和運動方向,不會輸出裝置的絕對位置。
解析度:指編碼器能夠分辨的最小單位。
- 對於增量式編碼器,其解析度表示為編碼器轉軸旋轉一圈所產生的脈衝數,即脈衝數/轉(Pulse Per Revolution 或PPR)。由第一張圖可知,我們的電機PPR為11,即旋轉一圈產生11個脈衝。
如何採集編碼器的脈衝資料呢?恰好我們的STM32微控制器定時器模式中有一個定時器的編碼器模式,我們通常用它來測量脈衝變化值。通過訪問計數器cnt的值(編碼器模式中使用上下計數)來檢測接收到的脈衝數。
之前文章的工程配置裡有提到,我們設定TIM2為編碼器模式。
二、轉速測量
統計固定時間間隔內的編碼器的脈衝數,來計算速度值。我們需要根據編碼器的引數來得到轉速的計算方式。我們開啟一個定時器中斷TIM4,每隔0.01s測量一次轉速。
速度計算方法:這裡計算的是真實的電機的物理轉速n(r/s)
-
C:編碼器單圈總脈衝數,也有一個公式:
-
\[C=ρ×PPR \]
- ρ:電機減速比,即電機轉軸轉1圈,電機本身要轉多少圈
- PPR:編碼器解析度
-
T0:每次的統計時間(單位為秒)
-
M0:該時間內統計到的編碼器脈衝數,通過讀取這次和上次定時器計數器的值cnt得到
我們這裡減速比ρ經測試是20。PPR是11,因為定時器中斷為100Hz,T0為0.01。
三、角度測量
具體原理同速度測量,直接上公式:
- C:編碼器單圈總脈衝數,解釋見上。
- N0:該時間內統計到的編碼器脈衝數,通過讀取這次定時器計數器的值cnt得到
四、程式碼部分
基於上一篇文章新增以下程式碼。
1、新增變數
float speed;
float angle;
int32_t cnt;
int32_t last_cnt;
2、使能定時器中斷和編碼器模式
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim4);
HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
/* USER CODE END 2 */
3、新增中斷回撥函式
/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim4)
{
cnt = (short)TIM2->CNT; //tim2計數器的值
speed = (float)(cnt - last_cnt) / 22.0f / 20 * 100;
angle = ((float)cnt) / 22.0f / 20 * 360; //儲存上一次計數器的值
last_cnt = cnt;
}
}
/* USER CODE END 4 */
4、轉速控制
PWM佔空比越大,提供給電機的平均電壓越大,電機轉速就高。反之PWM佔空比越小,提供給電機的平均電壓越小,電機轉速就低。
我們之前工程配置輸出的PWM佔空比為50%,這裡加大轉速,佔空比設為70%。
set_pwm(700);
五、接線與數值監控
見圖一,和上一篇文章,編碼器訊號線黃線與綠線接微控制器PA0與PA1引腳,得到AB相脈衝。其餘和上一篇文章一致。
在Debug模式下觀測PWM佔空比分別為50%與70%時speed與angle資料。當然在串列埠上也能看。