今回はSTM32マイコンで直交エンコーダを読み込む方法をご紹介します。
秋月で販売しているロータリーエンコーダを使用しました。
1kΩより大きい抵抗ではインピーダンスが大きすぎるようで
330Ωでプルアップすると読み込めました。
CubeMXの設定は下記の通りです。
Combined ChannelsをEncoder Modeに設定すると
A相、B相を接続するポートが自動的に割り当てられます。
詳細設定は次の通りです。
Periodに設定した値までカウントすると0にリセットされます。
また、EncoderModeをTI1とTI2に設定することで
4逓倍となります。
この設定の場合、
今回のエンコーダは1回転24パルスですが、
4逓倍で1回転96パルスとなります。
CubeMXで自動で生成されたコードから下記のコードを追加しました。
HAL_TIM_Encoder_Start(&htim3, TIM_CHANNEL_ALL);
printf("Initialized Success!!\n");
while (1)
{
HAL_Delay(300);
int8_t uwDirection = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);
uint16_t cnt=TIM3->CNT;//htim3.Init.Period;
printf("CNT:%d, Drc:%d \n",cnt,uwDirection);
}
printf("Initialized Success!!\n");
while (1)
{
HAL_Delay(300);
int8_t uwDirection = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim3);
uint16_t cnt=TIM3->CNT;//htim3.Init.Period;
printf("CNT:%d, Drc:%d \n",cnt,uwDirection);
}
__HAL_TIM_IS_TIM_COUNTING_DOWN関数で回転方向を取得できます。
エンコーダの値はTIM3->CNTで取得します。
実際にコードを実行してエンコーダを回転させてみました。
実際のロボットなどの位置取得では、
1回転で0に戻ると制御できないため、
0で割り込みを発生させて繰り上がり、繰り下がり処理等を行うのが一般的です。
また、他にチャタリング防止等のフィルタ機能もあるようなので、
必要に応じて使ってみると良いと思いました。