執筆者: 瀕死
最終更新: 2025/03/01
ロータリーエンコーダは、回転を電気信号に変換し、回転方向や回転量を検出するためのセンサとして、広く利用されています。本記事では、ロータリーエンコーダ(EC12E2420801)を手っ取り早く利用するための方法を紹介します。
開発環境は以下の通りです。
回転を電気信号に変換するセンサです。詳細は後述します。
データシートを元に構成した回路は次の通りです。
この回路ではロータリーエンコーダの出力端子のA相とB相をプルアップし、その後はローパスフィルタを通してチャタリング等のノイズを除去したのち、マイコンのGPIOで信号を読み取ります。
しかしこれではかなり回路が煩雑で手っ取り早くできません。
そのため次の回路を利用します。
何回か試したところ、ローパスフィルタがなくてもそこまで影響がないため削減し、マイコンにプルアップを任せることでプルアップ抵抗も削減しました。 これによって配線を3本指すだけで動作します。
以下のようなプログラムを書き込みます。
#include <stdio.h>
#include "hardware/interp.h"
#include "pico/stdlib.h"
// ロータリーエンコーダとつながっているGPIO
#define A_LINE 16
#define B_LINE 15
int vol = 0;
// 割り込み処理を行う関数
void gpio_callback(uint gpio, uint32_t events) {
if (gpio_get(A_LINE) ^ gpio_get(B_LINE))
vol++;
else
vol--;
printf("GPIO: %d, VOL: %d \n", gpio, vol);
}
int main() {
stdio_init_all();
gpio_init(A_LINE);
gpio_init(B_LINE);
gpio_set_dir(A_LINE, false);
gpio_set_dir(B_LINE, false);
gpio_pull_up(A_LINE);
gpio_pull_up(B_LINE);
printf("Hello, world!\n");
// ここまでほぼ初期化処理
// この関数でA_LINEの立ち上がりと立ち下りで割り込み関数を呼ぶように設定
gpio_set_irq_enabled_with_callback(
A_LINE, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
while (true) {
// 後はやることないので待機
sleep_ms(10);
}
}
任意のシリアルモニターによって回転が検出できていることがわかります。
90°位相差のA相、B相から回転方向と回転量を読み取ります。
グラフの横軸はTimeでなくCW回転方向の角度であることに注意してください。 つまり回転していないときは波形は変化しません。
つまり一定量回転するごとにHIGHとLOWが入れ替わるため回転量が検出でき、位相差があることで回転方向が検出できます。CCWは反時計回りです。
Aの変化先 | Bの状態 | 回転方向 |
---|---|---|
LOW | LOW | CCW |
LOW | HIGH | CW |
HIGH | LOW | CW |
HIGH | HIGH | CCW |
上の表より排他的論理和で時計回りを真とすると回転方向が求まります。
絶対的な角度に対する線形な電圧やパラレルな出力から現在の角度を取得できます。