トップ画像
ロータリーエンコーダを手っ取り早く利用する

執筆者: 瀕死

最終更新: 2025/03/01

ロータリーエンコーダを手っ取り早く利用する

ロータリーエンコーダは、回転を電気信号に変換し、回転方向や回転量を検出するためのセンサとして、広く利用されています。本記事では、ロータリーエンコーダ(EC12E2420801)を手っ取り早く利用するための方法を紹介します。

環境説明

開発環境は以下の通りです。

  • Raspberry Pi Pico互換ボード
  • Raspberry Pi Pico SDK v1.5.1
  • ロータリーエンコーダ: 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

上の表より排他的論理和で時計回りを真とすると回転方向が求まります。

アブソリュート型ロータリーエンコーダ

絶対的な角度に対する線形な電圧やパラレルな出力から現在の角度を取得できます。

参考文献

取得に失敗しました

2024年度 入部