インクリメント型のロータリーエンコーダの回転状態を2bitに圧縮する

インクリメント型ロータリーエンコーダの簡単な説明

インクリメント型のロータリーエンコーダでは、2相(A相B相}の状態から読み取ります。
A相とB相がHIGHかLOWかの情報なので、エンコーダの状態は2bitで表せます。
回転の方向を知るためには、さらに一つ前のエンコーダの状態の情報が必要になるため、計4bitから回転を検出することになります。

下図は、エンコーダが正回転することによって、A相B相の状態が左から右に変移していく図です。

例えば現在のエンコーダはA相=0、B相=0だとすると、正回転すると右のA相=1、B相=0に変移します。
逆に逆回転すると、A相=0、B相=1に変移します。

4bitで表すエンコーダの回転状態

エンコーダの回転を読み取るためには、先に示した現在と過去のエンコーダの状態4bitが必要になり、つまり16通りの状態が存在します。
しかし、エンコーダの回転を検出するという意味では、状態を「正回転、逆回転、無回転、読み飛ばし」の4状態=2bitで表すことができます。

例を挙げると、現在の状態がA相=0、B相=0だとすると、

前回の状態 A相 B相
正回転 0 1
逆回転 1 0
無回転 0 0
読み飛ばし 1 1

となります。

エンコーダの状態は連続的に変化するため、ひとつ前の状態が現在の状態と同じ状態(無回転)と、1つ飛ばした状態(読み飛ばし)は本来あり得ません。
しかし、なんらかのエラーによってひとつ前の状態を正確に読めなかった場合を考慮してこの4状態とします。

これらを表にすると以下のような感じです。

2bitに圧縮

今回の主目的は、この現在と過去のエンコーダの状態4bitから、「正回転、逆回転、無回転、読み飛ばし」の2bitに圧縮することです。

まず、「正回転、逆回転、無回転、読み飛ばし」を「11、01、00、10」と定義しておきます。

一応表にすると、以下のような感じです。

表の左の4bitから右の2bitに変換する演算を求めたいのです。

結論から言うと、 Ao、Boを過去のA相B相、Ac、Bcを現在のA相B相、回転の状態をXと定義すると、 X = 0b11&((Ao<<1)|(Ao^Bo) - (Ac<<1)|(Ac^Bc)) で表すことができます。

回転状態 演算結果X
正回転 0b11
逆回転 0b01
無回転 0b00
読み飛ばし 0b10

すべての状況を書くと以下の表になります。
きちんと分類できていることがわかります。

エンコーダの状態をA相B相のHIGH、LOWとして記憶しておくのではなく、(Ao<<1)|(Ao^Bo)と記憶しておけば、エンコーダの状態への変換の他は、減算とマスク処理のみで回転状態を得られます。