ロータリーエンコーダを読む

エンコーダは'AMT102-V'を使用した。

エンコーダを読むことで移動距離などを計算できる。エンコーダにはA相とB相を用いて回転方向と回転量をアナログ値として読み取ることができるらしい。
マイコンのピンのSPI◯_MISOSPI◯_MOSIの機能を使用していると予想。タイマーのエンコーダモードを使用する。
[プロジェクト名].ioc-Pinout & Configuration-Timers-TIM3-Mode-Combined ChannelsEncoder ModeConfiguration-Parameter Settings-Counter Settings-Counter Period8192Encoder-Encoder ModeEncoder Mode TI1 and TIT2に設定。今回はTIM3を使用した。
printfを使用する。
main.c

/* USER CODE BEGIN 0 */
int over;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim){
    if(htim->Instance == TIM3){
        __HAL_TIM_CLEAR_FLAG(&htim3,TIM_IT_UPDATE);
        if(__HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3)){
            over--;
        }else{
            over++;
        }
    }
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
STprintf(&huart2);
HAL_TIM_Encoder_Start(&htim3, TIMCH_ALL);
HAL_TIM_Base_Start_IT(&htim3);
int count;
over = 0;
/* USER CODE END 2 */

/* USER CODE BEGIN WHILE */
while (1)
{
    // count = TIM3 -> CNT;
    count = (long)(over * 8192) + (long)TIM3 -> CNT;
    printf("%d\r\n",count);
    HAL_Delay(100);
/* USER CODE END WHILE */

エンコーダの回転量をTIM3 -> CNTでゲットし表示する。ただ8192を上回るまたは0を下回ると8192から0にまたは0から8192に飛ぶ。
それを解決するためにオーバーフローを検知しその回数を記録しcountに反映させる。HAL_TIM_PeriodElapsedCallback関数はオーバーフローが起こった時に実行される関数であるため、そこにオーバーフローの回数を記録する。一回転が8192であるからover * 8192で増分を増やす。一回転が8192であるのはエンコーダのデータシートに記載されていて内部のディップスイッチが1~4までが全て0になっている場合、一回転は2048 * 48192になると書かれている。

encoder_inside.JPG

角度を求めてみる

回転量から回転回数や基準からの角度などを求められる。((float)count / 8192) * 360で1周360°になる。ただしcountはもともとint型なので計算結果を少数にするためにfloat型にキャスト変換する。また、以下のコードで角度を~360°にすることで何周しても同じ角度になるようにすることができる。
以下のコード

while(deg > 360){
    deg = deg - 360;
}
while(deg < 0){
    deg = deg + 360;
}

また、スイッチが押されたらその場所を基準としてそこからの角度を表示できるようにすると良いかもしれない。するとすればoverTIM3->CNTをそれぞれ0にする必要がある。

deg.png

参考